Je reçois une exception et je ne trouve pas la raison de celle-ci.
L'exception que je reçois est:
Java.lang.IllegalAccessError: tentative d'accès à la méthode Connected.getData (Ljava/lang/String;) Ljava/sql/ResultSet; de classe B
La méthode est publique.
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;
}
j'utilise Apache Tomcat 5.5.12 et Java 1.6
Vous utilisez presque certainement une version de la classe différente de celle attendue au moment de l'exécution. En particulier, la classe d'exécution serait différente de celle contre laquelle vous avez compilé (sinon, cela aurait causé une erreur de compilation) - cette méthode ever at-elle été private
? Avez-vous d'anciennes versions des classes/jars sur votre système?
En tant que javadocs pour IllegalAccessError
,
Normalement, cette erreur est interceptée par le compilateur. cette erreur ne peut se produire au moment de l'exécution que si la définition d'une classe a été modifiée de manière incompatible.
Je regarderais certainement votre chemin de classe et vérifierais qu'il réserve des surprises.
Cela se produit lors de l'accès à une méthode de package d'une classe appartenant au même package mais se trouvant dans un jar et un chargeur de classes différents.
Ceci était ma source, mais le lien est maintenant brisé. Voici le texte intégral de Google Cache:
Les packages (comme dans l'accès aux packages) sont étendus par ClassLoader.
Vous indiquez que le ClassLoader parent charge l'interface et l'enfant ClassLoader charge l'implémentation. Cela ne fonctionnera pas à cause du Nature spécifique au ClassLoader de la portée du package. L’interface n’est pas visible pour la classe d'implémentation car, même s'il s'agit du même nom de package, ils sont dans différents ClassLoaders.
Je n'ai parcouru que les posts de ce fil de discussion, mais je pense que vous avez déjà découvert que cela fonctionnera si vous déclarez que l'interface est publique. Ce serait aussi travaillez pour que l'interface et l'implémentation soient chargées par le même ClassLoader.
Vraiment, si vous vous attendez à ce que des personnes arbitraires mettent en oeuvre l'interface (ce que vous faites apparemment si l'implémentation est chargée par un autre ClassLoader), vous devez alors rendre l'interface publique.
La portée de l'étendue du package par ClassLoader (qui s'applique à l'accès aux méthodes, variables, etc. du package. Package) est similaire à l'étendue générale de. noms de classe. Par exemple, je peux définir deux classes, toutes deux nommées com.foo.Bar, avec un code d'implémentation totalement différent si je les définis séparément ClassLoaders.
Joel
Si getData
est protégé, essayez de le rendre public. Le problème pourrait exister dans Java 1.6 et être absent dans 1.5x
J'ai ceci pour ton problème. Erreur d'accès illégal
Je recevais cette erreur sur une application Spring Boot où un @RestController ApplicationInfoResource
avait une classe imbriquée ApplicationInfo
.
Il semble que le Spring Boot Dev Tools
utilisait un autre chargeur de classes.
L'exception que je devenais
2017-05-01 17: 47: 39.588 WARN 1516 --- [nio-8080-exec-9] .m.m.a.ExceptionHandlerExceptionResolver: Une exception résolue a provoqué par exécution du gestionnaire: org.springframework.web.util.NestedServletException: répartition du gestionnaire échoué; L'exception imbriquée est Java.lang.IllegalAccessError: essayé de classe d'accès com.gt.web.rest.ApplicationInfo de la classe com.gt.web.rest.ApplicationInfoResource $$ EnhancerBySpringCGLIB $$ 59ce500c
Solution
J'ai déplacé la classe imbriquée ApplicationInfo
dans un fichier .Java séparé et je me suis débarrassé du problème.
Cela m'est arrivé quand une classe dans un bocal essayait d'accéder à une méthode privée dans une classe à partir d'un autre bocal. J'ai simplement changé la méthode privée en publique, recompilée et déployée, et cela a fonctionné correctement par la suite.
Juste un ajout à la réponse résolue:
Cela pourrait poser un problème avec la fonction d'exécution instantanée d'Android Studio, par exemple, si vous réalisez que vous avez oublié d'ajouter la ligne de code: finish()
à votre activité après en avoir ouvert une autre, et que vous avez déjà rouvert l'activité Si vous n'avez pas rouvert (que le finish()
a résolu), vous ajoutez ensuite finish()
et Instant Run se produit, puis l'application se bloque, car la logique a été interrompue.
TL: DR;
Ce n'est pas nécessairement un problème de code, juste un problème d'exécution instantanée
Du point de vue Android: Méthode non disponible dans la version api
J'obtenais ce problème principalement parce que j'utilisais quelque chose qui n'est pas disponible/obsolète dans cette version Android
Fausse route:
Notification.Builder nBuilder = new Notification.Builder(mContext);
nBuilder.addAction(new Notification.Action(Android.R.drawable.ic_menu_view,"PAUSE",pendingIntent));
La bonne façon:
Notification.Builder nBuilder = new Notification.Builder(mContext);
nBuilder.addAction(Android.R.drawable.ic_media_pause,"PAUSE",pendingIntent);
ici Notification.Action n'est pas disponible avant API 20 et ma version minimale était API 16.
Dans mon cas, le problème était qu’une méthode était définie dans une interface A
comme default
, alors que sa sous-classe l’avait surchargée comme privée. Ensuite, lorsque la méthode a été appelée, Java Runtime s'est rendu compte qu'il appelait une méthode privée.
Je ne comprends toujours pas pourquoi le compilateur ne s'est pas plaint du remplacement privé.
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();
}