Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null) 해결

Chung Lee·2024년 10월 27일
Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
...
It appears as if your JDK does not supply a working agent attachment mechanism.
Java               : 1.8
JVM vendor name    : Amazon.com Inc.
JVM vendor version : 25.422-b05
JVM name           : OpenJDK 64-Bit Server VM
JVM version        : 1.8.0_422-b05
JVM info           : mixed mode
OS name            : Mac OS X
OS version         : 14.4
...
Caused by: java.lang.IllegalStateException: Error during attachment using: net.bytebuddy.agent.ByteBuddyAgent$AttachmentProvider$Compound@97b54ad
...
Caused by: java.lang.UnsatisfiedLinkError: Native Library /Users/userName/Library/Java/JavaVirtualMachines/corretto-1.8.0_422/Contents/Home/jre/lib/libattach.dylib already loaded in another classloader
...
Caused by: [CIRCULAR REFERENCE: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in sun.misc.CompoundEnumeration@3dbdc020]

등의 에러가 발생하며 테스트 코드 실행이 되지 않았습니다.

MSA 구조이기에 각 마이크로 서비스 별로 테스트 코드가 존재하고 이전까지는 개발 시 문제가 되지 않았지만 특정 마이크로 서비스의 테스트 코드를 실행하니 이러한 오류가 발생했습니다.

오류를 읽어봤을 때 MockMaker 가 초기화되지 않았고 대체가 없기 때문에 테스트가 정상 실행되지 못했다고만 보여 정확한 해결 방법을 위해 구글링을 했습니다만

핵심만 말하면 제 경우에는 두 가지 방법으로 해결 가능했습니다.

  1. 프로젝트 SDK 버전 변경

8 버전에서 11 버전으로 변경하니 오류는 사라졌습니다.

하지만, 또 다른 마이크로 서비스에서 동일한 오류가 발생해서 동일하게 11버전으로 변경하니 다른 의존성에 의해 런타임 중 오류가 발생했습니다.

java.lang.IllegalStateException: Failed to load ApplicationContext

근원적인 해결책을 위해 구글링을 해도 대부분은 자바 버전을 업데이트 혹은 byte-buddy 를 의존성으로 추가하는 방법이었습니다.

의존성 추가로 해결한 케이스

여러 해결방법이 달린 stackoverflow 게시글

오류가 발생한 프로젝트에는 이미 아래 의존성이 있고 mockito-core 에서 byte-buddy 를 가지고 있기 때문입니다.

		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-junit-jupiter</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-core</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
		    <groupId>org.mockito</groupId>
		    <artifactId>mockito-inline</artifactId>
		    <scope>test</scope>
		</dependency>
  1. mockito 의존성 삭제

byte-buddy 가 이미 Mockito-core 에 존재하는 것처럼 spring-boot-starter-test 에도 아래와 같이 Mockito 의존성이 이미 존재합니다. 그래서 위에 작성한 세 개의 의존성을 삭제하고 빌드하니 에러가 발생하지 않았습니다.

	<dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <version>4.5.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-junit-jupiter</artifactId>
      <version>4.5.1</version>
      <scope>compile</scope>
    </dependency>

동일한 오류를 겪고 계신 분께 도움이 되었으면 좋겠습니다.

감사합니다.

추가)

starter-test 내에 mockito-core, -junit-jupiter 가 존재하기에 mockito-inline 만 삭제해봤는데 역시 오류가 사라졌습니다.

찾아보니 커뮤니티에서 static, final 클래스 mock 기능 통합이 논의되었고 따라서 mockito 버전이 올라가며 mockito-core 에 -inline 기능이 포함되어 별도로 작성되었다고 합니다.
그래서 별도 작성한 경우 문제가 발생한 것 같습니다.
stackOverFlow 링크 내 댓글 참고

정말 통합이 되었나? 궁금해서 마찬가지로 위 링크 내 댓글에 있는 적용 방법을 실제로 구현해보았습니다.

  1. src/test/resources/mockito-extensions 경로에 org.mockito.plugins.MockMaker 파일 생성 후 아래 내용 작성 후 저장
mock-maker-inline
final class FinalClass {
  String finalMethod() { return "something"; }
}


import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;

class FinalMockClassTest {

    @Test
    @DisplayName("Final_class_mock_테스트")
    void Final_class_mock() {
        // given
        FinalClass concrete = new FinalClass();
        FinalClass mock = mock(FinalClass.class);
        given(mock.finalMethod()).willReturn("not anymore");

        // when && then
        assertThat(mock.finalMethod()).isNotEqualTo(concrete.finalMethod());
    }
}

테스트 정상 통과되어 잘 작동함을 확인했습니다.

감사합니다.

추가2)

org.mockito.plugins.MockMaker 파일에 'mock-maker-inline' 를 작성 후 재실행해보니 동일하게 에러가 발생했습니다.

미루어보아 결국 static, final 을 mock 해주기 위한 기능이 오류를 발생시킴을 알 수 있었습니다...만, 근본적으로 무엇에 의한 오류인지 알 수 없는 게 아쉽네요.

0개의 댓글