Reputation: 11087
I'm trying to have mvn exec:exec
(or mvn exec:java
) run my program with a local jar in the classpath. However the jar fails to load:
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)
Running the program directly from the CLI using java
works:
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
Here's the <build>
part of my pom.xml
:
<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>
Could someone tell me how should I edit the pom.xml
such that mvn exec:exec
works like the java
command above?
com.sun.speech.freetts.en.us.cmu_us_slt_arctic.ArcticVoiceDirectory
is a class in cmu_us_slt_arctic.jar
Upvotes: 10
Views: 34589
Reputation: 94
In maven it is possible to include a local jar (which is outside of maven repository) using systemPath. But since the scope is system (for dependencies declared with systemPath), there are few limitations and because of that it only works with exec:java.
For exec:exec, the above solution will not work because maven does not include system scoped dependencies in its generated (runtime) classpath (%classpath) so the solution is to use your own classpath instead of maven generated classpath as shown below.
<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>
Replace local.jar with all the jar files that are required to be present at some fixed location (here project root is assumed, where pox.xml is located). Also note the use of 'project-jar-with-dependencies.jar', in your case it should be target\XpressAudio-1.0-SN APSHOT-jar-with-dependencies.jar.
Upvotes: 6
Reputation: 895
standard java does not allow us to specify multiple -cp
arguments, but exec-maven-plugin
does, so
<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>
note the call to java.pl
above, this is the trick
#!/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;
understand what java.pl
does and use it or do the equivalent in bash, cmd, powershell, whatever..
Upvotes: 3
Reputation: 51
To set additional classpath in maven you should use in your maven configuration file as below:
<additionalClasspathElements>
<additionalClasspathElement>path/to/additional/jar</additionalClasspathElement>
</additionalClasspathElements>
For more detail: http://maven.apache.org/surefire/maven-surefire-plugin/examples/configuring-classpath.html
Upvotes: 1