我在一个项目中遇到了一个有趣的问题,其中使用了标题中提到的所有技术。我已经能够跟踪诊断(由Surefire准备的测试类路径),但我不明白它是否可以修复以及如何修复。这不是一个表明,对我来说这确实是一个小问题,但无论如何我想解决它。
首先粗略描述。
问题与在项目的特定模块中执行测试有关,并且仅以特定方式执行。
当我从主pom级别运行时,一切正常(测试通过):
cd ${projHome}
mvn install
当我跑步时,一切正常(测试通过):
cd ${projHome}/modules/CoreImplementation/
mvn test
这意味着我可以毫无问题地构建和测试,对于我的Jenkins也是如此,NetBeans可以在需要时从IDE运行测试。
但是当我从主pom级别运行时,该模块未通过测试:
cd ${projHome}
mvn test
出现此错误:
java.lang.NoSuchMethodError: it.tidalwave.northernwind.profiling.RequestProfilerAspect.aspectOf()Lit/tidalwave/northernwind/profiling/RequestProfilerAspect;
at it.tidalwave.northernwind.frontend.ui.spi.DefaultSiteViewController.processRequest(DefaultSiteViewController.java:82) ~[classes/:na]
at it.tidalwave.northernwind.frontend.ui.spi.DefaultSiteViewControllerTest.must_call_some_RequestProcessors_when_one_breaks(DefaultSiteViewControllerTest.java:161) ~[test-classes/:na]
作为第二遍(mvn test
之后)运行mvn install -DskipTests
恰好是Drone.io和Travis完成工作的方式。虽然我可以更改其配置,但我希望保持标准配置并尽可能解决问题。
简短的诊断和我的问题。
现在,问题简短(详情请见下文)。我能够以不同的方式追踪问题,Surefire准备类路径来执行测试。
当我运行mvn install
时,类路径为:
${repo}/org/apache/maven/surefire/surefire-booter/2.16/surefire-booter-2.16.jar
${repo}/org/apache/maven/surefire/surefire-api/2.16/surefire-api-2.16.jar
${projHome}/modules/CoreImplementation/target/test-classes
${projHome}/modules/CoreImplementation/target/classes
${projHome}/modules/Core/target/it-tidalwave-northernwind-core-1.1-ALPHA-37-SNAPSHOT.952b0c8bdc77.jar
${repo}/it/tidalwave/thesefoolishthings/it-tidalwave-role/3.0-ALPHA-1/it-tidalwave-role-3.0-ALPHA-1.jar
${projHome}/modules/Profiling/target/it-tidalwave-northernwind-core-profiling-1.1-ALPHA-37-SNAPSHOT.952b0c8bdc77.jar
${repo}/org/apache/commons/commons-math3/3.0/commons-math3-3.0.jar
…
当我运行mvn test
(从项目主页)时,类路径为:
${repo}/org/apache/maven/surefire/surefire-booter/2.16/surefire-booter-2.16.jar
${repo}/org/apache/maven/surefire/surefire-api/2.16/surefire-api-2.16.jar
${projHome}/modules/CoreImplementation/target/test-classes
${projHome}/modules/CoreImplementation/target/classes
${projHome}/modules/Core/target/unwoven-classes
${repo}/it/tidalwave/thesefoolishthings/it-tidalwave-role/3.0-ALPHA-1/it-tidalwave-role-3.0-ALPHA-1.jar
${projHome}/modules/Profiling/target/unwoven-classes
${repo}/org/apache/commons/commons-math3/3.0/commons-math3-3.0.jar
…
不同的部分是缩进的部分。在前一种情况下,SureFire仅对被测模块使用classes
目录(在我的情况下暂时忘记它们unwoven-classes
),并为每个依赖项使用已安装的jar文件。在后一种情况下,它似乎是对反应堆中的所有依赖项使用classes
。
类别路径中的这种差异给我带来麻烦的原因在下面的“血腥细节”一节中解释。简而言之,unwoven
意味着它们包含未被AspectJ扩充的字节码,因此是在运行时无法找到的方法。
我正在使用SureFire 2.16,但我也尝试了最新的2.19,没有任何变化。能够强制SureFire 始终使用jar文件的依赖关系将解决我的问题。如果你有答案,你可以在这里停止阅读我的帖子。
血腥细节(仅仅是为了好奇)。
错误模块artifactId为it-tidalwave-northernwind-core-default
,它取决于it-tidalwave-northernwind-core-profiling
中可用的方面 - 这是违规RequestProfilerAspect
所在的位置。方面库依赖关系是故障模块的常规依赖关系和aspectj插件的配置:
<dependency>
<groupId>it.tidalwave.northernwind</groupId>
<artifactId>it-tidalwave-northernwind-core-profiling</artifactId>
</dependency>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<configuration>
<aspectLibraries combine.children="append">
<dependency>
<groupId>it.tidalwave.northernwind</groupId>
<artifactId>it-tidalwave-northernwind-core-profiling</artifactId>
</dependency>
</aspectLibraries>
</configuration>
</plugin>
</plugins>
</build>
AspectJ集成是通过Super POM中的以下配置文件,在构建中激活,其相关部分是:
<profile>
<id>it.tidalwave-aspectj-springaop-v1</id>
...
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>compile</phase>
<configuration>
<outputDirectory>target/unwoven-classes</outputDirectory>
</configuration>
</execution>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<configuration>
<outputDirectory>target/unwoven-test-classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
...
在配置文件中配置了aspectj插件,以便在unwoven-test-classes
目录中静态编织二进制文件。这种方法的原因在于它是唯一可行的解决方案AFAIK让Lombok和AspectJ一起工作。
现在,回到上面描述的两个类路径:SureFire使用unwoven-classes
的事实意味着它指向未使用AspectJ方法扩充的字节码,因此出错。
参考
该项目是一个FLOSS项目,可以在
找到https://bitbucket.org/tidalwave/northernwind-src
或
https://github.com/tidalwave-it/northernwind-src
可以重现问题的变更集是f98e9a89ac70138c1b6bd0d4570a22d59ed71be6
。构建项目需要JDK 1.8.0(即使它还没有使用Java 8代码)。
可以在这里找到SuperPOM:
https://bitbucket.org/tidalwave/thesefoolishthings-superpom-src