민서네집

AspectJ 버그 해결 본문

Java

AspectJ 버그 해결

브라이언7 2015. 3. 25. 10:38

AspectJ 는 Spring Framework에서도 사용되는, 유명한 오픈 소스 라이브러리인데, 왜 여기에 버그가 있을까? 다른 프로젝트에서는 그럼 이 라이브러리를 어떻게 쓴단 말인가?

그런데 내가 했던 프로젝트에서는 약간 특이하게 Controller 에 point cut을 걸었다. 그게 문제였을까?

어쨌든...


2013년도 말 경에 m2matm 이라는 프로젝트를 한 적이 있었는데, AspectJ 라이브러리와 관련해서 가끔 서버 에러가 났다.


항상 나는 것도 아니고, 5초 주기로 몇 대의 컴퓨터에서 자동으로 ajax 호출하도록 밤새 켜 놓아야지 한두번 Server Error가 날까 말까한 버그가 있었다.


아마도 AspectJ 라이브러리에서 Class 정보를 Cache 하면서, 멀티 쓰레드 환경에서 동기화 관련된 이슈에서 발생한 버그로 판단된다.

그 해결 방법을 간단히 적어보았다.

- 이런 방법을 적용하면 오픈 소스 라이브러리에서 발생하는 버그를 해결할 수 있을 것이다.


1) 관련 라이브러리 jar 파일을 WEB-INF/lib 폴더에 갖다 놓아도, aspectjtools-1.7.4-sources.jar 의 압축을 풀어서 src 디렉터리에 갖다 놓으면 클래스 실행 우선순위가 src 폴더가 더 높아서 여기 것이 실행된다. 이렇게 하지 않고, lib 폴더에 있는 jar 파일을 없애면 연관된 소스 파일을 모두 갖다 놓아야 하고, 그렇지 않으면 컴파일 에러가 나서 상당히 일이 커진다.


2) Server Error Log의 Stack Trace를 보고, 에러가 나는 지점에 Eclipse에서 브레이크 포인트를 걸고, 에러가 나면 Call Stack을 보고, 실행 경로를 거슬러 올라가면서 이 에러가 보다 잘 발생하도록 소스를 수정한다. 

- Cache 때문에 에러가 잘 나지 않는 것을 방지하기 위함이다.

문제는 NullPointerException 이었으므로 멤버 변수에 null 을 대입하는 코드 뒤에 sleep() 함수로 대기시간을 줘서, 멀티 쓰레드 환경에서 실행할 때 보다 더 에러가 잘 나게 수정함.


3) 에러가 보다 더 빈번히 발생됨을 확인한다.


4) 소스에서 멤버 변수에 null 을 대입하는 메서드를 모두 찾아본다.

그 메서드에 synchronized 선언을 추가해보고, 다시 테스트 해 봐서 에러가 발생하지 않음을 확인한다.


< AspectJ 라이브러리에서 NullPointerException 방지 >


aspectjtools-1.7.4-sources.jar 의 압축을 풀어서 

src 디렉터리에

/m2matm/src/java/org/aspectj/weaver/TypeVariable.java 파일을 갖다 놓고,

몇몇 메서드에 synchronized 선언을 추가해서 해결함.


< AspectJ 라이브러리에서 java.util.ConcurrentModificationException 방지 >


AspectJ 1.7.3 버전에서 가끔 발생해서 1.7.4 버전으로 업그레이드 함.

[참고]

https://bugs.eclipse.org/bugs/show_bug.cgi?id=408721

http://forum.spring.io/forum/spring-projects/aop/122321-java-util-concurrentmodificationexception-is-thrown-when-using-spring-aop


AspectJ 라이브러리의 버그를 해결하기 위해 프로젝트의 src 폴더에 추가했던 소스 파일을 첨부합니다.
< 관련 posting >

java.util.ConcurrentModificationException is thrown when using Spring AOP

http://bryan7.tistory.com/196


Comments