我的小程序需要的类是外部jar(带符号的jar)和本机库的一部分。我将这些jar部署在applet.jar中。要从这些jar中加载类,我发现com.jdotsoft.jarloader.JarClassLoader类很有用。我首先构建一个控制台应用程序来测试我的applet的功能,并且JarClassLoader对我来说工作正常。
接下来,我用另外两个公共方法编写了MyApplet类,比方说action1()和action2()。并且,如JarClassLoader所述,我编写了一个MyAppletLauncher类。 (请参见下面的代码)。为了获得对MyApplet对象的引用(由JarClassLoader实例化),我将getApplet()方法添加到JarClassLoader类中。

MyApplet.java:

public class MyApplet extends Applet {
    public void init()    { ... }
    public void start()   { ... }
    public void stop()    { ... }
    public void destroy() { ... }

    public String action1() {
        ...
    }
    public int action2() {
        ...
    }
}


MyAppletLauncher.java:

public class MyAppletLauncher extends Applet {
    private JarClassLoader jcl;
    public void init() {
        jcl = new JarClassLoader();
        jcl.initApple("MyApplet", this);
    }
    public void start() {
        jcl.startApplet();
    }
    public void stop() {
        jcl.stopApplet();
    }
    public void destroy() {
        jcl.destroyApplet();
    }
    public String action1() {
        return ((MyApplet) jcl.getApplet()).action1(); // <-- ClassCastException
    }
    public int action2() {
        return ((MyApplet) jcl.getApplet()).action2(); // <-- ClassCastException
    }
}


我对JarClassLoader.java的更改:

public class JarClassLoader extends ClassLoader {

    private Applet applet; // was JApplet

    public JarClassLoader() {
        this(ClassLoader.getSystemClassLoader());
    }

    public JarClassLoader(ClassLoader parent) {
        super(parent);

        ...
    }

    public void initApplet(String sClass, final Applet appletParent) { // 2nd arg was JApplet
        Class<?> clazz = loadClass(sClass);
        applet = (Applet) clazz.newInstance();
        ...
    }

    public Applet getApplet() {
        return applet;
    }
    ...


在我看来,很明显MyAppletLauncher实例无法将提供的Applet实例向下转换为MyApplet,因为MyApplet实例是在不同的命名空间中创建的(=不是由同一类加载器创建的)。但是,我的问题是如何获得对MyApplet对象的action1()和action2()调用?或更常见的是,我可以从MyAppletLauncher对象调用MyApplet的公共接口吗?

我已经尝试过几件事,例如


MyApplet实现MyInterface,然后将其强制转换为MyInterface
将成员JarClassLoader.applet的类型更改为MyApplet


但是所有这些都会在某个时刻导致ClassCastException。

任何建议都欢迎。谢谢。

最佳答案

我认为您缺少启动程序小程序的要点。一方面,它充当小程序容器与其系统ClassLoader之间的垫片,另一方面,它充当JCL加载的真实小程序和JCL。除了applet生命周期方法外,启动器applet中应该没有任何内容。

我不确定如何在启动程序applet上调用除生命周期方法以外的任何方法。那不是偶然的,所以就别再尝试了。在真正的applet类和所需的任何帮助程序类中实现您applet的所有功能,就像启动器applet不存在一样。

如果必须让外部组件在其applet上查找并调用方法,则使用与应用程序生命周期方法相同的模型,修改或子类化JCL以提供其他的shim方法。

10-04 16:58