Java小程序 - 无法从最终的类继承 [英] Java Applet - Cannot inherit from final class

查看:321
本文介绍了Java小程序 - 无法从最终的类继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个Java小程序是在大多数客户端环境,主要是工作正常的Windows 7,但最近我们一直要求支持Ubuntu的客户也是如此。

We have a java applet which is working OK in most client environments, primarily Windows 7, but recently we have been asked to support Ubuntu clients as well.

问题是,当此applet被解雇了Ubuntu的客户端(运行Firefox和本地安装IcedTea的Java虚拟机1.7.0_75),我们得到这个异​​常:

The problem is that when the applet is fired up on the Ubuntu client (running Firefox and the natively installed "IcedTEA" Java VM 1.7.0_75) we get this exception:

java.lang.VerifyError: Cannot inherit from final class
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at net.sourceforge.jnlp.runtime.JNLPClassLoader.access$1701(JNLPClassLoader.java:103)
    at net.sourceforge.jnlp.runtime.JNLPClassLoader$5.run(JNLPClassLoader.java:1636)
    at net.sourceforge.jnlp.runtime.JNLPClassLoader$5.run(JNLPClassLoader.java:1634)
    at java.security.AccessController.doPrivileged(Native Method)
    at net.sourceforge.jnlp.runtime.JNLPClassLoader.findClass(JNLPClassLoader.java:1633)
    at net.sourceforge.jnlp.runtime.JNLPClassLoader.loadClassExt(JNLPClassLoader.java:1670)
    at net.sourceforge.jnlp.runtime.JNLPClassLoader.loadClass(JNLPClassLoader.java:1471)
    at com.renosci.Nlx.chartapplet.NlxBrowserJsEngine.<init>(NlxBrowserJsEngine.java:46)
    at com.renosci.Nlx.chartapplet.UtilityApplet.init(UtilityApplet.java:87)
    at sun.applet.AppletPanel.run(AppletPanel.java:436)
    at java.lang.Thread.run(Thread.java:745)

我们没有得到Windows下此异常(当然,不同的JVM和建立在Windows我们使用的是
Oracle提供的虚拟机,而不是这个版本的IcedTea)。

We don't get this exception under Windows (admittedly, different JVM builds and of on Windows we are using the Oracle supplied VMs instead of this IcedTea version).

我理解异常的含义 - 并有一个快速谷歌搜索显示,主要归结为建议多SO问题的构建路径是不一样的类路径,这样,在编译时的基类不是决赛,但在运行时的类加载器发现它最终的决定。

I understand the meaning of the exception - and have a quick google search revealed multiple SO questions that mainly boiled down to the the suggestion that the build path is not the same as the class path, such that at compile time a base class was not final, but at runtime the classloader is finding it final.

不过,我不明白怎么可以如此:

However, I don't understand how that can be the case:


  • 这是引发错误的类是从一个抽象基类就是我们的codeBase类的一部分延伸
    根据我们的版本控制系统从来就不是最后的

  • The class which is throwing the error is extending from an abstract base class that is part of our codebase, and according to our version control system has never been final

有没有那里是这个类在目标机器上,我与测试的任何其他版本的可能性 - 其实我创建了一个新的虚拟机本次测试,得到了问题马上

There is no possibility of there being any other versions of this class on the target machine that I am testing with - in fact I created a fresh VM for this test and got the problem straight away

我假设它是在抱怨NlxBrowserJsEngine类,调用的loadClass之前立即运行 - 是正确的?而且该基类这个类的是它认为一个是最终的?

I am assuming that the class it is complaining about NlxBrowserJsEngine, running immediately before the call to loadClass - is that correct? And that the base class of this class is the one which it thinks is final?

有关完整性 - 这里是类的声明(这是例外抱怨该行46)和仅有的两个领域具有的声明:

For completeness - here is the declaration of the class (which is the line 46 that the exception complains about) and the declaration of the only two fields it has:

public class NlxBrowserJsEngine extends NlxJsEngine {  /* Line 46 */
    private JSObject windowObj;
    static private Object evalLock = new Object();

JSObject是netscape.javascript.JSObject,由Java浏览器插件提供的。

JSObject is netscape.javascript.JSObject, provided by the Java browser plugin.

下面是基类的声明:

public abstract class NlxJsEngine {

感谢您的任何见解!

Thanks for any insights!

推荐答案

我最终找到了这个原因。

I eventually tracked down the cause of this.

正如@ immibis的评论所指出的,例外的是类初始化过程中,而建设一个实例的过程中。

As indicated by @immibis's comments, the exception was during class initialization, rather during construction of an instance.

一类NlxBrowserJsEngine的方法调用另一个类的静态方法 - 这类从netscape.javascript.JSObject扩展

One of the methods of class NlxBrowserJsEngine calls a static method of another class - and this class extends from netscape.javascript.JSObject.

在<一个href=\"http://www.oracle.com/webfolder/technetwork/java/plugin2/liveconnect/jsobject-javadoc/netscape/javascript/JSObject.html\"相对=nofollow> Oracle实施这JSObject类没有被声明为final,因此延长它工作正常。

In the oracle implementation this JSObject class is not declared final, so extending it works fine.

的IcedTea 实施JSObject是最终决定。加载这个类中的IcedTea JVM插件因此,当一个异常被抛出。

In the IcedTea implementation, JSObject is final. Therefore when loading this class in the IcedTea JVM Plugin, an exception is thrown.

我不知道,如果这种不兼容性是代表的IcedTea实现者,或者故意进行的监督(由于安全吧?)。无论哪种方式,它造成大问题我们。

I'm not sure if this incompatibility was an oversight on behalf of the IcedTea implementors, or perhaps done deliberately (due to security perhaps?). Either way it caused big problems for us.

通过广泛的重构它本来可以克服这一点,但是在我们的情况下,这个不被认为有价值的,所以我们已经决定,要求我们的用户安装Oracle JVM。

Through extensive refactoring it would have been possible to overcome this, however in our case this was not considered worthwhile so we have decided to require our users to install the Oracle JVM.

这篇关于Java小程序 - 无法从最终的类继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆