Applet类加载器在applet的jar中找不到类

A. *_*evy 4 java applet classloader

我开始问这个问题,然后在提交之前找出答案.我决定发布这个问题,以便遇到同样问题的其他人能够从我的错误中吸取教训.


我遇到了applet(实际上是JApplet)无法实例化另一个类的问题,该类与applet包含在同一个jar中.我在Java控制台上看到的例外是:

Exception in thread "thread applet-com.company.program.cm.hmi.MediatorApplet-1" java.lang.NoClassDefFoundError: com/company/program/cm/cs/JDataStore
    at com.company.program.cm.hmi.MediatorApplet.getMediator(MediatorApplet.java:63)
    at com.company.program.cm.hmi.MediatorApplet.init(MediatorApplet.java:49)
    at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.company.program.cm.cs.JDataStore
    at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClassInternal(Unknown Source)
    ... 4 more
Caused by: java.io.IOException: open HTTP connection failed:http://localhost:8080/TransportHMI/pages/com/company/program/cm/cs/JDataStore.class
    at sun.plugin2.applet.Applet2ClassLoader.getBytes(Unknown Source)
    at sun.plugin2.applet.Applet2ClassLoader.access$000(Unknown Source)
    at sun.plugin2.applet.Applet2ClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    ... 8 more

我知道这个JDataStore类包含在jar中.如果我使用我列出的内容,jar tvf CM_Library.jar我可以看到它在适当的包下.但是,上面链接的异常使我相信类加载器不会搜索存档JDataStore,而是在Web服务器上查找JDataStore.class文件.为什么是这样?类加载器知道从jar加载MediatorApplet类,为什么不检查JDataStore呢?如果我没有在applet标签上正确指定参数,我也会在这里包含:

<applet id="mediator-applet"
        width="0"
        height="0"
        codebase="./"
        archive="CM_Library.jar"
        code="com.company.program.cm.hmi.MediatorApplet">
</applet>
Run Code Online (Sandbox Code Playgroud)

A. *_*evy 8

通过查看针对相关问题发布的建议找到答案.Eddie的回答并没有解决这个问题,但确实给了我解决方案.

从我的问题来看,特别明显的是JDataStore类继承自另一个包含在另一个jar中的类.我没有必要在几个月内处理JDataStore的实现细节,所以我完全忘记它的父类org.json.simple.JSONObject不在CM_Library.jar中,而是在json_simple-1.0中.2.jar.修复非常简单,只需将缺少的jar复制到codebase目录,并将缺少的jar添加到applet标记archive属性中以逗号分隔的归档列表中:

<applet id="mediator-applet"
        width="0"
        height="0"
        codebase="./"
        archive="CM_Library.jar, json_simple-1.0.2.jar"
        code="com.company.program.cm.hmi.MediatorApplet">
</applet>
Run Code Online (Sandbox Code Playgroud)

这解决了错误.异常消息不是特别有用.当实际问题是它无法为所请求的类加载超类时,它会让你相信它根本找不到类.