관리 메뉴

제뉴어리의 모든것

[JAVA] Parameter타입객체.getName() 이 arg0, arg1 로 나올때... 본문

BugNote

[JAVA] Parameter타입객체.getName() 이 arg0, arg1 로 나올때...

제뉴어리맨 2022. 10. 31. 14:32

상황

아래의 소스를 보자.

Parameter 객체에서 getName() 메소드를 이용하여, 파라미터명을 가져오려고 했다.

@Aspect
@Component
@RequiredArgsConstructor
public class TxAspect {

    private final PlatformTransactionManager transactionManager;

    @Around("@annotation(com.preproject.server.tx.NeedMemberId)") //NeedMemberId를 붙인 메소드에
    public Object applyTx(ProceedingJoinPoint joinPoint) throws Throwable {

        TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionDefinition());

        try {
            Object[] parameterValues = joinPoint.getArgs(); //우선 현재 Controller로 넘어 온 파라미터 값들을 가져 옴
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); //SecurityContext에 저장된 Authentication 가져 옴

            WrapperUserNamePasswordAuthenticationToken wUNPAT = (WrapperUserNamePasswordAuthenticationToken) authentication;
            Long memberId = wUNPAT.getMemberId(); //SecurityContext에 저장된 서버가 인식하는 실제 MemberId

            //조인 포인트 (호출 되는 메소드를 말한다) 가 호출되는 시점에 넘겨 받은 인자값들
            MethodSignature signature = (MethodSignature) joinPoint.getSignature(); //메소드의 선언 부분에 대한 정보
            Method method = signature.getMethod(); //메소드 자체의 대한 정보를 갖는 클래스
            Parameter[] parameters = method.getParameters(); //메소드가 갖는 파라미터들의 정보

            for (int i = 0; i < method.getParameters().length; i++) {
                if (parameters[i].getName().equals("authMemberId")) { //------------- 문제의 부분
                    parameterValues[i] = memberId; //해당 파라미터에 위에서 Authentication을 이용하여 얻은 "memberId"를 넣음
                    break;
                }
            }

            Object object = joinPoint.proceed(parameterValues); //새롭게 설정된 파라미터 값들을 해당 메소드에 전달

            transactionManager.commit(transaction);
            return object;
        } catch (RuntimeException runtimeException) {
            transactionManager.rollback(transaction);
            throw runtimeException;
        }
    }
}

그런데,,,

문제는 내 Local에서는 잘 되지만,

해당 코드를 pull로 받아 사용하는 팀원분 인텔리제이에서는 정상적으로 작동하지 않아서 보니

"문제의 부분" 인 

if (parameters[i].getName().equals("authMemberId")) 코드에서

authMemberid란 파라미터명의 파라미터를 찾지 못하였다.

그래서 확인해보니...

모든 파라미터명이 단순히 순서에 따라,

arg0, arg1, arg2 .... 이런식으로 넘어왔다.

 

 


에러 메세지

 

 


원인

원인은 아직도 정확히는 모르겠다..

그러나, 이것저것 구글링을 하다보니

자바 버전에따라 특정 옵션을 넣어줘야 정상적으로 필드명을 가져오고 

그렇지 않으면,

arg0, arg1 ... 이런식으로 가져온다고 하였다.

그래서 동료분들의 intellij의 java 버전을 확인 하던 중,

팀원분의 제안으로 

아래 해결방법과 같이 해주니 정상적으로 작동하였다... 

즉, intellij 내부적으로 빌드, 컴파일 할때의 java 버전과 gradle로 빌드, 컴파일 할때의 java 버전이 다른듯하다..

그런데, 아무리 봐도 동료분의 세팅과 내 세팅을 보면 모두 자바 자바 11 로 동일하다..

 


해결 방법

윈도우 기준으로 FIle -> Settings 들어가서

Gradle 항목에서 우측 화면의 중간쯤 보면

 

  • Build and run using 
  • Run tests using 

항목들이 있을것이다.

해당 항목들 모두 Gradle이라고 바꿔 넣어라.

 

 


결론

빌드, 컴파일을 뭘로할지

java 버전이 뭘지에 따라 메소드의 작동이 달라질 수도 있다...

 


참고

 

아래는 해결 방법이라고 했던 것들인데, 현재 내 경우에서는 되진 않았다. 그냥 참고만,,

https://csy7792.tistory.com/311

 

[JAVA] Parameter name arg0이 나올 때

JAVA 8부터 Reflection을 사용하여 Parameter name을 가져올 수 있다고 들었다. 그래서 시도를 했더니 arg0, arg1 이런식으로 나왔다. 조금 찾아봤더니 옵션을 추가해야했다. 컴파일시 -parameters 옵션을 추가

csy7792.tistory.com

https://kim-jong-hyun.tistory.com/122

 

[JAVA] - Reflection을 이용하여 메서드 파라미터 변수이름 가져오기

최근에 회사 서비스에 AWS X-RAY를 적용하면서 요청 파라미터에 대한 정보를 트레이스 하려고 Reflection을 이용해서 파라미터의 변수이름과 값을 조회했는데 파라미터 값은 잘 나왔는데 변수이름이

kim-jong-hyun.tistory.com

 

 

 

 

 

intellij의 java 버전 확인

https://effectivecode.tistory.com/1366

 

IntelliJ IDEA JDK Version변경하는 방법

오픈JDK를 11로 바꿨으니 개발하는 IDEA의 JDKVersion도 변경을 해야 한다. 메이븐 설정의 프로젝트에서는 pom.xml에서 자바 버전을 변경해주면 된다. 11 그리고 인텔리제이에서는 다음 절차에 따라 변

effectivecode.tistory.com

 

Parameter.getName() 의 공식문서

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/reflect/Parameter.html#getName() 

 

Parameter (Java SE 11 & JDK 11 )

 

docs.oracle.com