/*
 * Bytecode Analysis Framework
 * Copyright (C) 2003,2004 University of Maryland
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package edu.umd.cs.findbugs.ba;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import edu.umd.cs.findbugs.classfile.ClassDescriptor;
import edu.umd.cs.findbugs.classfile.DescriptorFactory;
import edu.umd.cs.findbugs.classfile.ResourceNotFoundException;
import edu.umd.cs.findbugs.internalAnnotations.DottedClassName;
import edu.umd.cs.findbugs.util.ClassName;

Parse the detail message in a ClassNotFoundException to extract the name of the missing class. Unfortunately, this information is not directly available from the exception object. So, this class parses the detail message in several common formats (such as the format used by BCEL).
Author:David Hovemeyer
/** * Parse the detail message in a ClassNotFoundException to extract the name of * the missing class. Unfortunately, this information is not directly available * from the exception object. So, this class parses the detail message in * several common formats (such as the format used by BCEL). * * @author David Hovemeyer */
public class ClassNotFoundExceptionParser { // BCEL reports missing classes in this format private static final Pattern BCEL_MISSING_CLASS_PATTERN = Pattern.compile("^.*while looking for class ([^:]*):.*$"); // edu.umd.cs.findbugs.ba.type.TypeRepository // and edu.umd.cs.findbugs.ba.ch.Subtypes2 uses this format private static final Pattern TYPE_REPOSITORY_MISSING_CLASS_PATTERN = Pattern.compile("^Class ([^ ]*) cannot be resolved.*$"); private static final Pattern[] patternList; static { ArrayList<Pattern> list = new ArrayList<Pattern>(); list.add(BCEL_MISSING_CLASS_PATTERN); list.add(TYPE_REPOSITORY_MISSING_CLASS_PATTERN); patternList = list.toArray(new Pattern[list.size()]); }
Get the name of the missing class from a ClassNotFoundException.
Params:
  • ex – the ClassNotFoundException
Returns:the name of the missing class, or null if we couldn't figure out the class name
/** * Get the name of the missing class from a ClassNotFoundException. * * @param ex * the ClassNotFoundException * @return the name of the missing class, or null if we couldn't figure out * the class name */
public static @DottedClassName String getMissingClassName(ClassNotFoundException ex) { // If the exception has a ResourceNotFoundException as the cause, // then we have an easy answer. Throwable cause = ex.getCause(); if (cause instanceof ResourceNotFoundException) { String resourceName = ((ResourceNotFoundException) cause).getResourceName(); if (resourceName != null) { ClassDescriptor classDesc = DescriptorFactory.createClassDescriptorFromResourceName(resourceName); return classDesc.toDottedClassName(); } } if (ex.getMessage() == null) { return null; } // Try the regular expression patterns to parse the class name // from the exception message. for (Pattern pattern : patternList) { Matcher matcher = pattern.matcher(ex.getMessage()); if (matcher.matches()) { String className = matcher.group(1); ClassName.assertIsDotted(className); return className; } } return null; } }