我得到了一个例外,我找不到它的原因。
我得到的例外是:
java.lang.IllegalAccessError:尝试访问方法Connected.getData(Ljava / lang / String;)Ljava / sql / ResultSet;来自B级
该方法是公开的。
public class B
{
public void myMethod()
{
Connected conn = new Connected(); // create a connected class in order to connect to The DB
ResultSet rs = null; // create a result set to get the query result
rs = conn.getData(sql); // do sql query
}
}
public class Connected
{
public ResultSet getData(String sql)
{
ResultSet rs = null;
try
{
prepareConnection();
stmt = conn.createStatement();
stmt.execute(sql);
rs = stmt.getResultSet();
}
catch (SQLException E)
{
System.out.println("Content.getData Error");
E.printStackTrace();
}
return rs;
}
我正在使用apache tomcat 5.5.12 和JAVA 1.6
答案 0 :(得分:91)
当访问同一包中但位于不同jar和类加载器中的类的包范围方法时,会发生这种情况。
This是我的来源,但现在链接已被破坏。以下是Google缓存中的全文:
包(在包访问中)的范围是每个ClassLoader。
您声明父ClassLoader加载了接口和子级 ClassLoader加载实现。这不会起作用因为 ClassLoader特定的包范围。界面不可见 实现类因为,即使它是相同的包名, 他们在不同的ClassLoader中。
我只浏览了这个帖子中的帖子,但我想你已经发现了 如果您声明接口是公共的,这将起作用。它也会 努力使接口和实现都由同一个ClassLoader加载。
真的,如果你期望任意人实现界面(你 显然,如果实现是由不同的加载 ClassLoader),然后你应该公开接口。
包范围的ClassLoader-scoping(适用于访问包 方法,变量等)类似于一般的ClassLoader-scoping 班级名称。例如,我可以定义两个名为com.foo.Bar的类, 如果我在单独的定义中使用完全不同的实现代码 类装入器。
乔尔
答案 1 :(得分:71)
您几乎肯定会在运行时使用与您期望的类不同的类。特别是,运行时类与您编译的运行时类不同(否则会导致编译时错误) - 该方法曾是private
吗?您的系统上是否有旧版本的课程/罐子?
作为IllegalAccessError
州的javadoc,
通常,编译器会捕获此错误;如果类的定义发生不兼容的更改,则此错误只能在运行时发生。
我肯定会查看你的类路径并检查它是否有任何意外。
答案 2 :(得分:4)
如果getData
受到保护,请尝试将其公开。问题可能存在于JAVA 1.6中,并且不存在于1.5x
我为你的问题得到了这个。 Illegal access error
答案 3 :(得分:3)
我在Spring引导应用程序上遇到此错误,@RestController ApplicationInfoResource
有一个嵌套类ApplicationInfo
。
似乎Spring Boot Dev Tools
使用了不同的类加载器。
我遇到的例外
2017-05-01 17:47:39.588 WARN 1516 --- [nio-8080-exec-9] .m.m.a.ExceptionHandlerExceptionResolver:已解决的异常导致 由Handler执行: org.springframework.web.util.NestedServletException:处理程序调度 失败;嵌套异常是java.lang.IllegalAccessError:试过 从类访问类com.gt.web.rest.ApplicationInfo com.gt.web.rest.ApplicationInfoResource $$ EnhancerBySpringCGLIB $$ 59ce500c
<强>解决方案强>
我将嵌套的类ApplicationInfo
移动到一个单独的.java文件中,并解决了这个问题。
答案 4 :(得分:2)
当我在一个jar中尝试从另一个jar中访问类中的私有方法时,发生了这种情况。我只是将私有方法更改为public,重新编译和部署,之后它运行正常。
答案 5 :(得分:0)
从Android角度来看: api版本中没有的方法
我之所以遇到这个问题主要是因为我在Android版本中使用了一些不可用/弃用的东西
错误的方式:
<button style="background-color: #ff0000;" id="rButton" onclick="minFunction()" >min</button>
正确的方式:
Notification.Builder nBuilder = new Notification.Builder(mContext);
nBuilder.addAction(new Notification.Action(android.R.drawable.ic_menu_view,"PAUSE",pendingIntent));
这里的Notification.Action在 API 20 之前不可用,而我的最小版本是 API 16
答案 6 :(得分:0)
只是对已解决的答案的补充:
这可能是Android Studio的即时运行功能的问题,例如,如果您发现忘记在以后的活动中添加代码行finish()
打开另一个,你已经重新打开了你不应该重新打开的活动(finish()
解决了),然后你添加了finish()
并且发生了即时运行,那么应用程序将崩溃,因为逻辑被打破了。
<强> TL:DR 强>
这不一定是代码问题,只是一个即时运行问题
答案 7 :(得分:0)
在我的情况下,问题是某个接口A
中的方法定义为default
,而其子类将其作为私有覆盖。然后当调用该方法时,java Runtime意识到它正在调用一个私有方法。
我仍然感到困惑的是为什么编译器没有抱怨私有覆盖..
public interface A {
default void doStuff() {
// doing stuff
}
}
public class B {
private void doStuff() {
// do other stuff instead
}
}
public static final main(String... args) {
A someB = new B();
someB.doStuff();
}
答案 8 :(得分:0)
就我而言,在从eclipse部署.ear的情况下,在Wildfly中运行我的应用时遇到了此错误。因为它是从eclipse部署的,所以部署文件夹不包含.ear文件,而是包含代表它的文件夹,并且在其中包含了所有将包含在.ear文件中的jar。就像耳朵被拉开一样。
所以我在罐子里:
class MySuperClass {
protected void mySuperMethod {}
}
在另一个罐子里:
class MyExtendingClass extends MySuperClass {
class MyChildrenClass {
public void doSomething{
mySuperMethod();
}
}
}
解决方案是在MyExtendingClass中添加新方法:
class MyExtendingClass extends MySuperClass {
class MyChildrenClass {
public void doSomething{
mySuperMethod();
}
}
@Override
protected void mySuperMethod() {
super.mySuperMethod();
}
}
答案 9 :(得分:0)
由于intellij中的配置问题,我遇到了相同的错误。 如屏幕截图所示。 主模块和测试模块指向两个不同的JDK。 (在intellij项目上按F12打开模块设置)
我所有的dto都使用@ lombok.Builder,我将其更改为@Data。
答案 10 :(得分:0)
我在课堂上也遇到类似的异常情况
例如原因:java.lang.IllegalAccessError:试图访问类....
我通过公开授课来解决此问题。