[Note]把Spring web app用java main執行並包成可執行jar檔/Extract Spring Web App to a Executable Jar File Run by Main Method

如何使用Maven包出一個Executable jar,並且加入class path。

原本指令(沒有MANIFEST版本)java -cp yourJarFile.jar:lib/* full.qualified.className
後來覺得應該把class path 包在MANIFEST裡面

所以一開始try one jar:

看這篇(one jar 行不通的原因)
4.1. How can I add dependencies in a jar?

– You can put both log4j.jar and jodatime.jar inside the final.jar, but your classes are unable to call other classes which is inside the unpack log4j.jar, Java jar is designed like this, unless you create a special class loader like one-jar plugin.

– Alternatively, use maven-assembly-plugin to extract all dependency jars into raw classes, and group it together. Read this StackOverflow thread. This hack is workable in project with less dependencies only, for large project with many dependencies, it will cause Java class name conflict issue.

– Try one-jar plugin, it will create a fat-jar, which includes the entire project’s dependencies into a single jar file, read this article – Create a fat Jar file with Maven
http://www.mkyong.com/maven/how-to-create-a-jar-file-with-maven/
他有提到Maven-assembly-plugin有hack
會把jar抽成.class files (參考:http://stackoverflow.com/questions/1729054/including-dependencies-in-a-jar-with-maven)
但我碰到一個問題,.class檔會缺,可以用scope:runtime解決,但還會遭遇到其他問題。
one-jar plugin 沒有試過 看起來是會給你用一個新的class loader(http://www.mkyong.com/maven/maven-create-a-fat-jar-file-one-jar-example/ 這篇有 com/simontuffs/onejar/JarClassLoader$1.class)

最終採用solution:
一個runnable jar + dependency library folder + Class-Path in MANIFEST.MF
參考:http://www.mkyong.com/maven/how-to-create-a-jar-file-with-maven/
第四點 4. Working with Dependencies

package指令:mvn package
執行指令:java -jar target/yourJarFile.jar

pass system property to jar file http://stackoverflow.com/questions/29811377/how-to-pass-system-properties-to-a-jar-file
指令:java -Dyour.system.prop=value -jar target/yourJarFile.jar

 

設定方式:

Main.java

public static void main(String[] args) {

/**
* Prepare JNDI context
*
* You MUST call this method at the beginning of every main method.
*/
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
ExecutorService es = Executors.newFixedThreadPool(5);
builder.bind("java:jboss/ee/concurrency/executor/default", es);
try {
builder.activate();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}

/**
* Load application context file
*/
@SuppressWarnings("resource")
ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");

YourBean bean = appContext.getBean(YourBean.class);

bean.doSomething();

}

<

pre>pom.xml:

<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
...
<packaging>jar</packaging>
...
<build>
<!-- package方式:mvn package -->
<plugins>
<!-- Make this jar executable -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>full.qualified.className</mainClass>
<classpathPrefix>dependency-jars/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>

<!-- Copy project dependency -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/dependency-jars/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
...
</dependencies>
</project>

 

Ref:
http://www.mkyong.com/maven/how-to-create-a-jar-file-with-maven/
http://www.mkyong.com/maven/maven-create-a-fat-jar-file-one-jar-example/
http://stackoverflow.com/questions/1729054/including-dependencies-in-a-jar-with-maven
http://stackoverflow.com/questions/29811377/how-to-pass-system-properties-to-a-jar-file

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s