[Java/kotlin] None of the following functions can be called with the arguments supplied 에러 해결

2021. 10. 9. 23:54☕️ java

Java로 개발중이던 소셜로그인 코드를 코틀린으로 마이그레이션 하는 과정에서 만난 에러를 공유합니다.

 

WebSecurityConfiguration에서 접근허용 배열인 AUTH_WHITELIST를 antMatchers에 설정하려고 할 때, None of the following functions can be called with the arguments supplied. 에러를 만나게 되었습니다.

 

 

해당 에러는 제공된 인수로 다음 함수를 호출할 수 없다는 에러인데, 이미 존재하는 배열인 AUTH_WHITELIST를 vararg(가변인자) 함수로 넘기려고 할 때 스프레드 연산자인 *를 붙여주지 않아서 발생하는 문제였습니다.

 

 

기존 코드

private static final String[] AUTH_WHITELIST = {
            "/health",
            "/v2/api-docs",
            "/swagger-resources",
            "/swagger-resources/**",
            "/configuration/ui",
            "/configuration/security",
            "/webjars/**",
            "/v3/api-docs/**",
            "/swagger-ui/**",
            "/oauth2/**",
            "/login",
            "/signin/*",
            "/signup",
            "/reissue",
            "/"
    };

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http /....생략.../                
                .authorizeRequests()
                .antMatchers(AUTH_WHITELIST).permitAll()
}

코틀린 코드

val AUTH_WHITELIST = arrayOf(
            "/health",
            "/v2/api-docs",
            "/swagger-resources",
            "/swagger-resources/**",
            "/configuration/ui",
            "/configuration/security",
            "/webjars/**",
            "/v3/api-docs/**",
            "/swagger-ui/**",
            "/oauth2/**",
            "/login",
            "/signin/*",
            "/signup",
            "/reissue",
            "/"
        )

override fun configure(http: HttpSecurity) {
        http /....생략..../
            .antMatchers(*AUTH_WHITELIST).permitAll()
            .anyRequest().authenticated()
}

 

가변인자 vararg는 뭐길래?

 

그럼 왜 가변인자 함수에 * 를 붙이지 않으면 에러가 났던 것일까요?

이것을 제대로 알기 위해 가변인자가 무엇인지부터 들어가보았습니다.

 

가변인자는 지정된 자료형의 인자를 여러 개를 받을 수 있는 메서드입니다. 즉, 개수가 정해지지 않고 원하는 만큼 매개변수를 받을 수 있는 기능입니다. 그래서 가변인자를 사용하면 함수를 호출할 때 인자 수를 유동적으로 지정할 수 있습니다.

public void test(String ...strs){
    for(String s: strs){
        System.out.println(s);
    }
}

public static void main(String[] args){
    test("test1", "test2", "test3");
}
  • 컴파일러가 가변인자를 만나면 매개변수를 배열로 반환해줍니다.
  • 원본인 test("test1", "test2", "test3"); 를 컴파일러로 변환하면 test(new String[] {"test1", "test2", "test3"}); 와 같이 됩니다.

 

 

그래서 왜 에러가 났던거지?

antMatchers를 타고 들어가보면, String... 가변인자로 값을 받고 있는 것을 알 수 있었습니다.

그리고 kotlin에서는 정의된 배열을 가변인자로 넘기려면 *(스프레드 연산자)를 붙여야한다고 정리되어 있었습니다.

즉, 앞서 정리했던 것처럼 배열을 antMatcher에 그대로 넣으려고 했기 때문에 발생한 문제였습니다.

비록 별 것 아닌 에러였지만, 덕분에 모르던 개념을 짚고 넘어갈 수 있어서 좋아습니다.

 

 

 

📚참고문헌

Functions | Kotlin

[java] Kotlin 배열을 Java varargs로 변환 - 리뷰나라

[Kotlin] 가변 인자(vararg) 사용하기, 배열을 가변 인자로 넘기기

자바 가변인자(Varargs)에 대해서

Java - 오버로딩(overloading), 가변인자(varargs)

[이펙티브 자바] item 32 - 제네릭과 가변인수를 함께 쓸 때는 신중하라

 

'☕️ java' 카테고리의 다른 글

[Java] JVM 구조와 메모리 영역 - Method, Heap, Stack Area  (3) 2021.08.03