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