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


72

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; ab 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 benutze Apache Tomcat 5.5.12 und JAVA 1.6

Antworten:


81

Sie verwenden zur Laufzeit mit ziemlicher Sicherheit eine andere Version der Klasse als die, die Sie erwarten. Insbesondere wäre die Laufzeitklasse anders als die, die Sie gegen kompiliert haben (sonst würde dies einen Fehler bei der Kompilierung verursacht haben) - diese Methode hat jemals gewesen private? Haben Sie irgendwo alte Versionen der Klassen / Jars auf Ihrem System?

Als die Javadocs für den IllegalAccessErrorStaat,

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

Ich würde mir auf jeden Fall Ihren Klassenpfad ansehen und prüfen, ob er Überraschungen enthält.


3
@yossi: Wie hast du es gelöst? Kompiliere die Soruce neu und lege sie in deinen Klassenpfad? Nur neugierig, ob Sie die ursprüngliche Klasse dekompiliert und gesägt haben, was darin enthalten war.
Victor

Als ich dies hatte, hatte ich die Datei mit einer privaten Funktion gespeichert, die veröffentlicht wurde, und so sah der Editor alles in der .jsp-Datei als in Ordnung an, aber ich hatte das Hauptprogramm nicht neu gestartet, so dass es die neue Version nicht wirklich kompiliert hatte .
Brian White

Ich erhalte diesen Fehler von einem gerade installierten Maven-Paket. Ich habe das Projekt aktualisiert und bereinigt, aber alles scheint sich zu ändern.
Softwareplay

105

Dies geschieht beim Zugriff auf eine Methode mit Paketbereich einer Klasse, die sich im selben Paket befindet, sich jedoch in einem anderen JAR und Klassenlader befindet.

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

Pakete (wie beim Paketzugriff) sind pro ClassLoader gültig.

Sie geben an, dass der übergeordnete ClassLoader die Schnittstelle und der untergeordnete ClassLoader die Implementierung lädt. Dies funktioniert aufgrund der ClassLoader-spezifischen Natur des Paketumfangs nicht. Die Schnittstelle ist für die Implementierungsklasse nicht sichtbar, da sie sich, obwohl es sich um denselben Paketnamen handelt, in verschiedenen ClassLoadern befindet.

Ich habe nur die Beiträge in diesem Thread überflogen, aber ich denke, Sie haben bereits festgestellt, dass dies funktioniert, wenn Sie die Benutzeroberfläche als öffentlich deklarieren. Es würde auch funktionieren, wenn sowohl die Schnittstelle als auch die Implementierung von demselben ClassLoader geladen würden.

Wenn Sie erwarten, dass beliebige Personen die Schnittstelle implementieren (was Sie anscheinend tun, wenn die Implementierung von einem anderen ClassLoader geladen wird), sollten Sie die Schnittstelle öffentlich machen.

Das ClassLoader-Scoping des Paketbereichs (das für den Zugriff auf Paketmethoden, Variablen usw. gilt) ähnelt dem allgemeinen ClassLoader-Scoping von Klassennamen. Zum Beispiel kann ich zwei Klassen mit dem Namen com.foo.Bar mit völlig unterschiedlichem Implementierungscode definieren, wenn ich sie in separaten ClassLoadern definiere.

Joel


1
Ich habe dieses Problem commons-collections-3.2.1.jarunter JBoss EAP 5.3 mit Struts 1.1 behoben, da sich diese JAR bereits in den JBoss-Bibliotheken befindet, aber auch in meinen Anwendungen enthalten war. Ich habe die JAR aus meiner Anwendung entfernt, wodurch das Problem behoben wurde.
Julien Kronegg

2
Du hast mir gerade viel Zeit und Nerven gespart. Sehr schön!
Msteiger

Ich bekomme diesen Fehler für eine öffentliche statische Methode, die jetzt ein zweites Argument akzeptiert. Die alte JAR-Datei existiert nicht mehr, seit ich sie ersetzt habe. Irgendwelche Ideen?
Markus

Ich hatte eine abstrakte Klasse mit dem Modifikator package-private und eine andere Klasse (die die erstere erweitert) mit dem Modifikator public im selben Paket. Beide waren in einem einfachen Glas. Ich habe eine Methode der abstrakten Klasse aus einer Web-App verwendet. Das Seltsame ist, dass ich meine App in Tomcat aus Eclipse heraus bereitstellen konnte, aber nicht in Tomcat auf einem Remotecomputer. Ich habe den Zugriffsmodifikator der abstrakten Klasse in public geändert und alles hat funktioniert.
Fabriziocucci

Ich habe in meinem Fall ein Downgrade des Firefox-Treibers von 2.53.0auf 2.44.0geholfen (ich habe Grails 2.3.11 verwendet, eine alte Version).
flaz14


4

Ich habe diesen Fehler in einer Spring Boot-Anwendung erhalten, in @RestController ApplicationInfoResourceder eine verschachtelte Klasse vorhanden war ApplicationInfo.

Es scheint, dass der Spring Boot Dev Toolseinen anderen Klassenlader verwendet hat.

Die Ausnahme, die ich bekam

2017-05-01 17: 47: 39.588 WARN 1516 --- [nio-8080-exec-9] .mmaExceptionHandlerExceptionResolver: Behobene Ausnahme durch Handler-Ausführung: org.springframework.web.util.NestedServletException: Handler-Versand fehlgeschlagen; verschachtelte Ausnahme ist java.lang.IllegalAccessError: Es wurde versucht, über die Klasse com.gt.web.rest.ApplicationInfoResource $$ EnhancerBySpringCGLIB $$ 59ce500c auf die Klasse com.gt.web.rest.ApplicationInfo zuzugreifen

Lösung

Ich habe die verschachtelte Klasse ApplicationInfoin eine separate Java-Datei verschoben und das Problem behoben.


Sie sollten auch in Betracht ziehen, die Dev Tools von Spring Boot aus Ihrem Klassenpfad zu entfernen - möglicherweise nur vorübergehend. In meinem Fall IllegalAccessErrorwar das überhaupt nicht vernünftig. Aber als ich die Maven-Abhängigkeit zu Dev Tools entfernte und kurz darauf wieder hinzufügte, funktionierte alles so, wie es sollte.
Peter Wippermann

Ich danke dir sehr! Du hast den Tag gerettet.
Valijon

3

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


0

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

Ich habe dieses Problem hauptsächlich erhalten, 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);

hier Notification.Action ist vor API 20 nicht verfügbar und meine Mindestversion war API 16


0

Nur eine Ergänzung zur gelösten Antwort:

Dies KANN ein Problem mit der Sofortausführungsfunktion von Android Studio sein, wenn Sie beispielsweise festgestellt haben, dass Sie vergessen haben, die Codezeile finish()zu Ihrer Aktivität hinzuzufügen, nachdem Sie eine andere geöffnet haben, und die Aktivität, die Sie nicht hätten öffnen sollen, bereits wieder geöffnet haben ( was das finish()gelöst ist), dann fügst du hinzu finish()und Instant Run tritt auf, dann stürzt die App ab, da die Logik gebrochen wurde.


TL: DR;

Dies ist nicht unbedingt ein Codeproblem, sondern nur ein Sofortausführungsproblem


0

In meinem Fall bestand das Problem darin, dass eine Methode in einer Schnittstelle Aals definiert wurde default, während ihre Unterklasse sie als privat überschrieb. Als die Methode aufgerufen wurde, stellte die Java-Laufzeit fest, dass eine private Methode aufgerufen wurde.

Ich bin immer noch verwirrt, warum sich der Compiler nicht über die private Außerkraftsetzung 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

In meinem Fall wurde dieser Fehler beim Ausführen meiner App in Wildfly mit der von Eclipse bereitgestellten .ear-Datei angezeigt. Da es von Eclipse bereitgestellt wurde, enthielt der Bereitstellungsordner keine .ear-Datei, sondern einen Ordner, der es darstellt, und darin alle Gläser, die in der .ear-Datei enthalten gewesen wären. als ob das Ohr geöffnet wäre.

Also hatte ich im Glas:

class MySuperClass {
  protected void mySuperMethod {}
}

Und in einem anderen Glas:

class MyExtendingClass extends MySuperClass {

  class MyChildrenClass {
    public void doSomething{
      mySuperMethod();
    }
  }
}

Die Lösung hierfür war das Hinzufügen einer neuen Methode zu MyExtendingClass:

class MyExtendingClass extends MySuperClass {

  class MyChildrenClass {
    public void doSomething{
      mySuperMethod();
    }
  }

  @Override
  protected void mySuperMethod() {
    super.mySuperMethod();
  }
}

0

Ich habe den gleichen Fehler aufgrund eines Konfigurationsproblems in Intellij erhalten. Wie im Screenshot gezeigt. Haupt- und Testmodul zeigten auf zwei verschiedene JDK. (Drücken Sie im Intellij-Projekt F12, um die Moduleinstellungen zu öffnen.)

Außerdem verwendeten alle meine Dto's @ lombok.Builder, was ich in @Data änderte.

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein


0

Ich bekam eine ähnliche Ausnahme, aber auf Klassenebene

zB Verursacht durch: java.lang.IllegalAccessError: versucht, auf die Klasse zuzugreifen ....

Ich habe das behoben, indem ich meine Klasse öffentlich gemacht habe.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.