在Maven中使用依赖项和测试生成jar文件 [英] Generate jar file in Maven with dependencies and tests
问题描述
我在pom.xml中使用此代码来创建一个jar文件.
I use this code in pom.xml to create a jar file.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/log4j.properties</exclude>
</excludes>
<archive>
<manifest>
<mainClass>test.LeanFTest</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
我收到错误消息:
部署失败:未在POM中指定存储库元素 内部分布
Deployment failed: repository element was not specified in the POM inside distribution
更新:
我在pom.xml中添加了另一个插件.
I added another plugin in pom.xml.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>test.LeanFTest</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
它生成一个jar文件,但似乎没有依赖项.
It generates a jar file, but seemly without dependencies.
线程主"中的异常java.lang.NoClassDefFoundError: org/apache/log4j/Logger
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger
项目结构:
C:.
├───.idea
│ └───libraries
├───META-INF
├───out
│ └───artifacts
│ └───Test_LeanFT_jar
├───resources
│ ├───leanftjar
│ └───META-INF
├───RunResults
│ └───Resources
│ ├───Snapshots
│ └───User
├───src
│ ├───main
│ │ ├───java
│ │ │ ├───com
│ │ │ │ └───myproj
│ │ │ ├───jar
│ │ │ │ └───META-INF
│ │ │ ├───META-INF
│ │ │ ├───unittesting
│ │ │ └───utils
│ │ └───resources
│ └───test
│ └───java
│ └───test
├───target
│ ├───classes
│ │ ├───com
│ │ │ └───myproj
│ │ ├───unittesting
│ │ └───utils
│ ├───generated-sources
│ │ └───annotations
│ ├───generated-test-sources
│ │ └───test-annotations
│ ├───maven-archiver
│ ├───maven-status
│ │ └───maven-compiler-plugin
│ │ ├───compile
│ │ │ └───default-compile
│ │ └───testCompile
│ │ └───default-testCompile
│ ├───surefire
│ ├───surefire-reports
│ │ ├───Command line suite
│ │ ├───junitreports
│ │ └───old
│ │ └───Command line suite
│ └───test-classes
│ └───test
└───test-output
├───All Test Suite
├───junitreports
├───My_Suite
└───old
├───All Test Suite
└───My_Suite
pom.xml
文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>groupId</groupId>
<artifactId>LeanFT</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Mytest</name>
<description>Regression test</description>
<properties>
<leanftsdk>C:/Program Files (x86)/HPE/Unified Functional Testing/SDK/Java/</leanftsdk>
<maven.test.skip>true</maven.test.skip>
</properties>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>com.hp.lft</groupId>
<artifactId>sdk</artifactId>
<version>14.0.0</version>
<scope>system</scope>
<systemPath>${leanftsdk}/com.hp.lft.sdk-standalone.jar</systemPath>
</dependency>
<dependency>
<groupId>com.hp.lft</groupId>
<artifactId>report</artifactId>
<version>14.0.0</version>
<scope>system</scope>
<systemPath>${leanftsdk}/com.hp.lft.report.jar</systemPath>
</dependency>
<dependency>
<groupId>com.hp.lft</groupId>
<artifactId>unittesting</artifactId>
<version>14.0.0</version>
<scope>system</scope>
<systemPath>${leanftsdk}/com.hp.lft.unittesting.jar</systemPath>
</dependency>
<dependency>
<groupId>com.hp.lft</groupId>
<artifactId>verifications</artifactId>
<version>14.0.0</version>
<scope>system</scope>
<systemPath>${leanftsdk}/com.hp.lft.verifications.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.10</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>appmodels</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>test.LeanFTest</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
推荐答案
我的解决方案是构建一个归档文件(zip或其他格式),该归档文件将您的类包含在jar中,依赖项jar,带有运行时配置文件和脚本的文件夹中启动应用程序.范围是仅通过解压缩存档来拥有可运行的应用程序.
My solution is to build an archive (zip or other formats) that contains your classes in a jar, the dependencies jars, a folder with runtime configuration files and scripts to launch the application. The scope is to have a run ready application just by unzipping the archive.
构建的存档内容为:
artifactId-version.zip:
<artifactId folder>
├─ config
| ├─ log4j2.xml
├─ lib
| ├─ <all dependencies jars>
├─ leanft.cmd
├─ leanft.sh
└─ artifactId-version.jar
您应该根据需要/如果需要配置文件来定制解决方案.您不需要带有MANIFEST.MF文件的META-INF文件夹,因为它将由maven插件自动生成.
You should tailor the solution based on what/if you need configuration files. You don't need the META-INF folders with MANIFEST.MF files because will be generated automatically by maven plugin.
<maven_module_root>
├─ src
| ├─ main
| | ├─ assembly
| | | ├─ leanft-assembly.xml
| | ├─ java
| | | ├─ <your classes content>
| | ├─ resources
| | | ├─ log4j2.xml
| | | ├─ <your runtime configuration files>
| | ├─ scripts
| | | ├─ leanft.cmd
| | | ├─ leanft.sh
│ └───test
├─ pom.xml
项目结构与您当前的结构相似,但有两个附加文件夹:
-程序集:此文件夹中的leanft-assembly.xml用于自定义maven-assembly-plugin.
-脚本:在此文件夹中是您的应用程序的启动器脚本.如果您需要可用于编辑的运行时配置文件,则这是必需的.在我的示例中,resources/log4j2.xml将位于配置文件中,因此用户无需触摸任何jar/存档即可编辑该文件.
The project structure is similar with your current structure with two additional folders:
- assembly: in this folder is the leanft-assembly.xml to customize the maven-assembly-plugin.
- scripts: in this folder are the launcher scripts for your application. This is necessary it if you need to have runtime configuration files available for edit. In my example, the resources/log4j2.xml will be in a config file so the user can edit this file without touching any jar/archive.
该解决方案基于具有自定义配置的Maven程序集插件.我建议您从描述符程序集描述符开始熟悉它
The solution is based on maven assembly plugin with custom configuration. I recommend to get familiar with it, starting with descriptor assembly descriptor
您的leanft-assembly.xml看起来像:
Your leanft-assembly.xml could look like:
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>dist</id>
<formats>
<!-- <format>tar.gz</format> -->
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<baseDirectory>${project.artifactId}</baseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>${project.artifactId}-${project.version}.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/lib</directory>
<outputDirectory>/lib</outputDirectory>
<includes>
<include>*.*</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>/config</outputDirectory>
<includes>
<include>log4j2.xml</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.basedir}/src/main/scripts</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>leanft.*</include>
</includes>
</fileSet>
</fileSets>
</assembly>
Maven pom
最后,pom.xml使用3个插件:
Maven pom
Finally, the pom.xml make use of 3 plugins:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteIfNewer>true</overWriteIfNewer>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>test.LeanFTest</mainClass>
</manifest>
</archive>
<excludes>
<exclude>log4j2.xml</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<finalName>${project.artifactId}-${project.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/leanft-assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
我将解释Maven插件的用法:
-maven-dependency-plugin:在软件包阶段将所有依赖项复制到目标文件夹下的lib文件夹中.
-maven-jar-plugin:
-存档:生成清单文件,在清单中定义lib文件夹中的所有依赖关系以及主要类是什么,以便您也可以使用"java -jar"运行该应用程序.
-排除:不要在模块jar中包含log4j2.xml文件,因为它将在运行时从jar外部的config文件夹中提供.
-maven-assembly-plugin:在软件包阶段创建一个包含您的发行版的zip文件.归档文件放置在目标文件夹中.描述符标记引用您的程序集配置文件leanft-assembly.xml.
I will explain the usage of maven plugins:
- maven-dependency-plugin: copy all dependencies at package phase in a lib folder under the target folder.
- maven-jar-plugin:
- archive: generate manifest file, define in manifest all dependencies from the lib folder and what is the main class so you can run the application also with "java -jar"
- excludes: don't include the log4j2.xml file in the module jar because will be in config folder available at runtime from outside jar.
- maven-assembly-plugin: create at package phase a zip file that contains your distribution. The archive is placed in target folder. The descriptor tag reference your assembly configuration file leanft-assembly.xml.
用于启动应用程序的脚本使用预定义的参数调用Java,脚本的主要内容为:
The script to launch the application call java with predefined parameters, the main line from script being:
%JAVA_HOME%\bin\java %JVM_ARGS% -cp %SCRIPT_DIR%\*;%SCRIPT_DIR%\config\ test.LeanFTest
这篇关于在Maven中使用依赖项和测试生成jar文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!