JUnit AssertionError:在Maven中运行时无法识别平台
我正在使用Java 1.8将我们项目的构建结构从Ant转换到Maven(3.3.3),但我遇到了一个令我困惑的问题。我们的所有单元测试在Ant和Eclipse中都能正常工作,但我遇到过几个在Maven中执行失败的单元测试。失败的测试(不幸的是,由于公司的限制,我不能发布源代码)都试图通过javax.Imageio.ImageIO类读取图像,并且似乎都失败了,并显示NoClassDefFoundError,声明它们无法初始化java.nio.file.TempFileHelper。现在,我已经看到当某个东西试图初始化类并失败时会突然出现这种类型的问题(而不是根本找不到类定义),但我查看了TempFileHelper类的源代码,我似乎找不出会失败的是什么。
堆栈跟踪(手动键入,请原谅任何类型的人):
java.lang.NoClassDefFoundError: Could not initialize class java.nio.file.TempFileHelper
at java.nio.file.Files.createTempFile(Files.java:897)
at javax.imageio.stream.FileCacheImageInputStream.<init>(FileCacheImageInputStream.java:102)
at com.sun.imageio.spi.InputStreamImageInputStreamSpi.createInputStreamInstance(InputStreamImageInputStreamSpi.java:69)
at javax.imageio.ImageIO.createImageInputStream(ImageIo.java:357)
at javax.imageio.ImageIO.read(ImageIO.java:1397)
... our code beyond here ...
调用ImageIO.read的类是在与单元测试(称为core)不同的maven模块中定义的,并且core在此之前已经成功构建。调用ImageIO.Read的类提供了核心中定义的PNG文件的相对路径,图像存储在核心的Resources文件夹中的"Images"子文件夹下。
示例,使用foo.png作为文件名:
core/src/main/resources/images/foo.png
URL imageUrl = SomeClass.class.getResource("/images/foo.png");
ImageIO.read(imageUrl);
我已经验证了,在构建核心之后,foo.png位于core.jar中,并且位于JAR根目录下的图像文件夹中,并且核心模块是正在测试的模块的有效依赖项。
非常感谢您的帮助!
更新%1
在浏览TempFileHelper时,我无意中发现了一些可能失败的代码,并将其带入单元测试,以查看它是否继续失败。通过以下堆栈跟踪,该失败现在似乎表明默认文件系统未知:
java.lang.AssertionError: Platform not recognized
at sun.nio.fs.DefaultSystemProvider.create(DefaultSystemProvider.java:68)
... our code truncated...
更新2
根据Alexandre Carcapanis的请求,以下是POM片段。该项目是多模块的,父POM使用插件管理来控制版本。
父POM代码段:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
子POM代码段:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgs>
<arg>-XDignore.symbol.file</arg>
<compilerArg>-XDignore.symbol.file</compilerArg>
</compilerArgs>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
解决方案
我到处找了很久,才发现这个问题。我们的一位开发人员似乎编写了一个测试,将os.name(设置为"Testos")和os.version系统属性重置,但从未将它们重置为以前的值。这会导致所有的java.nio.Path调用失败。
我在查看sun.nio.fs.DefaultFileSystemProvider类的源代码后发现了这一点,它立即告诉我它试图查找的内容和期望值。在发现这一点后,并进行了更多的谷歌搜索,我插入了一个System.getProperty("os.name"),并在其中一个失败的测试中将其打印出来,导致我找到了"Testos"。在发现这一点之后,只需确定no、Maven或JUnit正在将os.name设置为该值,因此,它一定在我们的代码中。
感谢所有试图提供帮助的人,我们非常感谢您的帮助。
Rob
相关文章