[자바/코틀린/스프링] 자바-코틀린 통합 시 이슈 해결

1.

  • 문제: 코틀린 소스에서 Lombok 어노테이션에 의해 생성된 자바 클래스의 메서드를 호출하고 있다. 이 경우 그래들 빌드 시 자바 클래스의 메서드에 대해 unresolved reference 에러가 발생한다.
  • 원인: Lombok은 자바 컴파일러에 의해 처리되는 어노테이션 프로세서이다. 코틀린 컴파일러는 자바 컴파일러를 사용하지만 코틀린 컴파일 시 어노테이션 프로세서는 처리되지 않기 때문에 어노테이션 프로세서에 의한 코드 생성이 이루어지지 않는다.
  • 해결: 코틀린 컴파일 보다 자바 컴파일이 먼저 이루어지도록 빌드 시 컴파일 순서를 강제한다. 하지만 이 경우 자바 코드에서 코틀린 소스를 사용할 수 없다. 또다른 방법으로는 빌드 전 Lombok이 제공하는 Delombok 기능을 사용하여 자바 소스 코드를 Lombok에 의해 모든 소스 코드 변환이 적용된 코드로 전처리한 후 코틀린 소스 코드를 컴파일한다.
  • 참고: https://stackoverflow.com/questions/35517325/kotlin-doesnt-see-java-lombok-accessors


2.

  • 문제: 자바 및 JPA와 QueryDsl을 사용하는 환경에서 코틀린으로 작성한 엔티티 클래스의 Q클래스를 추가적으로 컴파일하기 위해 kapt 플러그인 추가 및 kapt "com.querydsl:querydsl-apt:${queryDslVersion}:jakarta" 의존성 추가 후 빌드 시 complieJava 태스크 실행 중 Attempt to create a file for type Q클래스 에러가 발생한다.
  • 원인: 기존 정의되어 있던 annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}:jakarta" 의존성에 의해 QueryDsl 어노테이션 프로세서가 두 번 실행된다. compileKotlin 태스크 실행 시 kaptKotlin 태스크가 실행되며 build/generated/source/kapt/main/... 경로에 코틀린으로 작성한 엔티티 클래스에 대한 Q클래스들이 생성된다. kapt는 자바 컴파일러를 사용하므로 kaptKotlin 태스크 실행 시 자바 컴파일러에 의한 어노테이션 프로세서도 수행되어 Q클래스의 중복 생성 시도가 일어나게 된다.
  • 해결: annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}:jakarta" 의존성을 제거한다. 이전에 자바의 어노테이션 프로세서에 대한 지원을 사용했다면, annotationProcessorkapt로 대체하는 것이 좋다. 프로젝트에 자바 클래스가 포함된 경우 kapt가 해당 클래스도 처리한다.


3.

  • 문제: 자바 및 코틀린 통합 환경에서 Mapstruct 라이브러리를 사용하여 코틀린의 데이터 클래스를 매핑하기 위해 매퍼 클래스 정의 후 빌드 시 매퍼 객체의 빈을 찾을 수 없다는 에러가 발생한다.
  • 원인: 기존 정의되어 있던 annotationProcessor "org.mapstruct:mapstruct-processor" 의존성에 의해 자바 객체의 매핑 처리는 되지만 코틀린 객체의 매핑 처리가 되지 않는다.
  • 해결: annotationProcessor "org.mapstruct:mapstruct-processor:" 의존성을 제거하고 kapt "org.mapstruct:mapstruct-processor" 의존성을 추가한다. 이전에 자바의 어노테이션 프로세서에 대한 지원을 사용했다면, annotationProcessorkapt로 대체하는 것이 좋다. 프로젝트에 자바 클래스가 포함된 경우 kapt가 해당 클래스도 처리한다.


4.

  • 문제: Mapstruct 라이브러리를 사용하여 코틀린의 데이터 클래스 매핑 시 매핑 후 객체의 val 프로퍼티에 값이 매핑되지 않는다.
  • 원인: 매핑 후 객체의 val 프로퍼티에 초기화 코드가 있을 경우 컴파일된 매핑 구현 클래스에 해당 프로퍼티의 매핑 코드가 존재하지 않게 된다. 초기화 코드를 제거할 경우 생성자 방식으로 매핑 대상 객체를 인스턴스화 하는 코드가 생성된다.
  • 해결: 프로퍼티 초기화 코드를 제거한다.


5.

  • 문제: 멀티 모듈 구조에서 한 모듈의 test 소스 셋에 존재하는 자바 소스로 된 테스트 클래스에서 다른 모듈의 java 소스 셋에 존재하는 코틀린 소스를 호출하였더니 java.lang.NoSuchMethodError가 발생한다.
  • 원인: ?
  • 해결: IntelliJ 캐시 삭제 및 재실행


참고

Comments