java.lang.IllegalAccessError:尝试访问方法


72

我遇到了一个例外,但找不到原因。

我得到的例外是:

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;
}

我正在使用Tomcat 5.5.12和JAVA 1.6

Answers:


81

几乎可以肯定,您在运行时使用的类版本与您期望的版本不同。特别是,运行时类将不同于您针对其进行编译的类(否则将导致编译时错误)-该方法曾经存在private吗?您的系统上任何地方都有类/ jar的旧版本吗?

作为IllegalAccessError状态的javadocs ,

通常,此错误由编译器捕获;如果类的定义发生了不兼容的更改,则只有在运行时才会发生此错误。

我一定会看看您的类路径,并检查它是否有任何惊喜。


3
@yossi:那你是怎么解决的呢?重新编译资源并将其放入您的类路径中?如果您对原始类进行了反编译并看到了其中的内容,那会很好奇。
维克多

遇到这个问题时,我已经用私有函数将文件保存为公共文件,因此编辑器认为.jsp文件中的所有内容都还可以,但是我没有重新启动主程序,因此实际上没有编译新版本。
布莱恩·怀特

我从刚安装的Maven软件包中收到此错误。我已经更新了该项目并清理了它,但似乎一切都没有改变。–
软件

106

当访问在同一包中但在不同的jar和类加载器中的类的包范围方法时,会发生这种情况。

是我的消息来源,但是链接现在断开了。以下是Google缓存的全文:

包(在包访问中)按ClassLoader进行作用域限定。

您声明父ClassLoader加载接口,子ClassLoader加载实现。由于软件包作用域的特定于ClassLoader的性质,因此无法使用。实现类看不到该接口,因为即使它具有相同的包名称,它们也位于不同的ClassLoader中。

我只浏览了该线程中的帖子,但我认为您已经发现,如果您声明接口为公共,则可以使用。使接口和实现都由同一个ClassLoader加载也将起作用。

的确,如果您希望任意的人来实现该接口(如果实现是由其他ClassLoader加载的,那么您显然会这样做),则应该将该接口公开。

包作用域的ClassLoader作用域(适用于访问包方法,变量等)类似于类名的常规ClassLoader作用域。例如,如果我在单独的ClassLoader中定义它们,则可以使用完全不同的实现代码定义两个都命名为com.foo.Bar的类。

乔尔


1
我在commons-collections-3.2.1.jar带有Struts 1.1的JBoss EAP 5.3下遇到了这个问题,因为该JAR已经在JBoss库中,但也打包在我的应用程序中。我从解决问题的应用程序中删除了JAR。
朱利安·克朗格

2
您刚刚为我节省了很多时间和精力。非常好!
msteiger 2015年

我正在为现在需要第二个参数的公共静态方法获取此错误。自从我替换了旧的jar文件后,它就不再存在。有任何想法吗?
马库斯

我在同一包中有一个带有package-private修饰符的抽象类,另一个带有public修饰符的类(扩展了前一个类)。两者都放在一个简单的罐子里。我正在使用Web应用程序中的抽象类方法。奇怪的是,我能够从Eclipse中在Tomcat中部署我的应用程序,但不能在远程计算机上的Tomcat中部署我的应用程序。我将抽象类的访问修饰符更改为public,一切正常。
fabriziocucci

我将Firefox驱动程序从降级2.53.02.44.0帮助(我使用的是Grails 2.3.11,这是旧版本)。
flaz14

4

如果getData受到保护,则尝试将其公开。该问题可能在JAVA 1.6中存在,而在1.5x中不存在

我为您解决这个问题。非法访问错误


4

我在一个@RestController ApplicationInfoResource具有嵌套类的Spring Boot应用程序上遇到此错误ApplicationInfo

似乎Spring Boot Dev Tools使用了不同的类加载器。

我得到的例外

2017-05-01 17:47:39.588警告1516-[nio-8080-exec-9] .mmaExceptionHandlerExceptionResolver:由处理程序执行引起的已解决异常:org.springframework.web.util.NestedServletException:处理程序分发失败;嵌套异常是java.lang.IllegalAccessError:尝试从com.gt.web.rest.ApplicationInfoResource $$ EnhancerBySpringCGLIB $$ 59ce500c类访问com.gt.web.rest.ApplicationInfo类

我将嵌套的类ApplicationInfo移到一个单独的.java文件中,摆脱了这个问题。


您还应该考虑从类路径中删除Spring Boot的Dev Tools-可能只是暂时的。就我而言,这IllegalAccessError根本不合理。但是,当我将Maven依赖关系删除到Dev Tools并在不久后再次添加时,一切都按预期运行。
彼得·维珀曼

非常感谢!您已经保存了一天。
瓦利洪

3

当我在一个jar中有一个类试图从另一个jar访问类中的私有方法时,这发生在我身上。我只是将私有方法更改为公共方法,重新编译和部署,然后就可以了。


0

从Android角度看:该 方法在api版本中不可用

我收到此问题的原因主要是因为我使用了该Android版本中不可用/不建议使用的某些东西

错误的方法:

Notification.Builder nBuilder = new Notification.Builder(mContext);
nBuilder.addAction(new Notification.Action(android.R.drawable.ic_menu_view,"PAUSE",pendingIntent));

正确的路:

Notification.Builder nBuilder = new Notification.Builder(mContext);
nBuilder.addAction(android.R.drawable.ic_media_pause,"PAUSE",pendingIntent);

这里Notification.Action在API 20之前不可用,而我的最低版本是API 16


0

只是解决方案的补充:

例如,这可能是Android Studio的“即时运行”功能的问题,如果您意识到finish()在打开另一个活动后忘记将代码行添加到活动中,并且已经重新打开了活动,则不应该重新打开活动(finish()解决了该问题),然后添加finish()并进行即时运行,则由于逻辑被破坏,该应用将崩溃。


TL:DR;

这不一定是代码问题,而只是即时运行问题


0

在我的情况下,问题是方法在某些接口中定义Adefault,而其子类将其覆盖为私有。然后,当调用该方法时,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();
}

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();
  }
}

0

由于intellij中的配置问题,我遇到了相同的错误。如屏幕截图所示。主模块和测试模块指向两个不同的JDK。(按intellij项目上的F12打开模块设置)

我所有的dto都使用@ lombok.Builder,我将其更改为@Data。

在此处输入图片说明

在此处输入图片说明


0

我遇到了类似的异常,但在课堂上

例如,由以下原因引起:java.lang.IllegalAccessError:试图访问类...。

我通过公开授课来解决这个问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.