我遇到了一个例外,但找不到原因。
我得到的例外是:
java.lang.IllegalAccessError:尝试访问方法Connected.getData(Ljava / lang / String;)Ljava / sql / ResultSet; 从B类
java.lang.IllegalAccessError
Connected.getData(Ljava / lang / String;)Ljava / sql / ResultSet
该方法是公开的。
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
几乎可以肯定,您在运行时使用的类版本与您期望的版本不同。特别是,运行时类将不同于您针对其进行编译的类(否则将导致编译时错误)-该方法曾经存在private吗?您的系统上任何地方都有类/ jar的旧版本吗?
作为IllegalAccessError状态的javadocs ,
IllegalAccessError
通常,此错误是由编译器捕获的。如果类的定义发生了不兼容的更改,则只有在运行时才会发生此错误。
我一定会看看您的类路径,并检查它是否有任何惊喜。
当访问在同一包中但在不同的jar和类加载器中的类的包范围方法时,会发生这种情况。
这是我的消息来源,但是链接现在断开了。以下是Google缓存的全文:
包(在包访问中)按ClassLoader进行作用域限定。
您声明父ClassLoader加载接口,子ClassLoader加载实现。由于软件包作用域的特定于ClassLoader的性质,因此无法使用。实现类看不到该接口,因为即使它具有相同的包名称,它们也位于不同的ClassLoader中。
我只浏览了该线程中的帖子,但我认为您已经发现,如果您声明接口为公共,则可以使用。使接口和实现都由同一个ClassLoader加载也将起作用。
的确,如果您希望任意的人来实现该接口(如果实现是由其他ClassLoader加载的,那么您显然会这样做),则应该将该接口公开。
包作用域的ClassLoader作用域(适用于访问包方法,变量等)类似于类名的常规ClassLoader作用域。例如,如果我在单独的ClassLoader中定义它们,则可以使用完全不同的实现代码来定义两个都命名为com.foo.Bar的类。