wake-up-neo.net

java.lang.IllegalAccessError: Es wurde versucht, auf die Methode zuzugreifen

Ich bekomme eine Ausnahme und kann den Grund dafür nicht finden.

Die Ausnahme, die ich bekomme, ist:

Java.lang.IllegalAccessError: Es wurde versucht, auf die Methode Connected.getData (Ljava/lang/String;) zuzugreifen. Ljava/sql/ResultSet; aus der Klasse B

Die Methode ist öffentlich.

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

ich verwende Apache Tomcat 5.5.12. und Java 1.6

65
yossi

Sie verwenden fast sicher eine andere Version der Klasse zur Laufzeit als Sie erwarten. Insbesondere unterscheidet sich die Laufzeitklasse von der, für die Sie kompiliert haben (andernfalls hätte dies einen Fehler bei der Kompilierung verursacht). Ist diese Methode ever private? Haben Sie irgendwo alte Versionen der Klassen/Gläser auf Ihrem System?

Wie die Javadocs für IllegalAccessError state,

Normalerweise wird dieser Fehler vom Compiler abgefangen. Dieser Fehler kann nur zur Laufzeit auftreten, wenn sich die Definition einer Klasse inkompatibel geändert hat.

Ich würde mir definitiv Ihren Klassenpfad ansehen und prüfen, ob er irgendwelche Überraschungen birgt.

67
Andrzej Doyle

Dies geschieht, wenn auf eine Methode mit Paketumfang einer Klasse zugegriffen wird, die sich in demselben Paket befindet, sich aber in einem anderen Jar und Classloader befindet. 

Dies war meine Quelle, aber der Link ist jetzt defekt. Es folgt der vollständige Text aus dem Google-Cache:

Pakete (wie beim Paketzugriff) werden pro ClassLoader festgelegt.

Sie geben an, dass der übergeordnete ClassLoader die Schnittstelle und das untergeordnete Element lädt ClassLoader lädt die Implementierung. Dies funktioniert nicht wegen der ClassLoader-spezifische Natur des Paketbereichs. Die Schnittstelle ist für .__ nicht sichtbar. die Implementierungsklasse, weil .__, obwohl es sich um denselben Paketnamen handelt. Sie befinden sich in verschiedenen ClassLoadern.

Ich habe nur die Beiträge in diesem Thread überflogen, aber ich glaube, Sie haben bereits entdeckt dass dies funktioniert, wenn Sie die Schnittstelle für öffentlich erklären. Es würde auch Damit Interface und Implementierung von demselben ClassLoader geladen werden.

Wenn Sie davon ausgehen, dass beliebige Benutzer die Schnittstelle implementieren (was Sie .__ offensichtlich tun, wenn die Implementierung von einem anderen ClassLoader geladen wird), sollten Sie die Schnittstelle öffentlich machen.

Der ClassLoader-Gültigkeitsbereich des Paketbereichs (der für den Zugriff auf Methoden, Variablen usw. des Pakets Gilt) ähnelt dem allgemeinen ClassLoader-Gültigkeitsbereich von Klassennamen. Zum Beispiel kann ich zwei Klassen definieren, die beide com.foo.Bar, .__ heißen. mit völlig anderem Implementierungscode, wenn ich sie in separaten .__ definiere. Klassenlader.

Joel

86
s_t_e_v_e

Wenn getData geschützt ist, versuchen Sie, es öffentlich zu machen. Das Problem könnte in Java 1.6 bestehen und in 1.5x nicht vorhanden sein 

Ich habe das für dein Problem bekommen. Unzulässiger Zugriffsfehler

5
Shadow

Ich habe diesen Fehler in einer Spring Boot-Anwendung erhalten, bei der ein @RestController ApplicationInfoResource eine verschachtelte Klasse ApplicationInfo hatte. 

Es scheint, dass Spring Boot Dev Tools einen anderen Klassenlader verwendet hat.

Die Ausnahme, die ich bekam  

2017-05-01 17: 47: 39.588 WARN 1516 --- [nio-8080-exec-9] .m.m.a.ExceptionHandlerExceptionResolver: Behobene Ausnahme verursacht durch Handlerausführung: org.springframework.web.util.NestedServletException: Handler-Dispatch gescheitert; geschachtelte Ausnahme ist Java.lang.IllegalAccessError: versucht, Zugriff auf die Klasse com.gt.web.rest.ApplicationInfo über die Klasse com.gt.web.rest.ApplicationInfoResource $$ EnhancerBySpringCGLIB $$ 59ce500c

Lösung

Ich verschob die verschachtelte Klasse ApplicationInfo in eine separate .Java-Datei und löste das Problem.

3
gtiwari333

Dies passierte mir, als ich eine Klasse in einem Glas hatte und versuchte, auf eine private Methode in einer Klasse aus einem anderen Glas zuzugreifen. Ich habe einfach die private Methode in public geändert, neu kompiliert und implementiert, und danach hat sie gut funktioniert.

2
Alan Smith

Nur eine Ergänzung zur gelösten Antwort:

Dies könnte ein Problem mit der Instant-Run-Funktion von Android Studio sein, zum Beispiel, wenn Sie feststellen, dass Sie vergessen haben, die Codezeile: finish() zu Ihrer Aktivität hinzuzufügen, nachdem Sie eine andere geöffnet haben, und Sie die gewünschte Aktivität bereits wieder geöffnet haben nicht erneut geöffnet (was die finish() gelöst hat), dann fügen Sie finish() hinzu und Instant Run wird ausgeführt, dann stürzt die App ab, da die Logik beschädigt wurde. 


TL: DR;

Dies ist nicht unbedingt ein Code-Problem, sondern nur ein Instant-Run-Problem

0
Ab_

Aus Android-Sicht: Methode in der API-Version nicht verfügbar

Ich habe dieses Problem in erster Linie bekommen, weil ich etwas verwendet habe, das in dieser Android-Version nicht verfügbar/veraltet ist

Falscher Weg:

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

Richtiger Weg:

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

notification.Action ist hier nicht verfügbar vor API 20 und meine Min-Version war API 16.

0
Maurice

In meinem Fall bestand das Problem darin, dass eine Methode in einem Interface A als default definiert wurde, während ihre Unterklasse sie als privat überschrieb. Beim Aufruf der Methode stellte die Java Runtime fest, dass sie eine private Methode aufrief.

Ich bin immer noch verwirrt, warum der Compiler sich nicht über die private Überschreibung beschwert hat.

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
Lonely Neuron