어느날 업무를 보다가
Xstream xml로 처리되는 API 중, 데이터를 파싱하는 과정에서 ClassCastException이 발생하였다.
분명 동일한 DTO class와 같은 데이터 형태로 request를 받았는데
ex) DTO(data="abc", data2="cba")
익셉션이 발생되었다. Xstream class lib을 직접 확인 해 보니, Reflection으로 동작하는 것을 확인 할 수 있었다. Reflection의 경우 간단하게 말하자면, runtime에서 동적으로 특정 Class정보를 추출한다.
이렇게 쓰라고 만든 것 처럼 동적 바인딩을 제공 하는데,
왜 해당 오류가 발생한 DTO는 바인딩 되지 못했을까 생각 해 보았다.
일단 정리하면, runtime에 동적으로 클래스를 로딩 한다는건 JVM이 모든 클래스를 로딩하지 않는다는 것을 알 수 있었고,
여러 자료를 찾던 중, runtime중 JVM의 method 영역에 동적으로 Java class를 읽는 행위를 도와주는 녀석이 classLoader였다는 것을 알았다.
아래 코드를 추가하여 처리하니 classCastException이 발생하지 않고, 정상 처리 되었다.
xStream.setClassLoader(Thread.currentThread().getContextClassLoader());
XStream의 classLoader를 현재 사용되고 있는 thread에서 그 classloader를 셋팅 해 주었습니다.
그렇다면 이게 왜 이상없이 정상 처리 되었을까?
참고한 자료에 따르면
Java의 ClassLoader는 Java Virtual Machine 의 application에서 필요할 때마다 class를 동적으로 로드하기 위해
Java Runtime Environment에 의해 호출되는데, ClassLoader는 Java Runtime Environment의 일부이므로
Java Virtual Machine은 기본 파일 및 파일 시스템에 대해 전혀 알지 못한다는 것을 알 수 있었다.
즉 결론으로 말하자면, "Reflection할 class가 어떤 classLoader로 읽었는지 알지 못 한다" 이다.
그 것을 명시한게 위 코드와 같다.( 여기서 읽어라 ! )
(코드 삽입 전 상위 클래스에서 로드 되었는지, 또는 어떤 클래스 로더로 로드 되었는 지 등등)
감사합니다.
(참고 링크)
https://www.edureka.co/blog/classloader-in-java/
ClassLoader in Java | Types of ClassLoader in Java | Edureka
This article is a comprehensive guide on how does the ClassLoader work in Java. It discusses the types, principles and methods of ClassLoader in Java.
www.edureka.co