[Java] java.lang.NoSuchMethodError 오류분석

Programming Language/Java

java.lang.NoSuchMethodError 오류메시지는 해당 메서드를 찾지 못할 때 발생된다.


본인의 경우는 라이브러리 중 하나의 메소드를 수정한 뒤 test 문제없음을 확인하고

수정된 라이브러리 운영(production)환경으로 반영했다.

그런데, 해당 라이브러리를 사용하는 타 class에서 java.lang.NoSuchMethodError 오류메시지 발생되었는데

Error 발생된 class file도 아무 수정없이 complie해서 운영(production)환경에 반영하니 문제가 사라졌다.



▶ 발생분석

* 현상 오류메시지 예시

java.lang.NoSuchMethodError: biz.com.dao.member.updateUser(Lbiz/com/vo/User;)V


- 해석

biz/com/vo/User 객체 1개를 파라미터로 받고 반환 값은 없는 biz.com.dao.member.updateUser라는 메서드를 찾지 못했다는 의미


* 소스코드 분석

Error가 발생된 (라이브러리를 사용하는)애플리케이션 코드 수정은 없었으며 라이브러리는 integer값을 반환 되도록 변경되었다.


- 라이브러리를 사용하는 애플리케이션 코드

// UserService.java

...

public void change(User user) {

...

member.update(user);

}


- 변경 전 후 라이브러리 소스코드

// Member.java - 변경 후

public int updateUser(User user) {

return member.update(user);

}


// Member.java - 변경 전

public void updateUser(User user) {

member.update(user);

}



▶ 발생예시 분석

라이브러리를 사용하는 애플리케이션 코드를 새로운 라이브러리로 다시 컴파일하지 않았기 때문이다.


라이브러리를 사용하는 애플리케이션 코드는 이전 라이브러리로 컴파일되었으므로, 

반환값이 없는 메서드를 호출하도록 class 파일에 기록되어 있지만, 

새로 변경된 라이브러리에서 반환값이 없는 메서드는 없어지고, integer값을 반환하는 메소드만 존재하기 때문이다.



▶ 결과

Java는 바이트코드를 이용해서 배포되며, 바이트코드는 자바 컴파일러에 의해 작성된다.

라이브러리가 변경 되었다면 이를 사용하는 어플리케이션 바이트코드도 다음과 같이 변경되어져야 하므로

어플리케이션 코드도 함께 반영되어져야한다.


biz.com.dao.member.updateUser(Lbiz/com/vo/User;)V ->  biz.com.dao.member.updateUser(Lbiz/com/vo/User;)I



▶ 참고문헌

http://d2.naver.com/helloworld/1230