web-dev-qa-db-fra.com

Interprétation du message Java.lang.NoSuchMethodError

J'obtiens le message d'erreur d'exécution suivant (avec la première ligne de la trace de pile, qui pointe vers la ligne 94). J'essaie de comprendre pourquoi il dit qu'aucune telle méthode n'existe.

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 ligne 94 de writeSummaryLink est illustrée ci-dessous.

QUESTIONS
Que signifie "ILcom" ou "Z"?
Pourquoi il y a quatre types entre parenthèses (ILcom/Sun/javadoc/ClassDoc; Lcom/Sun/javadoc/MemberDoc; Ljava/lang/String; Z) et un après les parenthèses Ljava/lang/String; lorsque la méthode printDocLinkForMenu a clairement cinq paramètres?

DÉTAIL DU CODE
La méthode writeSummaryLink est:

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

Voici la méthode que la ligne 94 appelle:

public void printDocLinkForMenu(int context, ClassDoc classDoc, MemberDoc doc,
        String label, boolean strong) {
    String docLink = getDocLink(context, classDoc, doc, label, strong);
    print(deleteParameterAnchors(docLink));
}
66
dougkramer

De section 4.3.2 de la spécification JVM:

 Interprétation des types de caractères 
 ------------------------------------- ----- 
 B octet signé octet 
 C char Caractère Unicode 
 D double virgule flottante double précision 
 F flottant virgule flottante simple précision valeur 
 I entier entier 
 J entier long long 
 L <nomclasse>; référence à une instance de classe 
 S court signé court 
 Z booléen vrai ou faux 
 [référence à une dimension de tableau 

De section 4.3.3, Descripteurs de méthode :

Un descripteur de méthode représente les paramètres que la méthode prend et la valeur qu'elle renvoie:

MethodDescriptor:
        ( ParameterDescriptor* ) ReturnDescriptor

Ainsi,

(ILcom/Sun/javadoc/ClassDoc;Lcom/Sun/javadoc/MemberDoc;Ljava/lang/String;Z) Ljava/lang/String;

se traduit par:

Une méthode avec int, ClassDoc, MemberDoc, String et boolean comme paramètres, et qui renvoie un String . Notez que seuls les paramètres de référence sont séparés par un point-virgule, car le point-virgule fait partie de leur représentation de caractère.


Donc, pour résumer:

Pourquoi il existe quatre types entre parenthèses (ILcom/Sun/javadoc/ClassDoc; Lcom/Sun/javadoc/MemberDoc; Ljava/lang/String; Z) et un après les parenthèses Ljava/lang/String; lorsque la méthode printDocLinkForMenu a clairement cinq paramètres?

Il y a cinq paramètres (int, ClassDoc, MemberDoc, String, boolean) et un type de retour (String).

85
JRL

Que signifie "ILcom" ou "Z"?

Ce sont des types de mappage pour les types natifs. Vous pouvez trouver un aperçu ici .

 Type natif | Java Type de langage | Description | Signature de type 
 --------------- + ------------ -------- + ------------------ + ---------------- 
 non signé char | jboolean | non signé 8 bits | Z 
 signé char | jbyte | signé 8 bits | B 
 non signé court | jchar | non signé 16 bits | C 
 court | jshort | signé 16 bits | S 
 long | jint | signé 32 bits | I 
 long long | jlong ​​| signé 64 bits | J 
 __ int64 | | | 
 float | jfloat | 32 bits | F 
 Double | jdouble | 64 bits | D 

De plus, la signature "L fully-qualified-class ;" signifierait la classe uniquement spécifiée par ce nom; par exemple, la signature "Ljava/lang/String;" fait référence à la classe Java.lang.String. De plus, le préfixe [ à la signature crée le tableau de ce type; par exemple, [I signifie le type de tableau int.


Quant à votre prochaine question:

Pourquoi il y a quatre types entre parenthèses (ILcom/Sun/javadoc/ClassDoc; Lcom/Sun/javadoc/MemberDoc; Ljava/lang/String; Z) et un après les parenthèses Ljava/lang/String; quand la méthode printDocLinkForMenu a clairement cinq paramètres?

Parce que vous n'exécutez pas le code que vous pensez exécuter. Le code en cours d'exécution en fait essaie d'appeler exactement la méthode décrite dans le message d'erreur, avec en fait cinq paramètres (le I doit être compté séparément) et un Stringreturn type, mais cette méthode n'existe pas dans le chemin de classe d'exécution (alors qu'elle était disponible dans le chemin de classe compiletime), d'où cette erreur. Voir aussi NoSuchMethodError javadoc :

Lancé si une application tente d'appeler une méthode spécifiée d'une classe (statique ou instance) et que cette classe n'a plus de définition de cette méthode.

Normalement, cette erreur est détecté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 changé de manière incompatibl.

Donc, vérifiez si vous exécutez réellement la bonne version du code comme vous l'avez publié dans votre question et utilisez les bonnes dépendances dans le chemin de classe d'exécution et que vous n'avez pas de bibliothèques de versions différentes en double dans le chemin de classe.

Mise à jour : l'exception signifie que le code réel essaie (implicitement) d'utiliser la méthode comme suit:

String s = printDocLinkForMenu(context, cd, (MemberDoc) emd, name, false);

Parce qu'il attend un résultat String alors qu'il est déclaré void.

17
BalusC