【问题标题】:Maven integration-test doesn't find my class in same package structureMaven 集成测试在相同的包结构中找不到我的类
【发布时间】:2016-11-17 20:07:23
【问题描述】:

这是我的文件:


Pom 父母:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>my.group</groupId>
    <artifactId>my.artifact.pom</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>my.artifact.ws</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.2.RELEASE</version>
    </parent>

    <properties>
        <!-- test -->
        <maven.test.failure.ignore>false</maven.test.failure.ignore>
    </properties>

    //lot of dependencies...

    <!-- PROFILES -->
    <profiles>
        <profile>
            <id>local</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
                <unit-tests.skip>false</unit-tests.skip>
                <integration-tests.skip>true</integration-tests.skip>
            </properties>
        </profile>
        <profile>
            <id>integration</id>
            <modules>
                <module>my-module-integration-test</module>
            </modules>
            <properties>
                <unit-tests.skip>true</unit-tests.skip>
                <integration-tests.skip>false</integration-tests.skip>
            </properties>
        </profile>
    </profiles>

    <!-- PLUGIN -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>${encoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

模块-ws pom:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <artifactId>my.artifact.ws</artifactId>
    <packaging>jar</packaging>
    <parent>
        <groupId>my.group</groupId>
        <artifactId>my.artifact.pom</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    //lot of dependencies...

</project>

集成测试 pom:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <artifactId>my.artifact.integration.test</artifactId>
    <packaging>jar</packaging>

    <parent>
        <groupId>my.group</groupId>
        <artifactId>my.artifact.pom</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <properties>
        <unit-tests.skip>false</unit-tests.skip>
        <integration-tests.skip>true</integration-tests.skip>
    </properties>

    <dependencies>
        <dependency>
            <groupId>my.group</groupId>
            <artifactId>my.artifact.ws</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
            </plugin>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <executions>
                    <execution>
                        <id>integration-test</id>
                        <goals>
                            <goal>integration-test</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

我的文件夹结构:

my-module
|-- my-module-integration-test
|   `-- src
|       `-- test
|           `-- java
|               `-- my
|                   `-- module
|                       `-- ws
|                           `-- rest
|                               `-- MyTest
`-- my-module-ws
    `-- src
        `-- main
            `-- java
                `-- my
                    `-- module
                        `-- Application

当我运行mvn clean install -P integration 时,我会收到消息:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-testCompile) on project mp-schedule-integration-test: Compilation failure: Compilation failure:
[ERROR] /Users/me/dev/my-module/my-module-integration-test/src/test/java/my/module/ws/rest/MyTest.java:[3,28] cannot find symbol
[ERROR] symbol:   class Application
[ERROR] location: package my.module

如果我将 Application 类放在 my-module-integration-test 的测试结构中,它可以工作(Go Horse)

有人可以帮我吗?

Ps.: os 模块和项目的名称可能是错误的,只是为了隐藏原始名称。

GitHub:https://github.com/LucasHCruz/stack40664101

特拉维斯:https://travis-ci.org/LucasHCruz/stack40664101

【问题讨论】:

  • 你确定你对包含Application类的模块有正确的依赖吗?
  • @Lucas 你用的是什么 maven 版本?我无法用 maven 3.x 重现它
  • 您使用的是&lt;module&gt;my.artifact.ws&lt;/module&gt;,但在后面的树中,磁盘上的文件夹称为my-module-ws(带有破折号,而不是圆点)。它是哪一个?请发minimal reproducible example,否则无法提供帮助。可能是该类受包保护而您无法访问它吗?您还需要发布Application,可能还需要发布MyTest。这里有太多的未知数。
  • 但底线是这应该可以工作,所以问题出在你没有展示的东西上。假设你是从多模块项目的父 POM 构建的,正如你一直应该做的那样,我的钱是 Application 而不是 public。或者某处有错字,因为您发布的 POM 不可能是您真正的 POM,因为它们甚至没有有效的 XML 语法。
  • 嗨卢卡斯。我无法使用问题中提供的信息重现您的问题。但也许这个链接会对你有所帮助:github.com/StefanHeimberg/…。我为我们公司的一些讨论创建了带有单元/集成和系统测试的多项目设置的 github 存储库

标签: java maven testing integration-testing


【解决方案1】:

-- github 发帖后更新

问题mp-schedule-ws模块的pom.xml中调用的重新打包spring-boot-maven-plugin。一旦 spring-boot-maven-plugin 被包含在你的 pom.xml 中,它会自动尝试重写档案以使用 spring-boot:repackage 目标使其可执行。

由于 mp-integration-test 包中的依赖关系,mp-schedule-ws/target/mp-schedule-ws-1.0-SNAPSHOT.jar 实际上会在类路径中,但是如果您查看内部结构,您会看到它加载了 org/springframework/boot/loader/* 类,并且您的类将驻留在 @ 987654331@文件夹,如BOOT-INF/classes/com/cnova/mpschedule/Application.class

如果你把 spring-boot-maven-plugin 放在注释中,你的构建就像一个 魅力。

要解决这个问题,您可以遵循一些策略:

  • 使用 classifier 为重新打包的可执行文件构建一个单独的 jar
  • 有条件地将spring-boot-maven-plugin 构建执行绑定到特定的打包配置文件,这样它就不会在集成测试配置文件中执行
  • 创建一个单独的模块,仅用于构建您的 Spring Boot 可执行 jar
  • spring boot 插件会使用 .jar.original 扩展名保留原始 jar 的备份,您可以使用 maven 插件复制它并将其添加到类路径 [ugly hack]

一个例子mp-schedule-wspom.xml中添加分类器的第一个策略:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <executable>true</executable>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                    <configuration>
                        <classifier>exec</classifier>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

这会给你 2 个罐子:

$ ls -al mp-schedule-ws/target/
-rwxr--r--  1 nick  wheel  55188756 Nov 23 06:38 mp-schedule-ws-1.0-SNAPSHOT-exec.jar
-rw-r--r--  1 nick  wheel     20311 Nov 23 06:38 mp-schedule-ws-1.0-SNAPSHOT.jar

另一个示例第二种策略是在mp-schedule-ws模块中定义一个特定的构建配置文件,例如:

<profiles>
    <profile>
        <id>package-application</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <executable>true</executable>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

这给出了:

$apache-maven-3.3.9/bin/mvn clean install -P integration

[INFO] mp-schedule ........................................ SUCCESS [  0.230 s]
[INFO] mp-schedule-core ................................... SUCCESS [  3.845 s]
[INFO] mp-schedule-ws ..................................... SUCCESS [  0.563 s]
[INFO] mp-schedule-integration-test ....................... SUCCESS [  0.721 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.751 s

并为 Spring Boot 构建可执行 jar:

$apache-maven-3.3.9/bin/mvn clean install -P package-application

[INFO] mp-schedule ........................................ SUCCESS [  0.255 s]
[INFO] mp-schedule-core ................................... SUCCESS [  3.822 s]
[INFO] mp-schedule-ws ..................................... SUCCESS [  0.968 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.396 s

当然,您可以选择最适合您项目的解决方案策略。

-- 旧答案 - 已过时,留作参考

它适用于 maven 3.x,我唯一需要更改的是添加

<version>1.0-SNAPSHOT</version>

my.artifact.ws,因为您在my.artifact.integration.test 中声明了依赖项

<dependency>
    <groupId>my.group</groupId>
    <artifactId>my.artifact.ws</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

我还在本地配置文件中添加了一个缺少的 &lt;properties&gt; 开始标记。

【讨论】:

  • 请指定maven版本。您的设置文件中有什么花哨的东西吗?
  • 看github到post
  • 感谢 github 的帖子,干得好,我现在可以复制它,它显示了一些有价值的信息;我用这个问题更新了我的答案,并提供了一些关于如何解决问题的指示
  • 创建一个单独的模块来构建 Spring boot 可执行文件是个好主意。但是这里也使用了classifier,这很好,它会创建带有分类器的 Spring Boot 的可执行 JAR,同时仍然像往常一样构建主要工件。但是请不要手动将“.jar.original”添加到类路径中,这真是一个丑陋的黑客......
  • 我也会使用分类器,我根据您的反馈更新了我的答案;复制.original是邪恶的,我写的时候觉得很脏。
猜你喜欢
  • 1970-01-01
  • 2010-10-10
  • 2015-07-28
  • 2019-08-21
  • 1970-01-01
  • 1970-01-01
  • 2019-03-19
  • 2019-05-17
  • 2013-03-04
相关资源
最近更新 更多