6

我有实现 IAssembly 的类 Assembly。

我在启动应用程序时看到以下错误

Caused by: java.lang.IllegalAccessError: class <Assembly > cannot access its superinterface <IAssembly>
        at java.lang.ClassLoader.defineClass1(Native Method)

汇编代码

class package.Assembly implements IAssembly {

}

组装

interface IAssembly { //note -this is not public, so uses default protected

}

Assembly 和 IAssembly 存在于两个不同的 jar 中。两个 jar 由不同的类加载器加载。Assembly 类在子类加载器中加载,IAssembly 是父类。类加载器正在使用链接。

在正常情况下,这是有效的。当我在使用 cobertura 检测 jar 后运行我的应用程序时发生错误。没有仪器,一切正常。cobertura 仪器会导致这样的错误吗?或者,无论如何,这都是一个等待检测的错误,但使用 cobertura,该错误很快就会暴露出来。

通过使界面“公开”,错误就会消失。

4

3 回答 3

8

在我看来,检测和多个类加载器的包保护失败,即使加载器是链式的。java.lang.instrument.Instrumentation上的这个 javadoc与您的场景没有直接关系,但它确实描述了类似的场景:

代理应注意确保 JAR 不包含任何类或资源,除了那些由引导类加载器为检测目的而定义的类或资源。不遵守此警告可能会导致难以诊断的意外行为。例如,假设有一个加载器 L,L 的委托父级是引导类加载器。此外,由 L 定义的类 C 中的方法引用非公共访问器类 C$1。如果 JAR 文件包含类 C$1,那么对引导类加载器的委托将导致 C$1 由引导类加载器定义。在此示例中,将引发 IllegalAccessError,这可能导致应用程序失败。避免这些类型问题的一种方法是为检测类使用唯一的包名称。

Java 虚拟机规范规定,后续尝试解析 Java 虚拟机之前未成功尝试解析的符号引用总是会失败,并引发与初始解析尝试相同的错误。因此,如果 JAR 文件包含与 Java 虚拟机未成功尝试解析引用的类对应的条目,则后续解析该引用的尝试将失败,并出现与初始尝试相同的错误。

也许检查哪个加载器正在找到您的检测类,看看是否有办法同时获取AssemblyIAssembly从同一个类加载器加载。

于 2011-10-08T17:09:46.343 回答
1

我认为您的问题可能是您没有使用兼容版本的 IAssembly。因此,即使它在您的类路径中,接口及其实现也不匹配。

如果是类加载器问题,您将收到 NoClassDefFoundError。

于 2011-09-16T16:06:23.393 回答
1

我将为此错误消息添加另外两个原因

  1. 如果您的界面的可见性不正确并且您需要将其从protectedtopublicprivateto更改为protected或 ...,也可能发生此错误。我知道这不是这里的原因,因为提问者知道看到他的评论。
  2. 在您的 IDE 中,一切都是绿色的,但在您的 OSGI 环境中,您会收到此错误。您需要检查该类是否已导出而不是在私有包中。
于 2020-07-31T07:56:13.040 回答