Hi,

I noticed that org.apache.bcel.util.ClassPath never refreshes its classpath
once initialized. I have a program that does the following:

   1. Accept a class filename (e.g., /dev/src/org/apache/bcel/x.class).
   2. Use BCEL to get the package for the class (e.g., org.apache.bcel).
   3. Find the fully qualified path to the class file.
   4. Get the package's main directory (e.g., /home/dev/src).
   5. Update the classloader's classpath using the main directory.
   6. Append the result to "java.class.path".
   7. Find all superclasses of x.class using the revised classpath.

FYI, steps 5 and 6 use http://davidjarvis.ca/dave/ClassPathUpdater.java.

At step 7, BCEL should use the updated classpath. This does not seem to
happen because at step 2, the classpath has been parsed and set in stone via
org.apache.bcel.util.ClassPath.java. Specifically, this line:

    public static final ClassPath SYSTEM_CLASS_PATH = new ClassPath();

Since SyntheticRepository treats ClassPath like a singleton, it appears as
though the following method is called only once:

    public static final String getClassPath() ...

The JavaClass then never gets a chance to take a second look at the
classpath to see if it has changed, as it uses:

    SyntheticRepository.getInstance();

The code I would like to write looks as follows:

    JavaClass jc = createJavaClass( filename );

    try {
      updateClassPath( getPackageRootPath( jc ) );
      updateClassPath( new File( "test.jar" ) );
    }
    catch( ClasspathException ex ) {
      // TODO: Inform subclasses of this error.
      //
      System.err.println( ex.toString() );
    }

    findSubclasses( jc );
    findSuperclasses( jc );

The findSuperclasses method should search the "root package path" (e.g.,
/dev/src/) and "test.jar" for classes. Here is the error resulting error:

java.lang.ClassNotFoundException: Exception while looking for class
javax.speech.Engine: java.io.IOException: Couldn't find:
javax/speech/Engine.class
    at
org.apache.bcel.util.SyntheticRepository.loadClass(SyntheticRepository.java:128)
    at org.apache.bcel.classfile.JavaClass.getInterfaces(JavaClass.java:788)
    at
org.apache.bcel.classfile.JavaClass.getAllInterfaces(JavaClass.java:804)
    at
org.apache.bcel.classfile.JavaClass.implementationOf(JavaClass.java:743)
    at org.apache.bcel.classfile.JavaClass.instanceOf(JavaClass.java:725)
    at
com.whitemagicsoftware.hierarchy.ClassAnalyzer.isSubclass(ClassAnalyzer.java:354)
    at
com.whitemagicsoftware.hierarchy.ClassAnalyzer.registerSubclass(ClassAnalyzer.java:403)
    at
com.whitemagicsoftware.hierarchy.ClassAnalyzer.findDirectorySubclasses(ClassAnalyzer.java:331)
    at
com.whitemagicsoftware.hierarchy.ClassAnalyzer.findSubclasses(ClassAnalyzer.java:308)
    at
com.whitemagicsoftware.hierarchy.ClassAnalyzer.analyze(ClassAnalyzer.java:116)
    at
com.whitemagicsoftware.hierarchy.ClassAnalyzer.main(ClassAnalyzer.java:527)

The class cannot be found because although the classpath has changed, BCEL
is not informed.

Any ideas how to resolve this issue?

Dave

Reply via email to