나는군요 NoSuchMethodError
내 Java 프로그램을 실행할 때 오류가 발생했습니다. 무엇이 잘못되었으며 어떻게 해결합니까?
나는군요 NoSuchMethodError
내 Java 프로그램을 실행할 때 오류가 발생했습니다. 무엇이 잘못되었으며 어떻게 해결합니까?
답변:
더 이상의 정보가 없으면 문제를 정확히 파악하기는 어렵지만 근본 원인은 메서드를 실행할 때 사용하는 것과 다른 버전의 메서드에 대해 클래스를 컴파일했을 가능성이 높습니다.
스택 추적보기 ... 라이브러리의 객체에서 메소드를 호출 할 때 예외가 발생하면 컴파일 및 실행시 별도의 버전의 라이브러리를 사용하는 것 같습니다. 두 버전 모두 올바른 버전인지 확인하십시오.
클래스가 인스턴스화 된 객체의 메소드 호출 할 때 예외가 나타나면 당신이 만든을 한 후 빌드 프로세스에 결함이있을 것으로 보인다. 컴파일 할 때 실제로 실행중인 클래스 파일이 업데이트되었는지 확인하십시오.
Caused by
추적 추적 의 마지막 섹션을 확인 하여 범인 클래스 / jar을 찾습니다
나는 당신의 문제를 겪고 있었고, 이것이 내가 고친 방법입니다. 다음 단계는 라이브러리를 추가하는 효과적인 방법입니다. 처음 두 단계를 올바르게 수행했지만 파일 시스템에서 ".jar"파일을 이클립스 프로젝트의 "lib"폴더로 직접 드래그하여 마지막 단계를 수행하지 않았습니다. 또한 빌드 경로와 "lib"폴더에서 이전 버전의 라이브러리를 제거해야했습니다.
리플렉션의 경우 NoSuchMethodException
, 비 반사 코드의 경우을 얻습니다 NoSuchMethodError
. 나는 서로 대면 할 때 매우 다른 곳을 찾는 경향이 있습니다.
JVM 매개 변수를 변경할 수있는 액세스 권한이있는 경우 자세한 출력을 추가하면 어떤 JAR 파일에서 어떤 클래스가로드되는지 확인할 수 있습니다.
java -verbose:class <other args>
프로그램이 실행될 때 JVM은 다음과 같은 표준 출력 정보로 덤프해야합니다.
...
[파일에서로드 된 junit.framework.Assert : / C : /Program%20Files/junit3.8.2/junit.jar]
...
이것은 일반적으로 Apache Ant 와 같은 빌드 시스템을 사용할 때 발생합니다. java 파일이 클래스 파일보다 최신 일 때 java 파일 만 컴파일하는 합니다. 메소드 서명이 변경되고 클래스가 이전 버전을 사용하는 경우 올바르게 컴파일되지 않을 수 있습니다. 일반적인 수정은 전체 재 구축 (보통 "ant clean", "ant")을 수행하는 것입니다.
때로는 한 버전의 라이브러리에 대해 컴파일 할 때 다른 버전에 대해서는 실행될 때이 문제가 발생할 수 있습니다.
Maven 또는 다른 프레임 워크를 사용하는 경우이 오류가 거의 무작위로 발생하면 다음과 같이 새로 설치하십시오.
clean install
이것은 객체를 작성했고 객체에 메소드가 있음을 알고있는 경우 특히 효과적입니다. 나를 위해 일했다.
리플렉션을 사용한 결과 일 수도 있습니다. 클래스에 반영하는 코드가 있고 이름으로 메소드를 추출하는 경우 (예 : with Class.getDeclaredMethod("someMethodName", .....)
) 리팩터링 중과 같이 메소드 이름이 변경 될 때마다 매개 변수를 리플렉션 메소드로 업데이트해야합니다. 새로운 메소드 서명, 또는 getDeclaredMethod
호출은NoSuchMethodException
.
이것이 원인 인 경우 스택 추적은 리플렉션 메소드가 호출 된 지점을 표시해야하며 실제 메소드 서명과 일치하도록 매개 변수를 업데이트하기 만하면됩니다.
내 경험상 이것은 개인 메소드 / 필드를 단위로 테스트하고 TestUtilities
클래스를 사용하여 테스트 확인을 위해 필드를 추출 할 때 가끔 발생 합니다. 일반적으로 단위 테스트를 염두에두고 설계되지 않은 레거시 코드를 사용합니다.
이러한 문제점은 동일한 두 클래스에서 동일한 오브젝트를 사용하여 발생합니다. 사용 된 객체에 새 메소드가 포함되지 않은 경우 새 객체 클래스에 포함 된 새 메소드가 추가되었습니다.
전의:
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$
이러한 문제점은 수반되는 02 유사한 클래스 (src에서 1, jar 파일에서 1은 gateway.jar)로 인해 발생합니다.
원래 질문에 대답합니다. 여기 에 Java 문서에 따르면 :
"NoSuchMethodError"어플리케이션이 클래스의 지정된 메소드 (정적 또는 인스턴스)를 호출하려고 시도하고 해당 클래스에 더 이상 해당 메소드의 정의가없는 경우 발생합니다.
일반적으로이 오류는 컴파일러에서 발생합니다. 이 오류는 클래스 정의가 호환되지 않는 경우에만 런타임시 발생할 수 있습니다.
Junit 테스트 파일의 이름을 바꾸어 Eclipse 에서이 문제를 해결했습니다.
Eclipse 작업 공간에는 App 프로젝트와 Test 프로젝트가 있습니다.
테스트 프로젝트는 빌드 경로에서 App 프로젝트를 필수 프로젝트로 사용합니다.
NoSuchMethodError가 발생하기 시작했습니다.
그런 다음 테스트 프로젝트의 클래스 이름이 앱 프로젝트의 클래스 이름과 동일하다는 것을 알았습니다.
App/
src/
com.example/
Projection.java
Test/
src/
com.example/
Projection.java
테스트 이름을 "ProjectionTest.java"라는 올바른 이름으로 바꾼 후 예외가 사라졌습니다.
나는 같은 오류가 있었다 :
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)
이를 해결하기 위해 먼저 모듈 종속성 다이어그램 ( click in your POM the combination -> Ctrl+Alt+Shift+U
또는 right click in your POM -> Maven -> Show dependencies
)을 확인하여 라이브러리 간의 충돌이 정확히 어디에 있는지 이해했습니다 (Intelij IDEA). 필자의 경우에는 다른 버전의 Jackson 종속성이있었습니다.
1) 따라서 프로젝트의 POM에 명시 적으로 가장 높은 버전-이 두 가지 중 2.8.7을 추가했습니다.
속성에서 :
<jackson.version>2.8.7</jackson.version>
그리고 의존성 :
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
2) 또한 의존성 제외를 사용하여 해결할 수 있습니다 .
예에서 아래와 같은 원리로 :
<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>
원하지 않는 버전의 종속성은 프로젝트에서 제외됩니다.
내 경우에는 내가 멀티 모듈 프로젝트를했고 같은 시나리오였다 com.xyz.TestClass
모듈에 있었다 A
뿐만 아니라 모듈 B
과 모듈은 A
모듈에 의존했다 B
. 따라서 어셈블리 항아리를 만드는 동안 호출 된 메서드가 없으면 클래스의 한 버전 만 유지되었다고 생각합니다.NoSuchMethodError
합니다. 런타임 예외가 발생했지만 컴파일은 괜찮습니다.
비슷한 문제가 발생했습니다.
Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I
마지막으로 근본 원인이 변수의 데이터 유형을 변경하고 있음을 확인했습니다.
Employee.java
-> 변수 (포함 EmpId
) 데이터 형식이 변경되었습니다 int
에 String
.ReportGeneration.java
-> getter를 사용하여 값을 검색합니다 getEmpId()
.수정 된 클래스 만 포함하여 항아리를 다시 묶어야합니다. 변경 사항이 없으므로 in Jar 파일 ReportGeneration.java
만 포함했습니다 Employee.class
. ReportGeneration.class
문제를 해결하기 위해 항아리에 파일 을 포함시켜야했습니다 .
나는 같은 문제가 있었다. 클래스에 모호성이있는 경우에도 발생합니다. 내 프로그램은 동일한 위치 / 클래스 경로에있는 두 개의 JAR 파일에 존재하는 메소드를 호출하려고했습니다. 하나의 JAR 파일 만 삭제하거나 하나의 JAR 파일 만 사용되도록 코드를 실행하십시오. 동일한 클래스를 포함하는 동일한 JAR 또는 다른 버전의 동일한 JAR을 사용하지 않는지 확인하십시오.
DISP_E_EXCEPTION [단계] [] [Z-JAVA-105 Java 예외 java.lang.NoSuchMethodError (com.example.yourmethod)]
대부분의 경우 java.lang.NoSuchMethodError는 컴파일러로 잡히지 만 때로는 런타임에 발생할 수 있습니다. 런타임에이 오류가 발생하면 클래스 구조가 변경되어 호환되지 않는 유일한 이유 일 수 있습니다.
가장 좋은 설명 : https://www.journaldev.com/14538/java-lang-nosuchmethoderror
이 오류도 발생했습니다.
내 문제는 메소드의 서명을 변경했다는 것입니다.
void invest(Currency money){...}
으로
void invest(Euro money){...}
이 메소드는 다음과 유사한 컨텍스트에서 호출되었습니다.
public static void main(String args[]) {
Bank myBank = new Bank();
Euro capital = new Euro();
myBank.invest(capital);
}
자본은 통화뿐만 아니라 유로이기 때문에 컴파일러는 경고 / 오류와 관련하여 침묵했습니다.
문제는 메소드가 정의 된 클래스 인 Bank 만 컴파일했지만 main () 메소드를 포함하는 메소드가 호출되는 클래스는 컴파일하지 않았기 때문에 나타났습니다.
이 문제는 프로젝트를 수동으로 다시 빌드하거나 수정 된 클래스를 컴파일하는 대신 빌드 작업이 자동으로 트리거되므로 자주 발생하는 문제는 아닙니다.
내 유스 케이스는 핫픽스로 사용할 .jar 파일을 생성했지만 App.class가 포함되지 않았기 때문에 수정되지 않았기 때문입니다. 초기 인수의 기본 클래스 여물 상속을 유지하면서 포함시키지 않는 것이 나에게 의미가있었습니다.
문제는 클래스를 컴파일 할 때 결과 바이트 코드가 static 인 것입니다. 즉, 하드 참조입니다 입니다.
javap 도구로 생성 된 원래 디스 어셈블 된 바이트 코드는 다음과 같습니다.
#7 = Methodref #2.#22 // Bank.invest:(LCurrency;)V
ClassLoader가 새로 컴파일 된 Bank.class를로드 한 후에는 그러한 메소드를 찾지 못하며, 제거되어 변경되지 않은 것처럼 표시되어 이름 지정된 오류가 발생합니다.
도움이 되었기를 바랍니다.
Intelij를 사용하는 Gradle 프로젝트와 비슷한 문제가있었습니다. .gradle (아래 스크린 샷 참조) 패키지를 삭제하고 프로젝트를 다시 작성하여 해결했습니다. .gradle 패키지