Java.lang.IllegalAccessError: попытался получить доступ к методу
Я получаю исключение, и я не могу найти причину этого.
Исключением я получаю:
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
Ответы
Ответ 1
Вы почти наверняка используете другую версию класса во время выполнения до той, которую вы ожидаете. В частности, класс выполнения будет отличаться от того, который вы скомпилировали (иначе это вызвало бы ошибку времени компиляции) - этот метод когда-либо был private
? У вас есть старые версии классов/банок в вашей системе в любом месте?
Как состояние javadocs для IllegalAccessError
,
Обычно эта ошибка улавливается компилятором; эта ошибка может возникнуть только во время выполнения, если определение класса несовместимо изменилось.
Я бы определенно посмотрел на ваш путь к классу и проверил, не вызывает ли у него никаких сюрпризов.
Ответ 2
Это происходит при доступе к пакетному методу класса, который находится в том же пакете, но находится в другом jar и загрузчике классов.
Это был мой источник, но ссылка теперь не работает. Ниже приводится полный текст из кэша Google:
Пакеты (как в доступе к пакетам) ограничены для ClassLoader.
Вы утверждаете, что родительский ClassLoader загружает интерфейс, а дочерний ClassLoader загружает реализацию. Это не будет работать из-за ClassLoader-специфичный характер определения объема пакета. Интерфейс не виден класс реализации, потому что, хотя это и то же имя пакета, они находятся в разных загрузчиках классов.
Я только просмотрел сообщения в этой теме, но я думаю, что вы уже обнаружили что это будет работать, если вы объявите интерфейс общедоступным. Это также работать так, чтобы интерфейс и реализация загружались одним и тем же ClassLoader.
Действительно, если вы ожидаете, что произвольные люди будут реализовывать интерфейс (который вы очевидно делать, если реализация загружается другим ClassLoader), тогда вы должны сделать интерфейс общедоступным.
ClassLoader-scoping области пакета (который применяется к доступу пакета методы, переменные и т.д.) аналогична общей области видимости ClassLoader имена классов. Например, я могу определить два класса, оба с именем com.foo.Bar, с совершенно другим кодом реализации, если я определю их в отдельном Загрузчиков классов.
Joel
Ответ 3
Если защита getData
защищена, попробуйте сделать ее общедоступной. Проблема может существовать в JAVA 1.6 и отсутствовать в 1.5x
Я получил это для вашей проблемы. Ошибка незаконного доступа
Ответ 4
Это случилось со мной, когда у меня был класс в одной банке, пытающийся получить доступ к приватному методу в классе из другой банки. Я просто сменил частный метод на публичный, перекомпилировал и развернул, и после этого он работал нормально.
Ответ 5
Я получал эту ошибку в приложении загрузки 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: Исправлено исключение по выполнению обработчика: org.springframework.web.util.NestedServletException: отправка обработчика не смогли; Вложенное исключение - java.lang.IllegalAccessError: попытался класс доступа com.gt.web.rest.ApplicationInfo из класса com.gt.web.rest.ApplicationInfoResource $$ EnhancerBySpringCGLIB $$ 59ce500c
Решение
Я переместил вложенный класс ApplicationInfo
в отдельный .java файл и избавился от этой проблемы.
Ответ 6
С точки зрения 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, а моя версия min - API 16
Ответ 7
Просто добавление к разрешенному ответу:
Это COULD может быть проблемой с функцией Android Studio Instant Run, например, если вы поняли, что забыли добавить строку кода: finish()
в свою деятельность после открытия другого, и вы уже повторно открыл активность, которую вы не должны были повторно открывать (решение которой было решено finish()
), затем вы добавляете finish()
и выполняется мгновенный запуск, после чего приложение выйдет из строя, поскольку логика была нарушена.
TL: DR;
Это не обязательно проблема с кодом, просто проблема с мгновенным запуском
Ответ 8
В моем случае проблема заключалась в том, что метод был определен в некотором интерфейсе A
как default
, в то время как его подкласс отверг его как частный. Затем, когда метод был вызван, среда выполнения Java обнаружила, что вызывает частный метод.
Я все еще озадачен, почему компилятор не жаловался на приватное переопределение..
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();
}
Ответ 9
В моем случае я получал эту ошибку при запуске моего приложения в wildfly с .ear, развернутым из eclipse. Поскольку она была развернута из eclipse, папка развертывания содержала не файл .ear, а папку, представляющую его, и внутри него все jar файлы, которые содержались бы в файле .ear; как если бы ухо было расстегнуто.
Итак, я был на банке:
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();
}
}