NoSuchMethodError를 어떻게 해결합니까?


178

나는군요 NoSuchMethodError내 Java 프로그램을 실행할 때 오류가 발생했습니다. 무엇이 잘못되었으며 어떻게 해결합니까?


11
Netbeans의 경우 : 프로젝트 탭에서 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 "청소 및 빌드"를 사용하십시오. 나를 위해 해결했습니다.
Heinzlmaen

3
또한 Intellij Idea에서 재 구축이 때때로 문제를 해결합니다.
Hawk

1
이 글은이 문제에 매우 도움이됩니다 reflectoring.io/nosuchmethod
Michael Smith

답변:


228

더 이상의 정보가 없으면 문제를 정확히 파악하기는 어렵지만 근본 원인은 메서드를 실행할 때 사용하는 것과 다른 버전의 메서드에 대해 클래스를 컴파일했을 가능성이 높습니다.

스택 추적보기 ... 라이브러리의 객체에서 메소드를 호출 할 때 예외가 발생하면 컴파일 및 실행시 별도의 버전의 라이브러리를 사용하는 것 같습니다. 두 버전 모두 올바른 버전인지 확인하십시오.

클래스가 인스턴스화 된 객체의 메소드 호출 할 때 예외가 나타나면 당신이 만든을 한 후 빌드 프로세스에 결함이있을 것으로 보인다. 컴파일 할 때 실제로 실행중인 클래스 파일이 업데이트되었는지 확인하십시오.


3
우리는 최근에 이들 중 하나의 원인을 발견했으며 Java 서버가 종료되기 전에 빌드 프로세스가 클래스 파일을 제 위치에 놓는 것으로 나타났습니다 .Java 서버가 일부 클래스를로드하지 않았기 때문에이를 누르십시오. 일부는 새로운 코드를 얻었고 새 코드는 이전 클래스에는 없었던 메소드를 참조했기 때문에 ...
bingo

"스택 추적 추적 ..."-글쎄, 나는 거의 항상 가서 Caused by추적 추적 의 마지막 섹션을 확인 하여 범인 클래스 / jar을 찾습니다
KrishPrabakar

108

나는 당신의 문제를 겪고 있었고, 이것이 내가 고친 방법입니다. 다음 단계는 라이브러리를 추가하는 효과적인 방법입니다. 처음 두 단계를 올바르게 수행했지만 파일 시스템에서 ".jar"파일을 이클립스 프로젝트의 "lib"폴더로 직접 드래그하여 마지막 단계를 수행하지 않았습니다. 또한 빌드 경로와 "lib"폴더에서 이전 버전의 라이브러리를 제거해야했습니다.

1 단계-.jar을 추가하여 경로 작성

여기에 이미지 설명을 입력하십시오

2 단계-소스 및 javadoc 연결 (선택 사항)

여기에 이미지 설명을 입력하십시오

3 단계-실제로 .jar 파일을 "lib"폴더로 드래그 (선택 사항 아님)

여기에 이미지 설명을 입력하십시오


75
+1 "모두가 사용 방법을 알고 있고 질문을 줄이려하지 않으면 모든 사용자가이를 알고 있어야합니다."
Vikram

73

리플렉션의 경우 NoSuchMethodException, 비 반사 코드의 경우을 얻습니다 NoSuchMethodError. 나는 서로 대면 할 때 매우 다른 곳을 찾는 경향이 있습니다.


다시 말해, 리플렉션을 사용하여 클래스에서 메소드를 가져오고 메소드를 찾을 수 없으면 NoSuchMethodException이 발생한다는 것입니다. 그러나 일부 라이브러리에 대해 코드를 컴파일 할 때 시나리오에 있고 서버에 다른 라이브러리가 있으면 (아마 더 오래된 것일 수도 있음) NoSuchMethodError가 발생합니다. 틀 렸으면 말해줘.
빅터

맞습니다, @Victor
KrishPrabakar

51

JVM 매개 변수를 변경할 수있는 액세스 권한이있는 경우 자세한 출력을 추가하면 어떤 JAR 파일에서 어떤 클래스가로드되는지 확인할 수 있습니다.

java -verbose:class <other args>

프로그램이 실행될 때 JVM은 다음과 같은 표준 출력 정보로 덤프해야합니다.

...

[파일에서로드 된 junit.framework.Assert : / C : /Program%20Files/junit3.8.2/junit.jar]

...


3
+1 훌륭합니다! 이 방법을 사용하여 불쾌한 작은 문제를 해결했습니다. 감사합니다. 이것은 클래스가 클래스 경로에 어떻게 든 몰래 들어 갔는지 발견하는 훌륭한 방법입니다.
Duncan Jones

1
+1 내 하루를 구했다! 그것은 같은 이름을 가진 오래된 클래스를 소스에 포함시킨 하나의 라이브러리였습니다.
Andrii Nemchenko

12

이것은 일반적으로 Apache Ant 와 같은 빌드 시스템을 사용할 때 발생합니다. java 파일이 클래스 파일보다 최신 일 때 java 파일 만 컴파일하는 합니다. 메소드 서명이 변경되고 클래스가 이전 버전을 사용하는 경우 올바르게 컴파일되지 않을 수 있습니다. 일반적인 수정은 전체 재 구축 (보통 "ant clean", "ant")을 수행하는 것입니다.

때로는 한 버전의 라이브러리에 대해 컴파일 할 때 다른 버전에 대해서는 실행될 때이 문제가 발생할 수 있습니다.


1
실제로 이것은 모든 답변에서 볼 수 있듯이 Maven, NetBeans 및 Apache Ant와 같은 Java 개발 프레임 워크를 사용하는 Java 프로그래머에게 발생하는 문제와 비슷합니다.
HoldOffHunger

8

Maven 또는 다른 프레임 워크를 사용하는 경우이 오류가 거의 무작위로 발생하면 다음과 같이 새로 설치하십시오.

clean install

이것은 객체를 작성했고 객체에 메소드가 있음을 알고있는 경우 특히 효과적입니다. 나를 위해 일했다.


Gradle 빌드의 경우에도 마찬가지입니다.
Jonathan Landrum

4

리플렉션을 사용한 결과 일 수도 있습니다. 클래스에 반영하는 코드가 있고 이름으로 메소드를 추출하는 경우 (예 : with Class.getDeclaredMethod("someMethodName", .....)) 리팩터링 중과 같이 메소드 이름이 변경 될 때마다 매개 변수를 리플렉션 메소드로 업데이트해야합니다. 새로운 메소드 서명, 또는 getDeclaredMethod호출은NoSuchMethodException .

이것이 원인 인 경우 스택 추적은 리플렉션 메소드가 호출 된 지점을 표시해야하며 실제 메소드 서명과 일치하도록 매개 변수를 업데이트하기 만하면됩니다.

내 경험상 이것은 개인 메소드 / 필드를 단위로 테스트하고 TestUtilities클래스를 사용하여 테스트 확인을 위해 필드를 추출 할 때 가끔 발생 합니다. 일반적으로 단위 테스트를 염두에두고 설계되지 않은 레거시 코드를 사용합니다.


3

webapp를 작성하는 경우 컨테이너의 전역 라이브러리 디렉토리와 앱에 충돌하는 jar 버전의 jar이 없는지 확인하십시오. 클래스 로더에서 어떤 jar이 사용되고 있는지 반드시 알 필요는 없습니다.

예 :

  • 바람둥이 / 공통 / lib
  • mywebapp / WEB-INF / lib

2

이러한 문제점은 동일한 두 클래스에서 동일한 오브젝트를 사용하여 발생합니다. 사용 된 객체에 새 메소드가 포함되지 않은 경우 새 객체 클래스에 포함 된 새 메소드가 추가되었습니다.

전의:

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)로 인해 발생합니다.


2

이는 해당 방법이 클래스에 존재하지 않음을 의미합니다.

  1. jar를 사용하는 경우 디 컴파일하고 각 jar 버전에 적절한 클래스가 있는지 확인하십시오.
  2. 소스에서 적절한 클래스를 컴파일했는지 확인하십시오.

2

나를 위해 함수의 인수 유형을 Object a에서 String a로 변경했기 때문에 발생했습니다. 깨끗하게 해결하고 다시 빌드 할 수 있습니다.


2

Eclipse를 다시 시작하고 applcation을 실행 하여이 오류를 해결했습니다. 내 이유는 프로젝트 또는 Eclipse를 닫지 않고 소스 파일을 교체하기 때문일 수 있습니다. 내가 사용하는 다른 버전의 클래스가 발생했습니다.


2

이 방법으로 시도하십시오 : 프로젝트 디렉토리 아래의 모든 .class 파일을 제거하십시오 (물론 모든 하위 디렉토리). 재 구축.

때로는 mvn clean(maven을 사용하는 경우)는 수동으로 만든 .class 파일을 정리하지 않습니다 javac. 그리고 그 오래된 파일에는 오래된 서명이 포함되어 있습니다 NoSuchMethodError.


2

기존 답변에 추가하기 만하면됩니다. 나는 일식에서 바람둥이와 함께이 문제에 직면했다. 나는 한 수업을 바꾸고 다음 단계를 밟았습니다.

  1. 간결하게 프로젝트를 정리하고 건설

  2. mvn 새로 설치

  3. 바람둥이 다시 시작

여전히 나는 같은 오류에 직면했다. 그런 다음 tomcat을 청소하고 tomcat 작업 디렉토리를 청소 하고 서버를 다시 시작 했는데 문제가 사라졌습니다. 이것이 누군가를 돕기를 바랍니다.


1

원래 질문에 대답합니다. 여기 에 Java 문서에 따르면 :

"NoSuchMethodError"어플리케이션이 클래스의 지정된 메소드 (정적 또는 인스턴스)를 호출하려고 시도하고 해당 클래스에 더 이상 해당 메소드의 정의가없는 경우 발생합니다.

일반적으로이 오류는 컴파일러에서 발생합니다. 이 오류는 클래스 정의가 호환되지 않는 경우에만 런타임시 발생할 수 있습니다.

  1. 런타임에 발생하면 메소드를 포함하는 클래스가 클래스 경로에 있는지 확인하십시오.
  2. JAR의 새 버전을 추가했는지 확인하고 메소드가 호환되는지 확인하십시오.

1

Junit 테스트 파일의 이름을 바꾸어 Eclipse 에서이 문제를 해결했습니다.
Eclipse 작업 공간에는 App 프로젝트와 Test 프로젝트가 있습니다.
테스트 프로젝트는 빌드 경로에서 App 프로젝트를 필수 프로젝트로 사용합니다.

NoSuchMethodError가 발생하기 시작했습니다.
그런 다음 테스트 프로젝트의 클래스 이름이 앱 프로젝트의 클래스 이름과 동일하다는 것을 알았습니다.

App/  
  src/
     com.example/  
       Projection.java
Test/  
  src/
     com.example/
       Projection.java

테스트 이름을 "ProjectionTest.java"라는 올바른 이름으로 바꾼 후 예외가 사라졌습니다.


나는 비슷한 문제가 있었다. 동일한 정식 이름을 가진 종속성 클래스가 있습니다. 이름을 바꾼 후 예외가 사라졌습니다.
moralejaSinCuentoNiProverbio

1

나는 같은 오류가 있었다 :

  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>

원하지 않는 버전의 종속성은 프로젝트에서 제외됩니다.


1

내 경우에는 내가 멀티 모듈 프로젝트를했고 같은 시나리오였다 com.xyz.TestClass모듈에 있었다 A뿐만 아니라 모듈 B과 모듈은 A모듈에 의존했다 B. 따라서 어셈블리 항아리를 만드는 동안 호출 된 메서드가 없으면 클래스의 한 버전 만 유지되었다고 생각합니다.NoSuchMethodError 합니다. 런타임 예외가 발생했지만 컴파일은 괜찮습니다.

관련 : https://reflectoring.io/nosuchmethod/


0

내 응용 프로그램에서 메소드 서명을 변경할 때 비슷한 문제가 발생했습니다. 프로젝트를 정리하고 다시 빌드하면 "NoSuchMethodError"가 해결되었습니다.


0

위의 답변은 매우 잘 설명합니다. 한 가지만 추가하십시오 eclipse를 사용하여 사용하는 경우 ctrl + shift + T를 사용하고 클래스의 패키지 구조를 입력하십시오 (예 : gateway.smpp.PDUEventListener), 존재하는 모든 jar / 프로젝트를 찾을 수 있습니다 . 클래스 경로에서 불필요한 항아리를 제거하거나 클래스 경로에 위의 내용을 추가하십시오. 이제 올바른 것을 선택합니다.


0

비슷한 문제가 발생했습니다.

Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I

마지막으로 근본 원인이 변수의 데이터 유형을 변경하고 있음을 확인했습니다.

  1. Employee.java-> 변수 (포함 EmpId) 데이터 형식이 변경되었습니다 intString.
  2. ReportGeneration.java-> getter를 사용하여 값을 검색합니다 getEmpId().

수정 된 클래스 만 포함하여 항아리를 다시 묶어야합니다. 변경 사항이 없으므로 in Jar 파일 ReportGeneration.java만 포함했습니다 Employee.class. ReportGeneration.class문제를 해결하기 위해 항아리에 파일 을 포함시켜야했습니다 .


0

나는 같은 문제가 있었다. 클래스에 모호성이있는 경우에도 발생합니다. 내 프로그램은 동일한 위치 / 클래스 경로에있는 두 개의 JAR 파일에 존재하는 메소드를 호출하려고했습니다. 하나의 JAR 파일 만 삭제하거나 하나의 JAR 파일 만 사용되도록 코드를 실행하십시오. 동일한 클래스를 포함하는 동일한 JAR 또는 다른 버전의 동일한 JAR을 사용하지 않는지 확인하십시오.

DISP_E_EXCEPTION [단계] [] [Z-JAVA-105 Java 예외 java.lang.NoSuchMethodError (com.example.yourmethod)]



0

이 오류도 발생했습니다.

내 문제는 메소드의 서명을 변경했다는 것입니다.

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를로드 한 후에는 그러한 메소드를 찾지 못하며, 제거되어 변경되지 않은 것처럼 표시되어 이름 지정된 오류가 발생합니다.

도움이 되었기를 바랍니다.


0

필자의 경우 문제는 빌드 경로에 동일한 라이브러리의 두 가지 버전이 있다는 것입니다. 이전 버전의 라이브러리에는 기능이 없었으며 최신 버전에는 기능이 없었습니다.


0

Intelij를 사용하는 Gradle 프로젝트와 비슷한 문제가있었습니다. .gradle (아래 스크린 샷 참조) 패키지를 삭제하고 프로젝트를 다시 작성하여 해결했습니다. .gradle 패키지


0

NoSuchMethodError :이 문제를 해결하는 데 몇 시간을 보냈습니다. 결국 패키지 이름을 바꾸고 정리하고 빌드하여 문제를 해결했습니다 ... 클래스가 작동하지 않으면 먼저 정리 빌드를 시도하십시오. 클래스 이름이나 패키지 이름을 바꾸고 빌드를 정리하십시오. . 고정되어야합니다. 행운을 빕니다.


-2

파일 이름이 기본 메소드를 포함하는 클래스 이름과 다른 경우이 오류가 발생할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.