본문 바로가기
Develop/Java

[Java] compiler message file broken 에러

by 연로그 2024. 3. 17.
반응형

compiler message file broken:
key=compiler.misc.msg.bug arguments=11.0.13, {1}, {2}, {3}, {4}, {5}, {6}, {7} java.lang.AssertionError: Incorrect number of arguments; expected 4, found 0 에러

 


에러 발생 코드

 

에러가 발생한 코드를 살펴보자면 아래와 같다. REST API 호출 시 발생하는 예외를 executeApi() 메서드를 통해 공통적으로 처리했다. 이 코드 중에서 ParameterizedTypeReference<>(){} 부분에서 에러가 발생했다. 

@Slf4j
@RequiredArgsConstructor
@Service
public class AuthUserApiService {

    private final RestTemplate authApiRestTemplate;

    public AuthUserDto findByUserId(Long userId) {
        String path = String.format(FIND_BY_USER_ID, userId);
        ResponseEntity<ResponseWrapper<AuthUserDto>> result = executeApi(
            () -> authApiRestTemplate.exchange(path, new ParameterizedTypeReference<>() {
            })
        );

        ResponseWrapper<AuthUserDto> resultBody = result.getBody();
        if (resultBody == null || !resultBody.isSuccess()) {
            throw new UserException("result data is not success");
        }

        return resultBody.getData();
    }

    public void deleteUser(UserDeleteDto deleteDto) {
        executeApi(
            () -> authApiRestTemplate
                .exchange(DELETE, deleteDto, new ParameterizedTypeReference<>() {
                }, HttpMethod.POST)
        );
    }

    private <T> T executeApi(Supplier<T> supplier) {
        try {
            return supplier.get();

        } catch (HttpClientErrorException e) {
            log.info("rest exception: {}", e.getMessage(), e);
            throw new UserException(e.getMessage);

        } catch (Exception e) {
            log.error("rest exception: {}", e.getMessage(), e);
            throw new UserException(e.getMessage());
        }
    }
}

 

 


문제 원인

 

익명클래스 생성 시 다이아몬드 오퍼레이터 '<>'를 사용한 경우, 타입 추론이 불가능한 문제였다.

 

이 에러에는 이상한 점이 하나 있었다. 위 코드는 로컬에서는 잘 실행되지만, GitLab MR에 적용한 CI 과정에서는 항상 빌드 실패가 일어났다. 구글링을 해보니, 해당 문제는 JDK 11 일부 버전에서 발생하는 문제이고, 마이너 버전을 올리면서 fix 되었으니 버전을 업그레이드 하라고 한다.

 

참고 글

 

자바 버전부터 확인해보았더니 내 로컬에서는 11.0.16, CI 환경(에러가 난 환경)은 11.0.13이었다.

 

 


문제 해결 방법

 

1. jdk 버전을 올린다.

꼭 jdk 11보다 더 높은 버전으로 올리지 않아도 된다. 마이너 버전만 올려도 충분하므로, 버전 올리는게 부담되지는 않을 것이다.

 

헌데 글들을 읽다보면 업데이트 해야한다는 버전이 다 다르다. 사용하는 jdk의 종류에 따라서 해당 문제가 fix된 시점이 다른가? 정도로만 추측해본다. 내가 사용하고 있는 temurin은 11.0.18부터 해당 문제를 수정했다는 듯 하다. (https://github.com/adoptium/adoptium-support/issues/678 참고) 특이하게도 예외적으로 11.0.16 에서는 해당 문제가 발생하지 않는다고 하는데 내가 딱 그 버전을 사용하고 있었다.😅

 

 

2. 타입을 명시적으로 선언해준다.

익명 클래스와 <>를 함께 사용했던 구간에 타입을 명시적으로 선언해준다.

@Slf4j
@RequiredArgsConstructor
@Service
public class AuthUserApiService {

    private final RestTemplate authApiRestTemplate;

    public AuthUserDto findByUserId(Long userId) {
        String path = String.format(FIND_BY_USER_ID, userId);
        ResponseEntity<ResponseWrapper<AuthUserDto>> result = executeApi(
            // 수정된 부분: new ParameterizedTypeReference<> -> new ParameterizedTypeReference<ResponseWrapper<AuthUserDto>>
            () -> authApiRestTemplate.exchange(path, new ParameterizedTypeReference<ResponseWrapper<AuthUserDto>>() {
            })
        );

        ResponseWrapper<AuthUserDto> resultBody = result.getBody();
        if (resultBody == null || !resultBody.isSuccess()) {
            throw new UserException("result data is not success");
        }

        return resultBody.getData();
    }

    public void deleteUser(UserDeleteDto deleteDto) {
        executeApi(
            () -> authApiRestTemplate
                // 수정된 부분: new ParameterizedTypeReference<> -> new ParameterizedTypeReference<Void>
                .exchange(DELETE, deleteDto, new ParameterizedTypeReference<Void>() {
                }, HttpMethod.POST)
        );
    }

    private <T> T executeApi(Supplier<T> supplier) {...}
}
반응형