본문 바로가기

Framework/My Spring Boot

컴파일시에 매개변수명이 삭제됨

문제상황

기본적으로 JVM이 .java 파일을 .class 파일로 컴파일하는 과정에서 메서드의 파라미터 이름을 arg로 수정합니다.

예시: sayNameAndAge(String name, String age)sayNameAndAge(String arg0, String arg1)

일반적인 프로그래밍에서는 컴파일을 할 때, 메서드 파라미터의 이름이 arg로 대체된다는 것을 알 기회가 없기에 많이 당황스러웠습니다. 이렇게 하면 매개변수를 어떻게 매칭시키지? 라는 생각이 들었습니다.

해결방법

처음 들었던 생각은 컴파일 과정에서 매개변수명을 남겨야한다는 생각이었습니다.

다행히 컴파일 옵션에서 파라미터 명을 유지할 수 있는 옵션이 있고, 저는 Gradle로 환경을 구성해서 build.gradle 파일을 수정해서 간단하게 해결했습니다.

compileJava {
    options.compilerArgs << '-parameters'
}

추가적인 문제

하지만 다른 문제가 있는데 제가 개발하고 있는 것은 프레임워크이고 다른 개발자의 컴파일 옵션을 강제할 수 없다는 것이었습니다.

추가적인 문제 해결방법

해결방법을 고민하다가 Spring Application을 개발할때 어떻게 했는지 다시 생각해보니, @PathVariable, @RequestParam등에 변수명이 존재함을 눈치챘습니다. Spring Framework 개발자들도 같은 고민끝에 어노테이션에 변수명을 넣어야한다고 결론을 내린것이죠.

그래서 컨트롤러 핸들러 메서드를 실행하고 매개변수를 매칭시킬때 해당 변수를 통해 매칭시키는 것으로 구현했습니다.

if (parameter.isAnnotationPresent(PathVariable.class)) {
    PathVariable pathVariable = parameter.getDeclaredAnnotation(PathVariable.class);
    String parameterName = pathVariable.value();
    Object value = objectMapper.readValue(pathVariables.get(parameterName), parameter.getType());
    args[i] = value;
} else if (parameter.isAnnotationPresent(RequestBody.class)) {
    args[i] = objectMapper.readValue(requestBody, parameter.getType());
} else if (parameter.isAnnotationPresent(RequestParam.class)) {
    RequestParam requestParam = parameter.getDeclaredAnnotation(RequestParam.class);
    String parameterName = requestParam.value();
    Object value = objectMapper.readValue(queryParams.get(parameterName), parameter.getType());
    args[i] = value;
}

 

출처:

https://medium.com/@daclouds/java-method-arguments-parameters-name-7c6ba6622e37

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javac.html

https://discuss.gradle.org/t/how-to-pass-parameters-option-to-javac-compiler-when-building-my-java-project-with-gradle/2106/2?source=post_page-----7c6ba6622e37--------------------------------