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