java-class-enumerator icon indicating copy to clipboard operation
java-class-enumerator copied to clipboard

ClassNotFound Exception

Open christianbalzer opened this issue 10 years ago • 1 comments

I have the following directory setup

src
+---main
|   +---java
|   |   +---com
|   |   |   \---example
|   |   |       \---test
|   |   |           \---dynamic
|   |   |               |   ClassEnumerator.java
|   |   |               |
|   |   |               \---classes
|   |   |                   |   MainDirTestClass.java
|   |   |                   |
|   |   |                   \---subpackage
|   |   |                           SubPackageTestClass.java
|   |   \---META-INF
|   |           MANIFEST.MF
|   \---resources
\---test
    \---java

The ClassEnumerator class contains the following main method as well as the methods posted on StackOverflow:

    public static void main(String... args0) {
        getClassesForPackage(Package.getPackage("com.example.test.dynamic"));
    }

This produces the following error message:

C:\...\test>java -jar ClassEnumeration.jar
ClassDiscovery: Package: com.example.test.dynamic becomes Path:com/example/test/dynamic
ClassDiscovery: Resource = jar:file:/C:/.../test/ClassEnumeration.jar!/com/example/test/dynamic
ClassDiscovery: FullPath = jar:file:/C:/.../test/ClassEnumeration.jar!/com/example/test/dynamic
ClassDiscovery: Directory = null
ClassDiscovery: JarEntry: com/example/test/dynamic/ClassEnumerator.class
ClassDiscovery: className = com.example.test.dynamic.ClassEnumerator
ClassDiscovery: JarEntry: com/example/test/dynamic/classes/
ClassDiscovery: className = com.example.test.dynamices.
Exception in thread "main" java.lang.RuntimeException: ClassNotFoundException loading com.example.test.dynamices.
        at com.example.test.dynamic.ClassEnumerator.getClassesForPackage(ClassEnumerator.java:75)
        at com.example.test.dynamic.ClassEnumerator.main(ClassEnumerator.java:87)

Any idea where the "...es." comes from in "com.example.test.dynamices"?

christianbalzer avatar Jan 08 '15 14:01 christianbalzer

The problem is partially this line, where the .class replacement happens last - after all slashes were turned into dots:

String className = entryName.replace('/', '.').replace('\\', '.').replace(".class", ""); // entryName: com/example/test/dynamic/classes/

An addition to the if statement and a bit of reordering gets us this conditional block, which now seems to work as expected:

if(entryName.startsWith(relPath) && entryName.endsWith(".class") && entryName.length() > (relPath.length() + "/".length())) {
  System.out.println("ClassDiscovery: JarEntry: " + entryName);
  String className = entryName.replace(".class", "").replace('/', '.').replace('\\', '.');
  System.out.println("ClassDiscovery: className = " + className);
  try {
    classes.add(Class.forName(className));
  }
  catch (ClassNotFoundException e) {
    throw new RuntimeException("ClassNotFoundException loading " + className);
  }
}

christianbalzer avatar Jan 08 '15 15:01 christianbalzer