简体   繁体   English

Maven 使用 surefire-plugin 编译并提供 JPMS 模块的单元测试范围

[英]Maven compile and provided scopes for unit testing of JPMS module with surefire-plugin

Trying to test my maven project (one parent pom and several modules (jpms modules)) I got annoying Error occurred in starting fork :尝试测试我的 maven 项目(一个父 pom 和几个模块(jpms 模块))时,我遇到了烦人Error occurred in starting fork

Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.0.0-M4:test (default-test) on project com.foo.plugin: There are test failures.
...
Error occurred in starting fork, check output in log
Process Exit Code: 1
org.apache.maven.surefire.booter.SurefireBooterForkException: The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
...
Error occurred in starting fork, check output in log
Process Exit Code: 1
    at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:690)
    at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:285)
    at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:248)
    at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1217)
    at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:1063)
    at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:889)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginM

A solution I found, for example, here suggested to set <forkCount>0</forkCount> in surefire-plugin configuration.例如,我发现解决方案建议在 surefire-plugin 配置中设置<forkCount>0</forkCount> However, such solution doesn't allow to run tests on module-path, so I went to this surefire issue .然而,这样的解决方案不允许在模块路径上运行测试,所以我去了这个 surefire issue

Surefire developers (thanks to them) found out that the reason was in maven scope of the dependencies I used. Surefire 开发人员(感谢他们)发现原因在我使用的依赖项的 maven scope 中。 In my project I have:在我的项目中,我有:

         <dependency>
            <groupId>jakarta.ws.rs</groupId>
            <artifactId>jakarta.ws.rs-api</artifactId>
            <version>2.1.6</version>
            <scope>provided</scope> <!-- NOTE IT -->
        </dependency>
        <dependency>
            <groupId>jakarta.xml.bind</groupId>
            <artifactId>jakarta.xml.bind-api</artifactId>
            <version>2.3.2</version>
            <scope>provided</scope> <!-- NOTE IT -->
        </dependency>

And they said it had to be:他们说它必须是:

          <dependency>
            <groupId>jakarta.ws.rs</groupId>
            <artifactId>jakarta.ws.rs-api</artifactId>
            <version>2.1.6</version>
            <scope>compile</scope> <!-- NOTE IT -->
        </dependency>
        <dependency>
            <groupId>jakarta.xml.bind</groupId>
            <artifactId>jakarta.xml.bind-api</artifactId>
            <version>2.3.2</version>
            <scope>compile</scope> <!-- NOTE IT -->
        </dependency>

And when I changed the scope my project was tested by surefire without problems.当我更改 scope 时,我的项目通过 surefire 测试没有问题。 Both dependencies jakarta.ws.rs-api and jakarta.xml.bind-api are JPMS modules and are required by my JPMS modules. jakarta.ws.rs-apijakarta.xml.bind-api这两个依赖项都是 JPMS 模块,并且是我的 JPMS 模块所required的。

So the question, is the problem in my code ( provided is wrong if I want to run my tests for my JPMS module) or the problem is in surefire plugin?所以问题是我的代码有问题(如果我想为我的 JPMS 模块运行测试,则provided是错误的)或者问题出在 surefire 插件中?

NOTE: You can freely remove <scope>compile</scope> since no declaration of the scope in your POM means that the Maven will use the default value compile anyway.注意:您可以自由删除<scope>compile</scope> ,因为在您的 POM 中没有声明 scope 意味着 Maven 无论如何都会使用默认值compile

The scope of provided is the project architecture aspect.提供的scope是项目架构方面。

It is used in situations when the application server contains WS API (even if different arfifact file name).它用于应用程序服务器包含 WS API(即使不同的工件文件名)的情况。 This way we mark it provided which makes the WAR file smaller and the WS API artifact would not be included.通过这种方式,我们将其标记为provided ,这使得 WAR 文件更小,并且不会包含 WS API 工件。

In situations where you are also building serverless application and you are building your own container, then no scope of provided is needed to declare.在您同时构建无服务器应用程序并且构建自己的容器的情况下,则不需要声明provided的 scope。 There the artifact will appear within the Fat JAR which is what you expect.工件将出现在 Fat JAR 中,这正是您所期望的。

So as you can see the dependency marked as provided copes with classpaths.因此,正如您所看到的,标记为提供的依赖项处理类路径。 It appears on Compiler classpath but it does not appear in runtime.它出现在编译器类路径中,但不会出现在运行时中。

There is one more feature in the scope provided . provided的 scope 中还有一项功能。 It is the inheritance, where such of dependency cannot be inherited transitively.就是inheritance,这样的依赖是不能传递继承的。 If you have such dependency witht the scope provided in a POM, then the inheritance would not see the dependency in a dependent child POM.如果您对 POM 中提供的 scope 有这样的依赖,那么 inheritance 将看不到从属子 POM 中的依赖。

For more information pls see Maven documentation.有关详细信息,请参阅 Maven 文档。

http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

This scope is only available on the compilation and test classpath, and is not transitive.这个 scope 仅在编译和测试类路径上可用,不可传递。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM