개발 관련 부가 지식/자바, 스프링

Cannot find symbol 해결해야 할 때

Developer-Choi 2023. 4. 19. 12:45
728x90
728x90

// 문제 상황 ❗

자바8 스프링 프로젝트 마이그레이션 중 문제가 생겼다.

(스프링 3, 이클립스 -> 스프링5, 인텔리제이 + gradle)

 

build 시에  sun.security.~~~ 패키지 관련하여 cannot find symbol이 발생한 것이 그 문제이다.

// 문제점 파악  👀

그럼 이클립스에서는 build가 왜 문제가 없었을까?

마이그레이션 전,후의 차이는 다음과 같다.

 

이클립스는 Java 용 Eclipse Compiler (ECJ) 라고 자체 컴파일러를 사용한다고 한다.

인텔리제이는 프로젝트에 적용한 JDK가 갖고있는 javac 컴파일러를 통해 컴파일을 한다고 한다.

 

내가 적용한 JDK8 javac 컴파일러는 해당 sun 패키지를 지원하지 않아서 빌드가 되지 않았던 것이다.

 

// 해결 방안 

1. 다른라이브러리로 재구현

구글링을 해보니 자바8에는 해당 패키지를 지원하지 않는다고 하여 다른 라이브러리로 구현하라는 글들이 많았다.

다른 라이브러리를 통해 해당 로직을 재 구현해 보았지만,

회사 자체적으로 쓰고있던 자바스크립트 상에서 다른 것으로 인식하여, 기존 로직을 무조건 써야되는 상황이였다.

 

2. symbol.file 무시

javac 컴파일러는 클래스 파일을 생성하기 위해서,

해당 클래스가 참조하는 다른 클래스와 인터페이스의 정보를 필요로 하는데,

이 정보는 symbol file(.sym 파일)에 저장되며, javac은 symbol file을 이용해 컴파일을 수행한다고 한다.

 

문제는 symbol file에 있는 정보들은 해당 자바 버전이 지원하는 패키지들이 들어있는 것으로, 내가 필요로 하는 특정 패키지가 없을 수 있다는 것이다.

(sun.security.~~ 패키지는 JDK 내부에서 사용하는 내부 패키지로 자바8에서는 지원하지 않아서 symbol.file에 없다고 한다.)

 

그러한 symbol file을 무시하는 옵션을 주게 되면,

javac 컴파일러가 symbol.file 참조 없이 전체를 재 컴파일 하여 내부패키지 또한 사용할 수 있다.

 

build.gradle에 해당 구문을 입력 하면 된다.

tasks.withType(JavaCompile) {
  options.fork = true
  options.forkOptions.executable = 'javac'
  options.compilerArgs << '-XDignore.symbol.file'
}

내부패키지를 사용하는 것은 일반적으로 권장 되지 않는 사항이므로,

다른라이브러리를 통해 구현하는 방향으로 가는 것이 좋다.

 

 

👏

👏