Recibo un NoSuchMethodError
error al ejecutar mi programa Java. ¿Qué pasa y cómo lo soluciono?
Recibo un NoSuchMethodError
error al ejecutar mi programa Java. ¿Qué pasa y cómo lo soluciono?
Respuestas:
Sin más información, es difícil determinar el problema, pero la causa principal es que probablemente compiló una clase contra una versión diferente de la clase a la que le falta un método, que el que está utilizando al ejecutarlo.
Mire el seguimiento de la pila ... Si la excepción aparece cuando se llama a un método en un objeto en una biblioteca, lo más probable es que esté usando versiones separadas de la biblioteca al compilar y ejecutar. Asegúrese de tener la versión correcta en ambos lugares.
Si la excepción aparece cuando se llama a un método en objetos instanciados por clases que realizó, entonces su proceso de compilación parece ser defectuoso. Asegúrese de que los archivos de clase que está ejecutando estén actualizados cuando compila.
Caused by
sección en el seguimiento de la pila para encontrar la clase / jarra culpable
Estaba teniendo tu problema, y así es como lo solucioné. Los siguientes pasos son una forma de trabajo para agregar una biblioteca. Había hecho los dos primeros pasos correctamente, pero no había hecho el último arrastrando el archivo ".jar" directamente desde el sistema de archivos a la carpeta "lib" en mi proyecto eclipse. Además, tuve que eliminar la versión anterior de la biblioteca tanto de la ruta de compilación como de la carpeta "lib".
Tenga en cuenta que en el caso de la reflexión, obtiene un NoSuchMethodException
, mientras que con el código no reflexivo, obtiene NoSuchMethodError
. Tiendo a mirar en lugares muy diferentes cuando me enfrento a uno versus el otro.
Si tiene acceso para cambiar los parámetros de JVM, agregar resultados detallados debería permitirle ver qué clases se están cargando desde qué archivos JAR.
java -verbose:class <other args>
Cuando se ejecuta su programa, la JVM debe volcar a información estándar como:
...
[Junit.framework.Assert cargado del archivo: / C: /Program%20Files/junit3.8.2/junit.jar]
...
Esto generalmente se produce cuando se usa un sistema de compilación como Apache Ant que solo compila archivos java cuando el archivo java es más nuevo que el archivo de clase. Si la firma de un método cambia y las clases usaban la versión anterior, es posible que las cosas no se compilen correctamente. La solución habitual es hacer una reconstrucción completa (generalmente "ant clean" y luego "ant").
Algunas veces esto también puede ser causado cuando se compila contra una versión de una biblioteca pero se ejecuta contra una versión diferente.
Si usa Maven u otro marco, y obtiene este error casi al azar, intente una instalación limpia como ...
clean install
Es especialmente probable que esto funcione si escribió el objeto y sabe que tiene el método. Trabajó para mi.
Esto también puede ser el resultado del uso de la reflexión. Si tiene un código que se refleja en una clase y extrae un método por nombre (por ejemplo: con Class.getDeclaredMethod("someMethodName", .....)
), cada vez que cambie el nombre del método, como durante un refactorizador, deberá recordar actualizar los parámetros al método de reflexión para que coincida con el nueva firma del método, o la getDeclaredMethod
llamada arrojará un NoSuchMethodException
.
Si esta es la razón, entonces el seguimiento de la pila debería mostrar el punto en que se invoca el método de reflexión, y solo necesitará actualizar los parámetros para que coincidan con la firma del método real.
En mi experiencia, esto surge ocasionalmente cuando la unidad prueba métodos / campos privados y usa una TestUtilities
clase para extraer campos para la verificación de pruebas. (Generalmente con código heredado que no fue diseñado teniendo en cuenta las pruebas unitarias).
Si está escribiendo una aplicación web, asegúrese de no tener versiones conflictivas de un jar en el directorio de la biblioteca global de su contenedor y también en su aplicación. Es posible que no sepa qué jar está utilizando el cargador de clases.
p.ej
Estos problemas son causados por el uso del mismo objeto en las mismas dos clases. Los objetos utilizados no contienen un nuevo método que se ha agregado que contiene la nueva clase de objeto.
ex:
filenotnull=/DayMoreConfig.conf
16-07-2015 05:02:10:ussdgw-1: Open TCP/IP connection to SMSC: 10.149.96.66 at 2775
16-07-2015 05:02:10:ussdgw-1: Bind request: (bindreq: (pdu: 0 9 0 [1]) 900 900 GEN 52 (addrrang: 0 0 2000) )
Exception in thread "main" java.lang.NoSuchMethodError: gateway.smpp.PDUEventListener.<init>(Lgateway/smpp/USSDClient;)V
at gateway.smpp.USSDClient.bind(USSDClient.java:139)
at gateway.USSDGW.initSmppConnection(USSDGW.java:274)
at gateway.USSDGW.<init>(USSDGW.java:184)
at com.vinaphone.app.ttn.USSDDayMore.main(USSDDayMore.java:40)
-bash-3.00$
Estos problemas son causados por la clase similar 02 concomitante (1 en src, 1 en el archivo jar aquí es gateway.jar)
Acabo de resolver este error al reiniciar mi Eclipse y ejecutar la aplicación. La razón de mi caso puede ser porque reemplazo mis archivos fuente sin cerrar mi proyecto o Eclipse. Lo que causó una versión diferente de las clases que estaba usando.
Pruebe de esta manera: elimine todos los archivos .class en los directorios de su proyecto (y, por supuesto, todos los subdirectorios). Reconstruir.
A veces mvn clean
(si está utilizando Maven) no limpia los archivos .class creados manualmente por javac
. Y esos archivos antiguos contienen firmas antiguas, lo que lleva a NoSuchMethodError
.
Solo agregando a las respuestas existentes. Estaba enfrentando este problema con tomcat en eclipse. Había cambiado una clase e hice los siguientes pasos,
Limpié y construyó el proyecto en eclpise
instalación limpia de mvn
Aún así me enfrentaba al mismo error. Luego limpié tomcat, limpié el directorio de trabajo de tomcat y reinicié el servidor y mi problema desapareció. Espero que esto ayude a alguien
Para responder la pregunta original. De acuerdo con los documentos de Java aquí :
"NoSuchMethodError" Se genera si una aplicación intenta llamar a un método específico de una clase (ya sea estática o instancia), y esa clase ya no tiene una definición de ese método.
Normalmente, este error es detectado 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.
Solucioné este problema en Eclipse cambiando el nombre de un archivo de prueba Junit.
En mi espacio de trabajo de Eclipse tengo un proyecto de aplicación y un proyecto de prueba.
El proyecto de prueba tiene el proyecto de la aplicación como un proyecto requerido en la ruta de compilación.
Comenzó a obtener el NoSuchMethodError.
Luego me di cuenta de que la clase en el proyecto de prueba tenía el mismo nombre que la clase en el proyecto de la aplicación.
App/
src/
com.example/
Projection.java
Test/
src/
com.example/
Projection.java
Después de cambiar el nombre de la prueba al nombre correcto "ProjectionTest.java", la excepción desapareció.
Yo tenía el mismo error:
Exception in thread "main" java.lang.NoSuchMethodError: com.fasterxml.jackson.core.JsonGenerator.writeStartObject(Ljava/lang/Object;)V
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:151)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3681)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3057)
Para resolverlo, verifiqué, en primer lugar, el Diagrama de dependencia del módulo ( click in your POM the combination -> Ctrl+Alt+Shift+U
o right click in your POM -> Maven -> Show dependencies
) para comprender dónde estaba exactamente el conflicto entre bibliotecas (Intelij IDEA). En mi caso particular, tenía diferentes versiones de las dependencias de Jackson.
1) Entonces, agregué directamente en mi POM del proyecto explícitamente la versión más alta: 2.8.7 de estos dos.
En propiedades:
<jackson.version>2.8.7</jackson.version>
Y como dependencia:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
2) Pero también se puede resolver usando Exclusiones de dependencia .
Por el mismo principio que a continuación en el ejemplo:
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
La dependencia con la versión no deseada se excluirá de su proyecto.
En mi caso, tenía un proyecto de varios módulos y el escenario era como si com.xyz.TestClass
estuviera en el módulo A
y, además, en el módulo B
y el módulo A
dependía del módulo B
. Entonces, al crear un jar de ensamblaje, creo que solo se retuvo una versión de la clase si eso no tiene el método invocado, entonces estaba obteniendoNoSuchMethodError
excepción de tiempo de ejecución, pero la compilación estuvo bien.
Relacionado: https://reflectoring.io/nosuchmethod/
La respuesta anterior explica muy bien ... solo para agregar una cosa Si está usando eclipse, use ctrl + shift + T e ingrese la estructura de paquete de la clase (por ejemplo: gateway.smpp.PDUEventListener), encontrará todos los frascos / proyectos donde está presente . Elimine los tarros innecesarios de classpath o agregue arriba en class path. Ahora recogerá el correcto.
Me encontré con un problema similar.
Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I
Finalmente identifiqué que la causa raíz estaba cambiando el tipo de datos de la variable.
Employee.java
-> Contiene la variable ( EmpId
) cuyo tipo de datos se ha cambiado de int
a String
.ReportGeneration.java
-> Recupera el valor con el captador, getEmpId()
.Se supone que debemos reempaquetar el jar incluyendo solo las clases modificadas. Como no hubo cambios ReportGeneration.java
, solo Employee.class
incluí el archivo Jar. Tuve que incluir el ReportGeneration.class
archivo en el jar para resolver el problema.
He tenido el mismo problema Esto también se produce cuando hay una ambigüedad en las clases. Mi programa intentaba invocar un método que estaba presente en dos archivos JAR presentes en la misma ubicación / ruta de clase. Elimine un archivo JAR o ejecute su código de modo que solo se use un archivo JAR. Compruebe que no está utilizando el mismo JAR o diferentes versiones del mismo JAR que contienen la misma clase.
DISP_E_EXCEPTION [paso] [] [Z-JAVA-105 Excepción de Java java.lang.NoSuchMethodError (com.example.yourmethod)]
La mayoría de las veces se captura java.lang.NoSuchMethodError en el compilador, pero a veces puede ocurrir en tiempo de ejecución. Si este error ocurre en tiempo de ejecución, la única razón podría ser el cambio en la estructura de clases que lo hizo incompatible.
Mejor explicación: https://www.journaldev.com/14538/java-lang-nosuchmethoderror
También he encontrado este error.
Mi problema fue que he cambiado la firma de un método, algo así como
void invest(Currency money){...}
dentro
void invest(Euro money){...}
Este método fue invocado desde un contexto similar a
public static void main(String args[]) {
Bank myBank = new Bank();
Euro capital = new Euro();
myBank.invest(capital);
}
El compilador guardó silencio con respecto a las advertencias / errores, ya que el capital es tanto moneda como euro.
El problema apareció debido al hecho de que solo compilé la clase en la que se definió el método: Bank, pero no la clase desde la que se llama al método, que contiene el método main ().
Este problema no es algo que pueda encontrar con demasiada frecuencia, ya que con mayor frecuencia el proyecto se reconstruye manualmente o se activa automáticamente una acción de compilación, en lugar de solo compilar la clase modificada.
Mi caso de uso fue que generé un archivo .jar que iba a usarse como un hotfix, que no contenía la App.class ya que no se modificó. Tenía sentido para mí no incluirlo, ya que mantuve la herencia básica de la clase base del argumento inicial.
La cuestión es que, cuando compila una clase, el bytecode resultante es algo estático , en otras palabras, es una referencia difícil .
El bytecode original desmontado (generado con la herramienta javap) se ve así:
#7 = Methodref #2.#22 // Bank.invest:(LCurrency;)V
Después de que ClassLoader carga el nuevo Bank.class compilado, no encontrará dicho método, parece que se eliminó y no se modificó, por lo tanto, el error con nombre.
Espero que esto ayude.
Tuve un problema similar con mi Proyecto Gradle usando Intelij. Lo resolví eliminando el paquete .gradle (ver captura de pantalla a continuación) y reconstruyendo el Proyecto. Paquete .gradle
NoSuchMethodError: He pasado un par de horas solucionando este problema, finalmente lo solucioné simplemente renombrando el nombre del paquete, limpiando y compilando ... Intenta limpiar primero si no funciona, intenta renombrar el nombre de la clase o el nombre del paquete y limpia la compilación ... . debería ser reparado. Buena suerte.
Si el nombre de su archivo es diferente al nombre de la clase que contiene el método principal, entonces es posible que este error pueda causar.