a java lang nosuchmethoderror exception has occurred
Interpretando el mensaje java.lang.NoSuchMethodError (2)
Aparece el siguiente mensaje de error de tiempo de ejecución (junto con la primera línea del seguimiento de la pila, que apunta a la línea 94). Estoy tratando de descubrir por qué dice que no existe tal método.
java.lang.NoSuchMethodError:
com.sun.tools.doclets.formats.html.SubWriterHolderWriter.printDocLinkForMenu(
ILcom/sun/javadoc/ClassDoc;Lcom/sun/javadoc/MemberDoc;
Ljava/lang/String;Z)Ljava/lang/String;
at com.sun.tools.doclets.formats.html.AbstractExecutableMemberWriter.writeSummaryLink(
AbstractExecutableMemberWriter.java:94)
La línea 94 de writeSummaryLink se muestra a continuación.
PREGUNTAS
¿Qué significa "ILcom" o "Z"?
Por qué hay cuatro tipos entre paréntesis (ILcom / sun / javadoc / ClassDoc; Lcom / sun / javadoc / MemberDoc; Ljava / lang / String; Z) y uno después de los paréntesis Ljava / lang / String; cuando el método printDocLinkForMenu claramente tiene cinco parámetros?
CÓDIGO DETALLE
El método writeSummaryLink es:
protected void writeSummaryLink(int context, ClassDoc cd, ProgramElementDoc member) {
ExecutableMemberDoc emd = (ExecutableMemberDoc)member;
String name = emd.name();
writer.strong();
writer.printDocLinkForMenu(context, cd, (MemberDoc) emd, name, false); // 94
writer.strongEnd();
writer.displayLength = name.length();
writeParameters(emd, false);
}
Aquí está el método que la línea 94 está llamando:
public void printDocLinkForMenu(int context, ClassDoc classDoc, MemberDoc doc,
String label, boolean strong) {
String docLink = getDocLink(context, classDoc, doc, label, strong);
print(deleteParameterAnchors(docLink));
}
¿Qué significa "ILcom" o "Z"?
Esos son tipos de mapeo para tipos nativos. Puede encontrar una descripción general here .
Native Type | Java Language Type | Description | Type signature ---------------+--------------------+------------------+---------------- unsigned char | jboolean | unsigned 8 bits | Z signed char | jbyte | signed 8 bits | B unsigned short | jchar | unsigned 16 bits | C short | jshort | signed 16 bits | S long | jint | signed 32 bits | I long long | jlong | signed 64 bits | J __int64 | | | float | jfloat | 32 bits | F double | jdouble | 64 bits | D
Además, la firma
"L fully-qualified-class ;"
significaría la clase especificada únicamente por ese nombre; por ejemplo, la firma"Ljava/lang/String;"
se refiere a la clasejava.lang.String
. Además, el prefijo[
a la firma hace que la matriz de ese tipo; por ejemplo,[I
significa el tipo de matriz int.
En cuanto a tu próxima pregunta:
Por qué hay cuatro tipos entre paréntesis (ILcom / sun / javadoc / ClassDoc; Lcom / sun / javadoc / MemberDoc; Ljava / lang / String; Z) y uno después de los paréntesis Ljava / lang / String; cuando el método printDocLinkForMenu claramente tiene cinco parámetros?
Porque no estás ejecutando el código que crees que estás ejecutando. El código actual está intentando llamar exactamente a ese método descrito en el mensaje de error, con cinco parámetros en realidad (el I
debe contar por separado) y un tipo de retorno de String
, pero este método no existe en el classpath en tiempo de ejecución (mientras estaba disponible en el classpath compiletime), de ahí este error. También vea el javadoc NoSuchMethodError
:
Lanzado 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 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.
Por lo tanto, verifique si realmente está ejecutando la versión correcta del código como lo ha publicado en su pregunta y está utilizando las dependencias correctas en el classpath de tiempo de ejecución y no tiene bibliotecas duplicadas de versiones diferentes en el classpath.
Actualización : la excepción significa que el código real está (implícitamente) tratando de usar el método de la siguiente manera:
String s = printDocLinkForMenu(context, cd, (MemberDoc) emd, name, false);
Porque espera un resultado de String
mientras se declara void
.
De la sección 4.3.2 de la especificación de JVM:
Character Type Interpretation ------------------------------------------ B byte signed byte C char Unicode character D double double-precision floating-point value F float single-precision floating-point value I int integer J long long integer L<classname>; reference an instance of class S short signed short Z boolean true or false [ reference one array dimension
De la sección 4.3.3, descripciones del método :
Un descriptor de método representa los parámetros que toma el método y el valor que devuelve:
MethodDescriptor:
( ParameterDescriptor* ) ReturnDescriptor
Así,
(ILcom/sun/javadoc/ClassDoc;Lcom/sun/javadoc/MemberDoc;Ljava/lang/String;Z) Ljava/lang/String;
se traduce a:
Un método con int
, ClassDoc
, MemberDoc
, String
y boolean
como parámetros, y que devuelve un String
. Tenga en cuenta que solo los parámetros de referencia se separan con un punto y coma, ya que el punto y coma es parte de la representación de sus caracteres.
Así que para resumir:
Por qué hay cuatro tipos entre paréntesis (ILcom / sun / javadoc / ClassDoc; Lcom / sun / javadoc / MemberDoc; Ljava / lang / String; Z) y uno después de los paréntesis Ljava / lang / String; cuando el método printDocLinkForMenu claramente tiene cinco parámetros?
Hay cinco parámetros (int, ClassDoc, MemberDoc, String, boolean) y un tipo de retorno (String).