Mavenでjarファイルを作成する方法
このチュートリアルでは、Mavenビルドツールの使用方法、単一の実行可能Jarの作成方法、およびプロジェクトの依存関係の処理方法を示します。
使用ツール:
-
Maven 3.1.1
-
JDK 1.7
-
log4j 1.2.17
-
ジョーダタイム2.5
-
Eclipse 4.3
1. 簡単なJavaプロジェクトを作成する
MavenクイックスタートテンプレートからJavaプロジェクトを作成します。
$ mvn archetype:generate -DgroupId=com.example.core.utils -DartifactId=dateUtils -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
次のファイルとフォルダー構造が作成されます。
. |____dateUtils | |____pom.xml | |____src | | |____main | | | |____java | | | | |____com | | | | | |____example | | | | | | |____core | | | | | | | |____utils | | | | | | | | |____App.java | | |____test | | | |____java | | | | |____com | | | | | |____example | | | | | | |____core | | | | | | | |____utils | | | | | | | | |____AppTest.java
上記のフォルダ構造では不十分です。log4j.properties
ファイルを作成してsrc/main/resources/log4j.properties
に配置し、リソースフォルダを手動で作成するだけです。
log4j.properties
# Root logger option log4j.rootLogger=DEBUG, stdout # Direct log messages to stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
Eclipseをサポートするようにします。
$ mvn eclipse:eclipse
プロジェクトをEclipse IDEにインポートすると、最終的なプロジェクト構造は次のようになります。
2. Pom.xmlを更新する
pom.xml
を更新して、log4jとjodatimeの両方の依存関係を宣言します。jar
形式に出力するには、パッケージが「jar」に設定されていることを確認してください。 以下のコメントを読んでください。
pom.xml
4.0.0 com.example.core.utils dateUtils jar 1.0-SNAPSHOT dateUtils http://maven.apache.org 1.7 2.5 4.11 1.2.17 junit junit ${junit.version} test joda-time joda-time ${jodatime.version} log4j log4j ${log4j.version} dateutils org.apache.maven.plugins maven-eclipse-plugin 2.9 true false org.apache.maven.plugins maven-compiler-plugin 2.3.2 ${jdk.version} ${jdk.version} org.apache.maven.plugins maven-jar-plugin **/log4j.properties com.example.core.utils.App
3. App.javaを更新する
生成されたApp.java
を次の内容で更新します。
App.java
package com.example.core.utils; import org.apache.log4j.Logger; import org.joda.time.LocalDate; public class App { private static final Logger logger = Logger.getLogger(App.class); public static void main(String[] args) { System.out.println(getLocalCurrentDate()); } private static String getLocalCurrentDate() { if (logger.isDebugEnabled()) { logger.debug("getLocalCurrentDate() is executed!"); } LocalDate date = new LocalDate(); return date.toString(); } }
現在、このプロジェクトにはlog4jとjodatimeの2つの依存関係があります。
4. 依存関係での作業
4.1. jarに依存関係を追加するにはどうすればよいですか?
– log4j.jarとjodatime.jarの両方をfinal.jar内に配置できますが、クラスはunlog log4j.jar内にある他のクラスを呼び出すことができません。特別なクラスローダーを作成しない限り、Java jarはこのように設計されます1 jarプラグインのように。
–または、maven-assembly-plugin
を使用して、すべての依存関係jarをrawクラスに抽出し、グループ化します。 この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.
–one-jar pluginを試してください。プロジェクト全体の依存関係を単一のjarファイルに含むfat-jarが作成されます。この記事を読んでください–Create a fat Jar file with Maven
4.2 *Solution*
1つのjarソリューションは本当に優れていますが、カスタムクラスローダーとfat-jarの概念は好きではありません。 私の最も簡単で常に機能するソリューションは、プロジェクト全体の依存関係を事前定義されたフォルダーにコピーし、jarのマニフェストファイルで依存関係クラスパスを定義することです。
以下は、更新された最後のpom.xml
で、maven-dependency-plugin
を使用してすべての依存関係をtarget/dependency-jars/
フォルダーにコピーし、maven-jar-plugin
を使用して依存関係クラスパスを追加します。
pom.xml
4.0.0 com.example.core.utils dateUtils jar 1.0-SNAPSHOT dateUtils http://maven.apache.org 1.7 2.5 4.11 1.2.17 junit junit ${junit.version} test joda-time joda-time ${jodatime.version} log4j log4j ${log4j.version} dateutils org.apache.maven.plugins maven-eclipse-plugin 2.9 true false org.apache.maven.plugins maven-compiler-plugin 2.3.2 ${jdk.version} ${jdk.version} org.apache.maven.plugins maven-jar-plugin **/log4j.properties true com.example.core.utils.App dependency-jars/ org.apache.maven.plugins maven-dependency-plugin 2.5.1 copy-dependencies package copy-dependencies runtime ${project.build.directory}/dependency-jars/
5.The final Jar file
5.1 Package the project.
$ mvn package
ターゲットフォルダーのフォルダー構造を確認する
dateutils.jar
が作成され、プロジェクトのランタイム依存関係全体(junitを除く)がtarget/dependency-jars/
フォルダーにコピーされます。
5.2 List out the dateutils.jar
content :
$ jar tf target/dateutils.jar META-INF/ META-INF/MANIFEST.MF com/ com/example/ com/example/core/ com/example/core/utils/ com/example/core/utils/App.class META-INF/maven/ META-INF/maven/com.example.core.utils/ META-INF/maven/com.example.core.utils/dateUtils/ META-INF/maven/com.example.core.utils/dateUtils/pom.xml META-INF/maven/com.example.core.utils/dateUtils/pom.properties
5.3 Extracts and review the content of MANIFEST.MF
, the dependencies are added in the Class-Path
.
META_INF/MANIFEST.MF
Manifest-Version: 1.0 Built-By: example Build-Jdk: 1.7.0_05 Class-Path: dependency-jars/joda-time-2.5.jar dependency-jars/log4j-1.2.17.jar Created-By: Apache Maven 3.1.1 Main-Class: com.example.core.utils.App Archiver-Version: Plexus Archiver
5.4 Run it
$ java -jar target/dateutils.jar log4j:WARN No appenders could be found for logger (com.example.core.utils.App). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. 2014-10-19
Oppss…
5.5 Where is log4j.properties
?
This is a GOOD practice to exclude the log4j.properties
in the jar file, to avoid issues like multiple log4j.properties
files in classpath.
次のように、log4j.configuration
システムプロパティを介してlog4jプロパティを渡すことができます。
$ java -jar -Dlog4j.configuration=file:/full_path/log4j.properties target/dateutils.jar 17:09:15,385 DEBUG App:18 - getLocalCurrentDate() is executed! 2014-10-19
Note
将来、dateUtils.jar
を移動する場合は、そのdependency-jars
フォルダーもコピーしてください。 あなたがより良いアイデアを持っているなら、私と共有してください、ありがとう。
完了しました。
ソースコードをダウンロード
ダウンロード–maven-create-a-jar.zip(7 KB)