Как создать файл JAR с Maven

Как создать файл jar с Maven

java jar with maven

В этом руководстве мы покажем вам, как использовать инструмент сборки Maven для создания единого исполняемого файла Jar и как работать с зависимостями проекта.

Используемые инструменты:

  1. Maven 3.1.1

  2. JDK 1,7

  3. log4j 1.2.17

  4. Джода-тайм 2,5

  5. Затмение 4.3

1. Создайте простой Java-проект

Создайте проект Java из шаблона быстрого запуска Maven.

$ 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.

4. Работа с зависимостями

4.1. Как я могу добавить зависимости в банку?

- Вы можете поместить как log4j.jar, так и jodatime.jar в final.jar, но ваши классы не могут вызывать другие классы, которые находятся внутри unpack log4j.jar, Java jar спроектирован таким образом, если вы не создаете специальный загрузчик классов как плагин с одной банкой.

- В качестве альтернативы используйтеmaven-assembly-plugin, чтобы извлечь все jar-файлы зависимостей в необработанные классы и сгруппировать их вместе. Прочтите это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, он создаст файл fat-jar, который включает все зависимости проекта в один файл jar, прочтите эту статью -Create a fat Jar file with Maven

4.2 *Solution*
Решение с одной банкой действительно хорошее, но мне не нравятся пользовательский загрузчик классов и концепция толстой банки. Мое самое простое и всегда работающее решение - скопировать все зависимости проекта в заранее определенную папку и определить путь к классам зависимостей в файле манифеста 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 через системное свойствоlog4j.configuration следующим образом:

$ 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 КБ)

Related