요즘 많이 사용되는 AOP Logging. 현재 작업 중인 프로젝트에서도 사용중인데, 최근 기능을 추가하면서 문제가 발생했다.


● 문제발생

현재 사용중인 프로젝트에서도 AspectLogging 기법을 사용했다. 그런데, class cast를 하는 과정에서 지속적으로

Exception in thread "main" java.lang.ClassCastException: $Proxy11 cannot be cast to classA

라고 하는 문제가 발생하면서 로깅클래스에서 동작이 멈추는 증상이 나타났다. 물론…
AOP측에서 이에 대한 예외처리를 제대로 했으면 별문제가 없었겠지만,


● 문제요인

문제가 발생하는 부분을 유심히 살펴봤다. 스프링의 ReloadableResourceBundleMessageSource를 확장extends하여 간단한 메소드를 추가한 ResourceBundleMessageSource클래스로 class casting을 하는 부분에서 문제가 발생하고 있었다.


● 힌트

이 문제가 왜 생겼는지 인터넷 검색에 들어간다.

그러다가 발견한 힌트!

classcastexception-proxy-cannot-be-cast-to-using-aop - Stackoverflow

제일 마지막 부분에

a good article about proxy creation in Spring

이 글을 보고 깨달음을 얻었다.


● 해결책

  1. BundleMessageSource 라고 하는 인터페이스를 만들고, ResourceBundleMessageSource 클래스에서 implements 로 구현한다고 선언.
  2. ResourceBundleMessageSource 를 class casting 하는 부분을 BundleMessageSource 로 변경하였다.
  3. OK~!

● 정리

… proxy에서 효과적인 캐스팅 방식은, ‘클래스 캐스팅을 사용할 경우 인터페이스를 선언하여 구현하고 인터페이스로 캐스팅하는 것’ 이다.

우분투의 언어설정을 변경하면, 그에 따라 우분투의 기본 폴더가 변경되는 특징을 가진다. 일본어로 테스트할 것이 있어서 시스템 환경을 일본어로 변경했다가 한국어로 변경했지만, 기본 폴더들이 일본어로 되어 있어, 이를 수정할 방법을 검색하다가 발견했다.

순서

  1. user-dirs.dirs 삭제
    $ rm ~/.config/user-dirs.dirs
    
  2. xdg-user-dirs-update 실행
    $ xdg-user-dirs-update
    
  3. ~/.config/user-dirs.dirs 수정
    # This file is written by xdg-user-dirs-update
    # If you want to change or add directories, just edit the line you're
    # interested in. All local changes will be retained on the next run
    # Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped
    # homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an
    # absolute path. No other format is supported.
    # 
    XDG_DESKTOP_DIR="$HOME/desktop"
    XDG_DOWNLOAD_DIR="$HOME/downloads"
    XDG_TEMPLATES_DIR="$HOME/template"
    XDG_PUBLICSHARE_DIR="$HOME/share"
    XDG_DOCUMENTS_DIR="$HOME/documents"
    XDG_MUSIC_DIR="$HOME/music"
    XDG_PICTURES_DIR="$HOME/picture"
    XDG_VIDEOS_DIR="$HOME/video"


intellij 12.1.5 버전에서 컴파일과 관련한 문제로 Lombok이 제대로 동작하지 않는 기현상을 보였다. 이에 jetbrain에서는 급히 컴파일 문제를 해결한 12.1.6 으로 업그레이드버전을 제공했다. 그런데 이녀석으로 업그레이드를 한 이후에 계속 컴파일 중에 오류가 발생한다.


로그에서 'ajc: the method ...' 라고 하는 메시지를 출력하며, Lombok annotation을 사용한 클래스가 정상적으로 컴파일 되지 않았다.

Lombok의 annotation이 컴파일시에 제대로 동작하지 않아서 생기는 문제가 아닐까 하고 Lombok plugin 재설치를 몇번해보고 설정에서 Compiler - Annotation Processors 에서 'Enable annotation processing'을 체크했다가 해제했다가를 반복했지만 증상은 똑같았다.

인터넷 검색을 해도 딱히 답이 나오지 않던 상황...

불현듯 '컴파일러!' 가 떠오르면서 'Compiler - Java Compiler' 를 찾아 들어갔다. 

'Use Compiler' 에 보니까 내가 모르는 Ajc가 선택되어 있다.

컴파일러를 'javac' 로 변경하고 나니 정상적으로 컴파일되고 배포까지 완료되었다...!! 두둥!

로그 속에 답이 있다는 진리를 새삼 깨닫다.


 

 정리

 

Intellij 12.1.6 업그레이드 후에도 Lombok 이 정상동작 하지 않을 시,

  • 이동: [Settings...] - [Compiler] - [Java Compiler]
  • 변경: 'User Compiler' - javac 로 변경



... Default는 javac라면서? 난... Compiler 변경한 적 없다!!

* 내 패키지 구조
  * package.domain.system
  * package.domain.document
* 변경된 패키지 구조
  * package.domain.entity

회사에서 다른 개발자들이 쓰는 패키지 구조가 맘에 들지 않는다.
패키지의 구조를 통해서 기능을 분리할 수가 있는데...
그건 하지 않고 하나의 패키지에 모두 몰아넣는 방식이
왜 이렇게 거북스러운거냐.

내가 만든 구조가 싫다면,
왜 싫은지 이유를 설명해주고 바꾸면 좋겠는데...
내가 만든 구조를 어느새 자신의 구조로 만들어놓을 뿐 설명이 없다.

단지 패키지 경로가 길어지기 때문인가?

+ Recent posts