java.lang.NoClassDefFoundError用于在运行时下载的jar文件

时间:2012-02-21 18:10:55

标签: java jar aix noclassdeffounderror

我的java应用程序启动如下: / usr / java6_64 / bin / java -cp main.jar:updater.jar:jtapi.jar

在某些情况下,jtapi.jar不存在,并在运行时下载。 main.jar和updater.jar旨在解决这个问题。这在多个操作系统上完美运行,包括AIX 5.3。

但是,在AIX 7.1上,如果jtapi.jar不存在则会失败。这是一个例外:

Exception in thread "main" java.lang.NoClassDefFoundError: com.cisco.jtapi.extensions.CiscoProviderObserver
        at java.lang.ClassLoader.defineClass(ClassLoader.java:275)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:69)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:540)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:451)
        at java.net.URLClassLoader.access$300(URLClassLoader.java:79)
        at java.net.URLClassLoader$ClassFinder.run(URLClassLoader.java:1038)
        at java.security.AccessController.doPrivileged(AccessController.java:284)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:429)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:660)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:358)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:626)
        at com.genesyslab.ciscocm.JtapiUpdater.main(JtapiUpdater.java:107)
Caused by: java.lang.ClassNotFoundException: com.cisco.jtapi.extensions.CiscoProviderObserver
        at java.net.URLClassLoader.findClass(URLClassLoader.java:434)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:660)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:358)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:626)
        at java.lang.ClassLoader.defineClassImpl(Native Method)
        ... 12 more

再次运行它,之后立即运行,因为jtapi.jar已经存在。 我已经验证了jtapi.jar文件已成功下载,甚至增加了延迟以确保它有时间。同样,这在AIX和其他操作系统的早期版本上工作正常。

有什么想法吗?

修改 到目前为止,“消除不存在的文件”理论似乎最合适。我使用下面的代码检查了规范的想法,无论是否存在jtapi.jar,输出都是相同的:

File jtapiFile = new File(".", JTAPI_JARFILE);
try {
  LogMain("JtapiUpdater: getCanonicalPath() " +  jtapiFile.getCanonicalPath() + ".");
} catch (IOException e) {}

输出:
JtapiUpdater:getCanonicalPath()/ home / ddg / aix / jtapi.jar。

但是,我仍然没有一种简单的方法来解决问题。

修改
我在java执行行中添加了跟踪选项:
     -Dibm.cl.verbose = com.cisco.jtapi.extensions.CiscoProviderObserver
     -Dibm.dg.trc.methods = java / lang / ClassLoader。*()-Dibm.dg.trc.print = mt

这些输出加载器如何查找类。这是它显示的......

如果jtapi.jar 最初不是,而是由updater.jar下载:

AppClassLoader attempting to find com.cisco.jtapi.extensions.CiscoProviderObserver
AppClassLoader using classpath /home/ddg/aix/ccm-tserver.jar:/home/ddg/aix/updater.jar:/home/ddg/aix/jtapi.jar
AppClassLoader could not find com/cisco/jtapi/extensions/CiscoProviderObserver.class in /home/ddg/aix/ccm-tserver.jar
AppClassLoader could not find com/cisco/jtapi/extensions/CiscoProviderObserver.class in /home/ddg/aix/updater.jar
AppClassLoader could not find com.cisco.jtapi.extensions.CiscoProviderObserver

如果jtapi.jar 存在:

AppClassLoader attempting to find com.cisco.jtapi.extensions.CiscoProviderObserver
AppClassLoader using classpath /home/ddg/aix/ccm-tserver.jar:/home/ddg/aix/updater.jar:/home/ddg/aix/jtapi.jar
AppClassLoader could not find com/cisco/jtapi/extensions/CiscoProviderObserver.class in     /home/ddg/aix/ccm-tserver.jar
AppClassLoader could not find com/cisco/jtapi/extensions/CiscoProviderObserver.class in /home/ddg/aix/updater.jar
AppClassLoader found com/cisco/jtapi/extensions/CiscoProviderObserver.class in /home/ddg/aix/jtapi.jar
AppClassLoader found com.cisco.jtapi.extensions.CiscoProviderObserver

注意AppClassLoader甚至不会在“不是”的情况下搜索/home/ddg/aix/jtapi.jar,即使jtapi.jar已成功下载并列在类路径中!

我的猜测是,这是JVM for AIX 7.1中的一个错误,因为它在任何其他操作系统(包括早期版本的AIX)上都不是问题。

1 个答案:

答案 0 :(得分:1)

听起来AIX上的JVM可能有一个默认的类加载器,用于检查启动时是否存在类路径条目,并丢弃任何不存在的类路径条目。但我无法在任何文档中验证。

在所有.jars完成下载之前,你不能等到启动应用程序吗?

如果您不能,则可能需要在代码中使用自定义类加载器,而不是调用Class.forName()

编辑:我一直在挖掘:系统类加载器sun.misc.Launcher$AppClassLoader将类路径条目转换为规范路径,然后创建一个数组他们的文件URL。但是a file that doesn't exist的规范路径是什么?

  

表示不存在的文件或目录的每个路径名也具有唯一的规范形式。在创建文件或目录之后,不存在的文件或目录的路径名的规范形式可能与相同路径名的规范形式不同。同样,在删除文件或目录后,现有文件或目录的路径名的规范形式可能与同一路径名的规范形式不同。

也许在AIX上,现有文件和不存在文件的规范路径名是不同的?