如何为mvn exec:exec设置classpath?

9

我想通过mvn exec:exec(或 mvn exec:java)命令在classpath中加载本地jar文件并运行程序。但是该jar文件加载失败:

Exception in thread "main" java.lang.Error: Unable to load voice directory. java.lang.ClassNotFoundException: com.sun.speech.freetts.en.us.cmu_us_slt_arctic.ArcticVoiceDirectory
at com.sun.speech.freetts.VoiceManager.getVoiceDirectories(VoiceManager.java:211)
at com.sun.speech.freetts.VoiceManager.getVoices(VoiceManager.java:111)
at com.sun.speech.freetts.VoiceManager.getVoice(VoiceManager.java:521)
at xpress.audio.TTS.<init>(TTS.java:66)
at xpress.audio.TTS.<init>(TTS.java:62)
at xpress.audio.AudioProducer.main(AudioProducer.java:18)

从CLI直接使用java运行程序是可以的:
    C:\XpressAudio\target\classes>java -cp "C:\XpressAudio\target\XpressAudio-1.0-SN
APSHOT-jar-with-dependencies.jar;C:\XpressAudio\cmu_us_slt_arctic.jar;C:\XpressA
udio\en_us.jar;C:\XpressAudio\*" xpress.audio.AudioProducer

这是我的pom.xml文件中与构建有关的<build>部分:
 <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <executable>java</executable>
                    <mainClass>xpress.audio.AudioProducer</mainClass>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>cmu_us</groupId>
                        <artifactId>slt_arctic</artifactId>
                        <version>1.0</version>
                        <scope>system</scope>
                        <systemPath>${basedir}/cmu_us_slt_arctic.jar</systemPath>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

请问有人能告诉我如何编辑pom.xml文件,使得mvn exec:exec的执行效果类似于上述的java命令吗?

com.sun.speech.freetts.en.us.cmu_us_slt_arctic.ArcticVoiceDirectorycmu_us_slt_arctic.jar中的一个类。


你应该使用Java Mojo而不是Exec Mojo,并查看其中列出的选项:http://mojo.codehaus.org/exec-maven-plugin/java-mojo.html。特别是executableDependency,includePluginDependencies和includeProjectDependencies。 - Tome
3个回答

5

Maven中,使用systemPath可以将本地JAR包(不在Maven仓库中的)包含进来。但是由于依赖于系统(使用systemPath声明的依赖),存在一些限制,因此只能在exec:java中使用。

对于exec:exec,上述解决方案将不起作用,因为Maven不会在生成的(运行时)类路径(%classpath)中包含系统范围的依赖项,所以解决方案是使用自己的类路径,如下所示。

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.2.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>exec</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <executable>java</executable>
                <arguments>
                     <argument>-classpath</argument>
                     <argument>local.jar;target/project-jar-with-dependencies.jar</argument>
                     <argument>xpress.audio.AudioProducer</argument>
                </arguments>
            </configuration>
        </plugin>

将local.jar替换为所有需要存在于某个固定位置(这里假设项目根目录,即pox.xml所在位置)的jar文件。还要注意使用'project-jar-with-dependencies.jar',在您的情况下应该是target\XpressAudio-1.0-SNAPSHOT-jar-with-dependencies.jar。


这个<plugin>...</plugin>块应该放在哪个部分?我尝试将其添加到<build><plugins>...中,以将目录/etc/hbase/conf添加到类路径中,但似乎没有任何效果。 - Ken Williams
2
如果您想在exec:exec中同时使用依赖项和本地路径,这是否可能? - niken

3

标准的Java不允许我们指定多个-cp参数,但是exec-maven-plugin允许,因此:

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.2.1</version>
    <executions>
      <execution><goals><goal>exec</goal></goals></execution>
    </executions>
    <configuration>
      <executable>./java.pl</executable>
      <arguments>
        <argument>-ea</argument>
        <argument>-cp</argument><argument>.</argument>
        <argument>-cp</argument><argument>my.jar</argument>
        <argument>-cp</argument><classpath/>
        <argument>org.example.ConfigByXml</argument>
      </arguments>
    </configuration>
  </plugin>

请注意上面对java.pl的调用,这是关键。
#!/usr/bin/env perl
while (@ARGV) {
    $arg = shift;
    if ($arg eq '-cp' or $arg eq '-classpath') {
        push @cp, shift;
        next;
    }
    push @args, $arg;
}
unshift @args, 'java', '-cp', join(':', @cp);
# print 'args: ', join(' --- ', @args); # uncomment to debug
exec @args;

理解 java.pl 的作用并使用它,或者在bash、cmd、powershell等环境中执行相应操作。


0

5
Surefire是用于运行单元测试的插件。问题涉及使用exec插件在运行时添加额外的jar包,因此按照您所描述的修改POM将不起作用。从您提供的链接中,“surefire插件按照以下顺序构建测试类路径”。 - Steven Magana-Zook
4
这个答案提供了关于maven-surefire-plugin的链接,并展示了一个合适的例子来扩展类路径。exec-maven-plugin也支持它,但没有提供示例,可以参考http://www.mojohaus.org/exec-maven-plugin/java-mojo.html#additionalClasspathElements。 - Konstantin Pelepelin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接