Интерпретация сообщения java.lang.NoSuchMethodError - PullRequest
64 голосов
/ 01 июня 2010

Я получаю следующее сообщение об ошибке во время выполнения (вместе с первой строкой трассировки стека, которая указывает на строку 94). Я пытаюсь понять, почему говорится, что такого метода не существует.

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)

Строка 94 writeSummaryLink показана ниже.

ВОПРОСЫ
Что означает "ILcom" или "Z"?
Почему в скобках четыре типа (ILcom / ВС / Javadoc / ClassDoc; Lcom / ВС / Javadoc / MemberDoc; Ljava / языки / String; Z) и один после скобок Ljava / языки / String; когда метод printDocLinkForMenu явно имеет пять параметров?

ДЕТАЛИ КОДА
Метод writeSummaryLink:

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

Вот строка метода 94, которая вызывается:

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

Ответы [ 2 ]

83 голосов
/ 01 июня 2010

С раздел 4.3.2 спецификации 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

С раздел 4.3.3, дескрипторы метода :

Дескриптор метода представляет параметры, которые принимает метод, и значение, которое он возвращает:

MethodDescriptor:
        ( ParameterDescriptor* ) ReturnDescriptor

Таким образом,

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

переводится как:

Метод с int, ClassDoc, MemberDoc, String и boolean в качестве параметров, который возвращает String. Обратите внимание, что только контрольные параметры разделяются точкой с запятой, поскольку точка с запятой является частью их символьного представления.


Итак, подведем итог:

Почему в скобках четыре типа (ILcom / sun / javadoc / ClassDoc; Lcom / sun / javadoc / MemberDoc; Ljava / lang / String; Z) и один после скобок Ljava / lang / String; когда метод printDocLinkForMenu явно имеет пять параметров?

Существует пять параметров (int, ClassDoc, MemberDoc, String, boolean) и один тип возврата (String).

17 голосов
/ 01 июня 2010

Что означает "ILcom" или "Z"?

Это типы отображения для нативных типов. Вы можете найти обзор здесь .

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

Кроме того, подпись "L fully-qualified-class ;" будет означать класс, однозначно указанный этим именем; например, подпись "Ljava/lang/String;" относится к классу java.lang.String. Кроме того, префикс [ к подписи делает массив этого типа; например, [I означает тип массива int.


Что касается вашего следующего вопроса:

Почему в скобках есть четыре типа (ILcom / sun / javadoc / ClassDoc; Lcom / sun / javadoc / MemberDoc; Ljava / lang / String; Z) и один после скобок Ljava / lang / String; когда метод printDocLinkForMenu явно имеет пять параметров?

Потому что вы не запускаете код, который, по вашему мнению, выполняется. На самом деле работающий код пытается вызвать именно тот метод, который описан в сообщении об ошибке, с фактически пятью параметрами (I должен учитываться отдельно) и типом возврата String, но этот метод не ' t существует в пути к классам времени выполнения (в то время как он был доступен в пути к классам времени компиляции), следовательно, эта ошибка. Также см. NoSuchMethodError javadoc :

Брошенный, если приложение пытается вызвать указанный метод класса (статический или экземпляр), и у этого класса больше нет определения этого метода.

Обычно эта ошибка отлавливается компилятором; эта ошибка может возникнуть только во время выполнения, если определение класса несовместимо изменилось.

Итак, проверьте, действительно ли вы используете правильную версию кода, которую вы разместили в своем вопросе, и используете ли правильные зависимости в пути к классам времени выполнения и не имеете дублирующихся разных версий библиотек в пути к классам.

Обновление : исключение означает, что фактический код (неявно) пытается использовать метод следующим образом:

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

Поскольку он ожидает String результата, в то время как он объявлен void.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...