has - throw exception java
java.lang.IllegalAccessError: intentado acceder al método (8)
Recibo una excepción y no puedo encontrar el motivo.
La excepción que obtengo es:
java.lang.IllegalAccessError: intentado acceder al método Connected.getData (Ljava / lang / String;) Ljava / sql / ResultSet; de la clase B
El método es público.
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;
}
estoy usando apache tomcat 5.5.12 y JAVA 1.6
En mi caso, el problema fue que se definió un método en algunas Interfaz A
como default
, mientras que su subclase lo anuló como privado. Luego, cuando se llamó al método, el Java Runtime se dio cuenta de que estaba llamando a un método privado.
Todavía estoy desconcertado sobre por qué el compilador no se quejó de la anulación privada ..
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();
}
Es casi seguro que está utilizando una versión diferente de la clase en tiempo de ejecución a la que espera. En particular, la clase de tiempo de ejecución sería diferente a la que compiló (de lo contrario, esto habría causado un error en tiempo de compilación): ¿ese método ha sido alguna vez private
? ¿Tiene versiones antiguas de las clases / jarras en su sistema en cualquier lugar?
Como los javadocs para el estado IllegalAccessError
,
Normalmente, este error es capturado por el compilador; este error solo puede ocurrir en tiempo de ejecución si la definición de una clase ha cambiado de manera incompatible.
Definitivamente miraría tu classpath y verifica si contiene sorpresas.
Estaba obteniendo este error en una aplicación Spring Boot donde @RestController ApplicationInfoResource
tenía una clase anidada ApplicationInfo
.
Parece que Spring Boot Dev Tools
estaba usando un cargador de clases diferente.
La excepción que estaba recibiendo
2017-05-01 17: 47: 39.588 WARN 1516 --- [nio-8080-exec-9] .mmaExceptionHandlerExceptionResolver: excepción resuelta causada por la ejecución del controlador: org.springframework.web.util.NestedServletException: el envío del controlador falló; la excepción anidada es java.lang.IllegalAccessError: intentado acceder a la clase com.gt.web.rest.ApplicationInfo de la clase com.gt.web.rest.ApplicationInfoResource $$ EnhancerBySpringCGLIB $$ 59ce500c
Solución
Moví la clase anidada ApplicationInfo
a un archivo .java separado y me deshice del problema.
Esto me sucedió cuando tuve una clase en un jar tratando de acceder a un método privado en una clase de otro jar. Simplemente cambié el método privado a público, recompilado e implementado, y funcionó bien después.
Esto ocurre al acceder a un método de ámbito de paquete de una clase que está en el mismo paquete pero está en un jar y un cargador de clases diferentes.
This fue mi fuente, pero el enlace ahora está roto. A continuación se muestra el texto completo de la caché de google:
Los paquetes (como en el acceso al paquete) tienen un alcance por ClassLoader.
Usted declara que el ClassLoader padre carga la interfaz y el ClassLoader hijo carga la implementación. Esto no funcionará debido a la naturaleza específica de ClassLoader del alcance del paquete. La interfaz no es visible para la clase de implementación porque, a pesar de que es el mismo nombre de paquete, están en diferentes ClassLoaders.
Solo analicé las publicaciones en este hilo, pero creo que ya descubriste que esto funcionará si declaras que la interfaz es pública. También funcionaría tener la interfaz y la implementación cargadas por el mismo ClassLoader.
En realidad, si espera que gente arbitraria implemente la interfaz (que aparentemente hace si la implementación está siendo cargada por un ClassLoader diferente), entonces debe hacer que la interfaz sea pública.
El ámbito de ClassLoader del alcance del paquete (que se aplica al acceso a los métodos de paquete, variables, etc.) es similar al alcance general de ClassLoader de los nombres de clase. Por ejemplo, puedo definir dos clases, ambas llamadas com.foo.Bar, con un código de implementación completamente diferente si las defino en ClassLoaders por separado.
Joel
Si getData
está protegido, intente hacerlo público. El problema podría existir en JAVA 1.6 y estar ausente en 1.5x
Tengo esto para tu problema. Error de acceso ilegal
Solo una adición a la respuesta resuelta:
Esto PODRÍA ser un problema con la función de ejecución instantánea de Android Studio, por ejemplo, si se dio cuenta de que olvidó agregar la línea de código: finish()
a su actividad después de abrir otra, y ya ha reabierto la actividad que no debería han reabierto (que el finish()
resuelto), luego agregas finish()
y se produce Instant Run, luego la aplicación se bloqueará debido a que se ha roto la lógica.
TL: DR;
Esto no es necesariamente un problema de código, solo un problema de ejecución instantánea
Desde la perspectiva de Android: Método no disponible en la versión api
Estaba recibiendo este problema principalmente porque estaba usando algo que no está disponible / en desuso en esa versión de Android
Camino equivocado:
Notification.Builder nBuilder = new Notification.Builder(mContext);
nBuilder.addAction(new Notification.Action(android.R.drawable.ic_menu_view,"PAUSE",pendingIntent));
Manera correcta:
Notification.Builder nBuilder = new Notification.Builder(mContext);
nBuilder.addAction(android.R.drawable.ic_media_pause,"PAUSE",pendingIntent);
aquí Notification.Action no está disponible antes de API 20 y mi versión mínima fue API 16