programing

maven Failsafe가 java.lang에서 실패합니다.클래스 정의를 찾을 수 없음 오류

elecom 2023. 7. 22. 09:23
반응형

maven Failsafe가 java.lang에서 실패합니다.클래스 정의를 찾을 수 없음 오류

새로운 프로젝트를 시작했습니다.사후 수정 SQL 구성.기본적으로 4개의 간단한 데이터베이스 테이블에 대한 CRUD 액세스를 제공해야 하는 간단한 Spring Boot 애플리케이션입니다.저는 첫 번째 테이블에 대한 저장소와 해당 저장소에 대한 몇 가지 기본 통합 테스트를 작성했습니다.이 테이블은 업데이트 기능을 제공하지 않아야 하므로 다음과 같이 업데이트 기능을 구현했습니다.

@Override
public void update(@NonNull Domain domain) throws NotUpdatableException {
    throw new NotUpdatableException("Domain entities are read-only");
}

어디에NotUpdatableException사용자 지정 예외 클래스입니다.

이 코드의 IT는 다음과 같습니다.

@Test(expected = NotUpdatableException.class)
public void testUpdate() throws NotUpdatableException {
    val domain = Domain.of("test");

    domainRepository.update(domain);
}

내 IDE(InteliJ 2018.2 EAP)에서 이 테스트를 실행하면 잘 통과하지만 실행 중입니다.mvn verify실패 대상:

java.lang.NoClassDefFoundError: com/github/forinil/psc/exception/NotUpdatableException
  at java.lang.Class.getDeclaredMethods0(Native Method)
  at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
  at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
  at java.lang.Class.getMethod0(Class.java:3018)
  at java.lang.Class.getMethod(Class.java:1784)
  at org.apache.maven.surefire.util.ReflectionUtils.tryGetMethod(ReflectionUtils.java:60)
  at org.apache.maven.surefire.common.junit3.JUnit3TestChecker.isSuiteOnly(JUnit3TestChecker.java:65)
  at org.apache.maven.surefire.common.junit3.JUnit3TestChecker.isValidJUnit3Test(JUnit3TestChecker.java:60)
  at org.apache.maven.surefire.common.junit3.JUnit3TestChecker.accept(JUnit3TestChecker.java:55)
  at org.apache.maven.surefire.common.junit4.JUnit4TestChecker.accept(JUnit4TestChecker.java:53)
  at org.apache.maven.surefire.util.DefaultScanResult.applyFilter(DefaultScanResult.java:102)
  at org.apache.maven.surefire.junit4.JUnit4Provider.scanClassPath(JUnit4Provider.java:309)
  at org.apache.maven.surefire.junit4.JUnit4Provider.setTestsToRun(JUnit4Provider.java:189)
  at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:132)
  at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:379)
  at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:340)
  at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:125)
  at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:413)
Caused by: java.lang.ClassNotFoundException: 
com.github.forinil.psc.exception.NotUpdatableException
  at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
  at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
  ... 18 more

그리고 솔직히 왜 그런지 모르겠어요...

누군가가 이 문제에 직면한 적이 있습니까?

제가 알아냈기 때문에 혹시 다른 사람도 같은 문제가 생길까봐 제가 직접 질문에 답을 드리는 겁니다.

maven-failsafe-plugin은 target/classes 디렉토리를 클래스 경로에 추가하는 것이 아니라 결과 jar를 추가하는 것으로 밝혀졌는데, 이는 대부분의 경우에 잘 작동합니다.

그러나 Spring Boot의 경우 target/classes 디렉토리의 내용 대신 Spring Boot 사용자 지정 클래스로더 클래스가 포함되어 있으며 디렉토리 BOOT-INF/classes로 이동됩니다.maven-failsafe-plugin은 '일반' 클래스로더를 사용하기 때문에 SpringBoot 클래스로더 클래스만 로드합니다. 처음에 실패하면 프로젝트 클래스 중 하나를 사용해야 합니다.

Spring Boot 프로젝트에서 IT 테스트를 실행하려면 패키지된 jar를 종속성에서 제외하고 원래의 수정되지 않은 jar 또는 target/classes 디렉토리를 추가해야 합니다.

maven-failsafe-plugin 및 Spring Boot에 대한 올바른 구성은 다음과 같습니다.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.21.0</version>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                 <goal>verify</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <classpathDependencyExcludes>
            <classpathDependencyExcludes>${groupId}:${artifactId}</classpathDependencyExcludes>
        </classpathDependencyExcludes>
        <additionalClasspathElements>
            <additionalClasspathElement>${project.build.outputDirectory}</additionalClasspathElement>
        </additionalClasspathElements>
    </configuration>
</plugin>

spring-boot-maven-plugin 구성에 분류기를 추가하는 것도 효과적인 것으로 보입니다.따라서 SpringBoot는 "기본" 빌드 대상 jar를 그대로 두고 대신 분류자 이름이 추가된 SpringBoot uber jar를 만듭니다.

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
          <classifier>sb-executable</classifier>
    </configuration>
</plugin>

이것은 봄부츠 프로젝트의 경우 저에게 효과가 있었고,failsafe plugin version - 3.0.0-M5

<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-failsafe-plugin</artifactid>
<executions>
    <execution>
        <goals>
            <goal>integration-test</goal>
            <goal>verify</goal>
        </goals>
    </execution>
</executions>
<configuration>
    <classesdirectory>${project.build.outputDirectory}</classesdirectory>
</configuration>
</plugin>

블로그 참조 / 아름다운 설명 - https://bjoernkw.com/2020/12/06/using-maven-failsafe-with-spring-boot/

당신이 어떤 프로젝트를 이해하고 싶다면요.build.outputDirectory는 - 메이븐 프로젝트입니다.build.디렉토리

감사합니다!

언급URL : https://stackoverflow.com/questions/50787704/maven-failsafe-fails-with-java-lang-noclassdeffounderror

반응형