You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用exec-maven-plugin执行test scope内嵌PostgreSQL主类报错求助

问题

我想用exec-maven-plugin执行一个Java主类,该类依赖test scope的com.opentable.components:otj-pg-embedded:0.13.4创建内嵌PostgreSQL并执行查询,但执行命令clean test exec:java后出现NoClassDefFoundError错误:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  34.374 s
[INFO] Finished at: 2024-12-12T15:01:58Z
[INFO] ------------------------------------------------------------------------
[WARNING] 
java.lang.NoClassDefFoundError: org/apache/commons/io/FileUtils
    at com.opentable.db.postgres.embedded.EmbeddedPostgres.close (EmbeddedPostgres.java:376)
    at com.opentable.db.postgres.embedded.EmbeddedPostgres$1.run (EmbeddedPostgres.java:342)
    at java.lang.Thread.run (Thread.java:829)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.io.FileUtils
    at org.codehaus.mojo.exec.URLClassLoaderBuilder$ExecJavaClassLoader.loadClass (URLClassLoaderBuilder.java:198)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:527)
    at com.opentable.db.postgres.embedded.EmbeddedPostgres.close (EmbeddedPostgres.java:376)
    at com.opentable.db.postgres.embedded.EmbeddedPostgres$1.run (EmbeddedPostgres.java:342)
    at java.lang.Thread.run (Thread.java:829)

我的exec-maven-plugin配置如下:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>3.5.0</version>
    <executions>
        <execution>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>exec</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <executable>maven</executable>
        <classpathScope>test</classpathScope>
        <cleanupDaemonThreads>false</cleanupDaemonThreads>
        <mainClass>example.Main</mainClass>
    </configuration>
</plugin>

项目依赖树显示commons-io:commons-io:jar:2.8.0存在于test scope中:

[INFO] --- maven-dependency-plugin:2.8:tree
[INFO] com.example:example-console-app:jar:0.0.1
[INFO] +- org.eclipse.persistence:eclipselink:jar:4.0.3:compile
[INFO] |  +- jakarta.persistence:jakarta.persistence-api:jar:3.1.0:compile
[INFO] |  +- jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.2:compile
[INFO] |  \- com.sun.xml.bind:jaxb-xjc:jar:4.0.5:compile
[INFO] |     \- com.sun.xml.bind:jaxb-core:jar:4.0.5:compile
[INFO] |        \- org.eclipse.angus:angus-activation:jar:2.0.2:runtime
[INFO] +- org.eclipse.persistence:org.eclipse.persistence.extension:jar:4.0.3:compile
[INFO] |  \- org.eclipse.persistence:org.eclipse.persistence.core:jar:4.0.3:compile
[INFO] |     \- org.eclipse.persistence:org.eclipse.persistence.asm:jar:9.7.0:compile
[INFO] +- org.postgresql:postgresql:jar:42.7.3:compile
[INFO] |  \- org.checkerframework:checker-qual:jar:3.42.0:runtime
[INFO] +- com.example:commons-testing:jar:0.0.1:test
[INFO] |  +- org.instancio:instancio-junit:jar:3.6.0:test
[INFO] |  |  \- org.instancio:instancio-core:jar:3.6.0:test
[INFO] |  +- org.junit.jupiter:junit-jupiter-api:jar:5.8.2:test
[INFO] |  |  +- org.opentest4j:opentest4j:jar:1.2.0:test
[INFO] |  |  +- org.junit.platform:junit-platform-commons:jar:1.8.2:test
[INFO] |  |  \- org.apiguardian:apiguardian-api:jar:1.1.2:test
[INFO] |  +- com.opentable.components:otj-pg-embedded:jar:0.13.4:test
[INFO] |  |  +- org.apache.commons:commons-lang3:jar:3.11:test
[INFO] |  |  +- org.apache.commons:commons-compress:jar:1.20:test
[INFO] |  |  +- org.tukaani:xz:jar:1.5:test
[INFO] |  |  +- commons-io:commons-io:jar:2.8.0:test
[INFO] |  |  +- commons-codec:commons-codec:jar:1.15:test
[INFO] |  |  +- com.github.spotbugs:spotbugs-annotations:jar:4.1.2:test
[INFO] |  |  \- org.slf4j:jcl-over-slf4j:jar:1.7.30:test
[INFO] |  +- org.junit.jupiter:junit-jupiter-params:jar:5.8.2:test
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.626 s
[INFO] Finished at: 2024-12-12T12:54:38+01:00
[INFO] ------------------------------------------------------------------------

解决方法

方法1:修正exec-maven-plugin的目标配置

你的插件配置里误用了<goal>exec</goal>,执行Java主类应该用exec:java目标而非exec:exec。修改插件执行配置:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>3.5.0</version>
    <executions>
        <execution>
            <phase>pre-integration-test</phase>
            <goals>
                <!-- 替换为java目标 -->
                <goal>java</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <!-- 移除executable配置,java目标不需要该参数 -->
        <classpathScope>test</classpathScope>
        <cleanupDaemonThreads>false</cleanupDaemonThreads>
        <mainClass>example.Main</mainClass>
    </configuration>
</plugin>

修改后可执行mvn clean test pre-integration-test触发阶段执行,或继续用mvn clean test exec:java手动触发目标。

方法2:显式引入commons-io依赖

虽然依赖树显示commons-io存在于test scope,但它是嵌套在com.example:commons-testing中的传递性依赖,exec-maven-plugin可能未正确加载。直接在pom.xml中显式添加该依赖:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.8.0</version>
    <scope>test</scope>
</dependency>

方法3:修复线程清理导致的类加载问题

EmbeddedPostgres的关闭线程是守护线程,插件默认会清理守护线程,导致类加载器提前销毁触发错误。可以:

  1. 移除<cleanupDaemonThreads>false</cleanupDaemonThreads>配置,让插件默认处理线程;
  2. 在主类中显式关闭EmbeddedPostgres并等待线程结束:
EmbeddedPostgres pg = EmbeddedPostgres.start();
// 执行查询逻辑
pg.close();
// 等待关闭线程完成
Thread.sleep(1000); // 或用CountDownLatch等更可靠的线程同步方式

内容的提问来源于stack exchange,提问作者The 5th column mouse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 14:22:33