Maven Failsafe Classpath - PullRequest
       33

Maven Failsafe Classpath

0 голосов
/ 10 июня 2018

Я начал новый проект: PostfixSQLConfig .Это простое приложение Spring Boot, которое должно обеспечить доступ к CRUD для 4 простых таблиц базы данных.Я написал репозиторий для первой таблицы и несколько базовых интеграционных тестов для указанного репозитория.Поскольку эта конкретная таблица не должна обеспечивать функциональность обновления, я реализовал функцию обновления следующим образом:

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

, где NotUpdatableException - это мой класс исключений.

ИТ для этого кода выглядит следующим образом:

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

    domainRepository.update(domain);
}

Если запустить этот тест из моей IDE (IntelliJ 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

И я, честно говоря, понятия не имею, почему...

Кто-нибудь когда-нибудь сталкивался с этой проблемой?

1 Ответ

0 голосов
/ 11 июня 2018

Я понял это, поэтому отвечаю на свой вопрос, если у кого-то есть такая же проблема.

Оказывается, что maven-failsafe-plugin не добавляет каталог target / classes в classpath, а скорее результирующий jar, который в большинстве случаев работает нормально.

Однако, когда дело доходит до Spring Boot, результирующий jar содержит пользовательские классы загрузчика классов Spring Boot вместо содержимого каталога target / classes, которыепереехал в каталог BOOT-INF / classes.Поскольку maven-failsafe-plugin использует «обычный» загрузчик классов, он загружает только классы загрузчика классов Spring Boot, в случае неудачи в первую очередь ожидается использование одного из классов проекта.

Для запуска ИТ-тестов в проекте Spring Boot,нужно исключить упакованный 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>
...