Mavenを使ってjarファイルを作成する方法

Mavenでjarファイルを作成する方法

java jar with maven

このチュートリアルでは、Mavenビルドツールの使用方法、単一の実行可能Jarの作成方法、およびプロジェクトの依存関係の処理方法を示します。

使用ツール:

  1. Maven 3.1.1

  2. JDK 1.7

  3. log4j 1.2.17

  4. ジョーダタイム2.5

  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にインポートすると、最終的なプロジェクト構造は次のようになります。

maven-create-a-jar

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

ターゲットフォルダーのフォルダー構造を確認する

maven-create-jar-dependency-jars

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)