Project/Troubleshooting

[Project - Troubleshooting] 파라미터명 인식 오류

Yn3(인삼) 2024. 5. 9. 15:20

문제 발생

SpringBoot로 개발을 하고 실행시켜 보니 아래와 같은 오류가 나타났다.

Parameter 0 of constructor in XXX.member.controller.MemberController required a single bean, but 2 were found:
- memberServiceImpl: defined in file [/XXX/out/production/classes/com/travelplan/member/service/MemberServiceImpl.class]
- memberService: defined by method 'memberService' in class path resource [XXX/member/config/MemberConfig.class]

This may be due to missing parameter name information

Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

Ensure that your compiler is configured to use the '-parameters' flag.
You may need to update both your build tool settings as well as your IDE.

 

원인 분석

Parameter 0 of constructor in XXX.member.controller.MemberController required a single bean, but 2 were found:
- memberServiceImpl: defined in file [/XXX/out/production/classes/com/travelplan/member/service/MemberServiceImpl.class]
- memberService: defined by method 'memberService' in class path resource [XXX/member/config/MemberConfig.class]
Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

MemberController에서 MemberService 빈을 찾을 때 MemberServiceImpl 클래스와 MemberConfig 클래스에서 2개의 MemberService 빈이 발견되어 컨트롤러에서 명확한 빈을 주입하지 못하는 오류 같다.

 

이 오류를 해결하려면 같은 이름의 빈이 2개 있으므로

@Primary 어노테이션을 사용하여 MemberSerivceImpl 클래스나 MemberConfig 클래스의 MemberSerivce 빈을 기본으로 주입할 빈으로 지정해 주거나,

@Qualifier 어노테이션을 사용하여 MemberController에서 MemberService에 필요한 빈의 이름을 명시해 줘서 해결하면 된다. (이때 MemberServiceImpl과 MemberConfig 중 하나는 MemberService를 빈 등록할 때 빈 이름을 변경해줘야 한다.)

 

하지만 위와 같은 방법을 사용해서 해결하는 게 끌리지 않아서 더 찾아보고 로그를 다시 확인했다.

This may be due to missing parameter name information
Ensure that your compiler is configured to use the '-parameters' flag.
You may need to update both your build tool settings as well as your IDE.

파라미터 이름 정보가 누락되어서 오류가 생겼을 수도 있다고 한다.

또한 컴파일러가 '-parameters' 플래그를 사용하도록 구성되었는지 확인해 보라고 한다.

 

이 로그를 중심으로 찾아보니 해당 오류는 @Primary나 @Qualifier 어노테이션을 쓰지 않고 해결할 수 있는 방법이 있었다.

 

Spring Boot 3.2부터 자바 컴파일러에 -parameters 옵션을 넣어줘야 어노테이션의 이름을 생략할 수 있다.

주로 아래 어노테이션을 사용할 때 문제가 발생한다.

  • @RequestParam
  • @PathVariable
  • @Autowired
  • @ConfigurationProperties

내가 문제가 생긴 곳은 @RequiredArgsConstructor를 사용한 부분 같다.

@Service
@RequiredArgsConstructor
public class MemberServiceImpl implements MemberService {
    private final MemberRepository memberRepository;
    
    /*
    @Autowired
    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
    */
}

이 어노테이션은 final 필드를 확인해서 주석 부분을 자동 생성한다.

따라서 직접적으로 @Autowired를 사용하지는 않았지만 내부적으로 자동 생성된 @Autowired를 사용한다.

 

자동 생성된 @Autowired 생성자 부분을 보자. (주석 부분)

MemberRepository를 주입받을 때 변수 이름인 memberRepository를 통해서 memberRepository라는 이름의 스프링 빈을 찾는다.

하지만 파라미터명을 사용할 수 없기 때문에 이름으로 대상을 찾을 수 없다.

 

문제 해결

IntelliJ IDEA -> Setting에서 Gradle을 검색한다.

Build and run using을 위 그림과 같이 IntelliJ IDEA로 선택한 경우에만 문제가 발생한다고 한다.

따라서 아래 그림과 같이 Gradle로 변경하자. (Gradle이 컴파일 시점에 해당 옵션을 자동으로 적용해 준다.)

이 문제로 시간을 많이 써서 너무 아쉽다. (역시 개발은 설정이 반...)

 

도움 받은 곳

https://docs.google.com/document/d/1j0jcJ9EoXMGzwAA2H0b9TOvRtpwlxI5Dtn3sRtuXQas/edit