- Arawn's Dev Blog
- Outsider's Dev Story
- Toby's Epril
- Benelog
- NHN 개발자 블로그
- SK 플래닛 기술 블로그
- OLC CENTER
- 소프트웨어 경영/공학 블로그
- 모바일 컨버전스
- KOSR - Korea Operating System …
- 넥스트리 블로그
- 리버스코어 ReverseCore
- SLiPP
- 개발자를 위하여... (Nextree 임병인 수석)
- "트위터 부트스트랩: 디자이너도 놀라워할 매끈하고 직관…
- Learning English - The English…
- real-english.com
- 'DataScience/Deep Learning' 카테…
- Deep Learning Summer School, M…
- Deep Learning Courses
민서네집
java.util.ConcurrentModificationException is thrown when using Spring AOP 본문
java.util.ConcurrentModificationException is thrown when using Spring AOP
브라이언7 2013. 12. 11. 00:58java.util.ConcurrentModificationException is thrown when using Spring AOP
지금 프로젝트에서 Spring AOP 3.1.2.RELEASE 와 AspectJ 1.7.3 버전을 사용하고 있는데, Spring AOP를 걸었을 때
아주 가끔(아마도 여러 명의 유저가 동시접근하는 멀티 쓰레드 환경에서)
ConcurrentModificationException 이 발생한다.
- 정확히 말하면 aspectjtools.jar 가 1.7.3 버전이다.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=408721
위 웹페이지를 보니 AspectJ 1.7.1 버전에서 에러가 발생해서,
fixed. I put synchronized blocks around access to that collection.
1.7.4 버전에서 수정되었다고 나와 있다.
Error 재현해 보기
aspectjtools-1.7.3.jar 의 소스를 풀어서
그 중에서 ReferenceType.java 파일의 소스를 풀어서
src 디렉터리에 패키지 경로 그대로 갖다 놓는다.
/** * Look for a derivative type with the specified type parameters. This can avoid creating an * unnecessary new (duplicate) with the same information in it. This method also cleans up * any reference entries that have been null'd by a GC. * * @param typeParameters the type parameters to use when searching for the derivative type. * @return an existing derivative type or null if there isn't one */ public ReferenceType findDerivativeType(ResolvedType[] typeParameters) { synchronized (derivativeTypes) { List<WeakReference<ReferenceType>> forRemoval = new ArrayList<WeakReference<ReferenceType>>(); for (WeakReference<ReferenceType> derivativeTypeRef: derivativeTypes) { //////////////// TEST START ////////////////////// //java.util.Random random = new java.util.Random(); /*try { //Thread.sleep(random.nextInt(2000)); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }*/ //////////////// TEST END ////////////////////// ReferenceType derivativeType = derivativeTypeRef.get(); if (derivativeType==null) { forRemoval.add(derivativeTypeRef); } else { if (derivativeType.isRawType()) { continue; } if (equal(derivativeType.typeParameters,typeParameters)) { return derivativeType; // this escape route wont remove the empty refs } } } derivativeTypes.removeAll(forRemoval); } return null; }
TEST START 과 TEST END 사이를 주석 처리해야지 처음에 Tomcat 서버가 뜬다. 아니면 뜨는데 시간이 너무 오래 걸림.
Tomcat 서버가 시작하면 TEST 부분의 주석을 풀고, 여러 브라우저를 띄워서 반복적으로 request 를 날려본다.
그러면 java.util.ConcurrentModificationException 이 매우 자주 발생한다.
중간에 주석을 풀어야 하므로, 이클립스에서 Tomcat 서버를 debug 모드로 실행해야 한다.
그리고, Web Modules 항목에서 Auto Reload 옵션을 Disabled 로 해야지, 변경 사항이 발생해도 Tomcat 서버가 재시작하지 않고 바로 변경사항이 적용된다.
이번에는 aspectjtools-1.7.4.jar 로 jar 를 업그래이드 해서 /WEB-INF/lib 폴더에 넣고, aspectjtools-1.7.4-sources.jar 파일도 받아서 압축을 풀고, findDerivativeType() 메서드를 찾아서 위와 같이 테스트 코드를 넣고, 동일하게 테스트를 해 본다.
소스를 보면 synchronized (derivativeTypes) { ... } 로
for (WeakReference<ReferenceType> derivativeTypeRef: derivativeTypes) { ... } 를 감싼 것을 알 수 있다.
ConcurrentModificationException 은 더 이상 발생하지 않는다.
'Spring' 카테고리의 다른 글
Thymeleaf Layout Dialect 사용 (0) | 2014.07.14 |
---|---|
Spring Security + Java Config + Thymeleaf (0) | 2014.05.29 |
사용자 패스워드 암호화 (0) | 2013.11.29 |
[Spring] Excel 파일 다운로드 (Spring Excel View 구현) (0) | 2013.10.25 |
[spring security] Spring Security 를 이용하여 로그인여부 화면에 표시하기 (0) | 2013.10.25 |