NoClassDefFoundError thrown

Help
2008-07-24
2013-05-23
  • Steve Freeland
    Steve Freeland
    2008-07-24

    Hi,

    I'm trying to run a project that depends on the jxl library, nested into a top-level jar using OneJar.  I'm running into some odd problems, namely:

    d:/dev/j2se/v1_6_0_01/bin/java.exe -Done-jar.verbose=true -jar jar/bb2xls.jar
    JarClassLoader: Info: resource: jar\bb2xls.jar!/META-INF/MANIFEST.MF
    JarClassLoader: cached bytes for class DirectoryIterator.class
    JarClassLoader: cached bytes for class DirectoryIteratorNode.class
    [ snip ]
    JarClassLoader: Info: caching lib/jxl.jar
    JarClassLoader: using jarFile.getInputStream(lib/jxl.jar)
    JarClassLoader: cached bytes for class jxl.WorkbookSettings.class
    [ snip ]
    JarClassLoader: cached bytes for class jxl.write.WritableCell.class
    [ snip ]
    Exception in thread "main" java.lang.NoClassDefFoundError: jxl/write/WritableCell
            at java.lang.Class.getDeclaredMethods0(Native Method)
            at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
            at java.lang.Class.getMethod0(Class.java:2670)
            at java.lang.Class.getMethod(Class.java:1603)
            at com.simontuffs.onejar.Boot.run(Boot.java:305)
            at com.simontuffs.onejar.Boot.main(Boot.java:159)

    Running under a debugger, I have confirmed that the Boot class is being initialized properly and then loads the "final" main class, namely bb2xls.  It fails when attempting to get the main(String[]) method from bb2xls.  The method is present; the failure seems to occur when pulling in the class' dependancies from the nested jar.

    The debugger also revealed that the exception is actually being thrown deeper in the stack.  The following is above java.lang.Class.getDeclaredMethods0() on the stack:
    URLClassLoader$1.run:200
    AccessController.doPrivileged
    URLClassLoader.findClass:188
    ClassLoader.loadClass:306
    Launcher$AppClassLoader.loadClass:276
    ClassLoader.loadClass:251
    ClassLoader.loadClassInternal:319

    The problem seems to be that the ClassLoader instance called by getDeclaredMethods0() is the default URLClassLoader and not the JarClassLoader created in Boot.  I have no idea why this would be, though, and since getDeclaredMethods0() is native I'm not sure how to find out.

    Any ideas on this?
    Thanks,
    - Steve