java.lang.IllegalAccessError: try to access method

2022-08-31 11:41:49

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

我得到的例外是:

java.lang.IllegalAccessError: tried to access method Connected.getData(Ljava/lang/String;)Ljava/sql/ResultSet; from class 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


答案 1

当访问位于同一包中但位于不同 jar 和类装入器中的类的包作用域方法时,会发生这种情况。

这是我的来源,但链接现在已经断开。以下是来自谷歌缓存的全文:

包(如在包访问中)按类加载器限定范围。

您声明父类加载器加载接口,子类加载器加载实现。这不起作用,因为包作用域特定于类加载器的性质。该接口对实现类不可见,因为即使它是相同的包名称,它们也位于不同的 ClassLoaders 中。

我只是略读了这个帖子中的帖子,但我认为你已经发现,如果你将接口声明为公共接口,这将起作用。让接口和实现都由同一个 ClassLoader 加载也是可行的。

实际上,如果你期望任意的人来实现接口(如果实现是由不同的ClassLoader加载的,你显然会这样做),那么你应该公开接口。

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

乔尔


答案 2

几乎可以肯定的是,您在运行时使用的类版本与预期的版本不同。特别是,运行时类将与您编译的运行时类不同(否则这会导致编译时错误) - 该方法曾经存在过吗?您的系统上是否有旧版本的类/jar?private

作为状态的 javadocs,IllegalAccessError

通常,编译器会捕获此错误;仅当类的定义发生不兼容更改时,此错误才会在运行时发生。

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