想象一个普通的java maven项目,其Main类生成工件项目-a.jar。该项目依赖于project-b.jar。
是否有Maven插件允许通过类似命令运行该jar?
mvn run-plugin:run org.mygroup:project-a:3.1 <args>
该插件将解析运行时依赖项(使用META-INF / maven /(...)/ pom.xml),将项目及其依赖项安装到本地maven存储库(如果尚未存在),构造类路径并调用
java -cp (...)/project-a-3.1.jar;(...)/project-b-2.1.jar org.mygroup.Main <args>
我知道通常的方法是构建一个包含依赖项的可执行(胖)jar,但这不是我要求的。
实际上,从jar中读取pom甚至不是必需的,因为maven可以从给定坐标的存储库下载它。
为什么这个问题与Maven Run Project问题有所不同:
我不想从已经检查过项目的来源开始。 因此通常使用exec插件不适用。 Maven Run Project问题的OP显然假设存在源代码项目文件夹。她的目的是测试,她接受了一个显然需要一个项目的答案。这两个问题的措辞也是正确的。单词&#34; 项目&#34;之间存在差异和&#34; jar &#34;它们在各自背景下的实际意义完全不同。
答案 0 :(得分:1)
您可以使用appassembler-maven-plugin
插件,它会为您创建一个在类路径中具有依赖关系的shell脚本。下面是一个示例配置
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
<configuration>
<extraJvmArguments>-Xms256m -Xmx1536m</extraJvmArguments>
<programs>
<program>
<mainClass>com.package.MyMainClass</mainClass>
<name>TestFormattingUtils</name>
</program>
</programs>
</configuration>
</plugin>
您可以在.../target/appassembler/bin
中找到输出脚本您可以手动检查脚本,您将看到它正在执行您希望通过命令行将jar添加到类路径的命令类型。即java -jar (...)/project-a-3.1.jar -cp (...)/project-b-2.1.jar <args>
答案 1 :(得分:0)
我也不是罐子里的粉丝,但我确实维护了各种具有很多依赖性的工具。所以,有一次,我决定编写一个可执行的AppBoot
jar,它将来自lib-subdirectory的所有jar放入类加载器中,然后调用所需(可执行)jar的main方法。这个问题促使我调查exec-maven-plugin
是否可以做类似的事情,而且可以。
exec-maven-plugin
不需要“Java项目”目录,但目录中需要pom.xml
。我使用的pom.xml
如下所示,请注意它可以放在任何(空)目录中,并且可以通过在该目录中打开shell /提示并执行mvn exec:exec
来启动应用程序。使用mvn -X exec:exec
查看exec-maven-plugin
使用的类路径。
<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>com.descartes</groupId>
<artifactId>exec-embed-demo</artifactId>
<version>1.2.2-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- Start the demo using Maven repository artifacts, execute with "mvn exec:exec" -->
<properties>
<demo.version>1.2.1.GH</demo.version>
<mainclass>com.descartes.basicjsp.embed.demo.Launch</mainclass>
<appname>${project.artifactId}</appname>
<homedir>${project.basedir}/</homedir>
</properties>
<dependencies>
<dependency>
<!-- exec-maven-plugin will get all required (runtime) jar-files from this dependency. -->
<groupId>com.descartes</groupId>
<artifactId>basic-jsp-embed-demo</artifactId>
<version>${demo.version}</version>
</dependency>
</dependencies>
<build>
<!-- The "outputDirectory" is added to the classpath by the exec-maven-plugin. -->
<!-- Add this pom's directory to the classpath instead of "./target/classes". -->
<!-- The directory should contain "logback.xml" to prevent a million lines of debug output from Tomcat. -->
<outputDirectory>${homedir}</outputDirectory>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<!-- mvn exec:exec configuration -->
<!-- Embedded Tomcat will not stop with "ctrl-c" -->
<!-- Use http://localhost:8080/shutdown instead -->
<configuration>
<executable>java</executable>
<arguments>
<argument>-Dapp.name=${appname}</argument>
<argument>-Dapp.home.dir=${homedir}</argument>
<argument>-Dapp.conf.dir=${homedir}</argument>
<argument>-cp</argument>
<classpath/>
<argument>${mainclass}</argument>
</arguments>
</configuration>
<!-- mvn exec:java configuration -->
<!-- "ctrl-c" stops Tomcat but embedded Tomcat fails to start properly, probably a classloader issue. -->
<!--
<configuration>
<mainClass>${mainclass}</mainClass>
<systemProperties>
<systemProperty>
<key>app.name</key>
<value>${appname}</value>
</systemProperty>
<systemProperty>
<key>app.home.dir</key>
<value>${homedir}/</value>
</systemProperty>
<systemProperty>
<key>app.conf.dir</key>
<value>${homedir}/</value>
</systemProperty>
</systemProperties>
</configuration>
-->
</plugin>
</plugins>
</build>
</project>
AppBoot
是使用嵌入式Tomcat的basic-jsp-embed
项目的一部分,可以找到该项目here(安装,下载最新版本,解压缩zip文件并运行“ mvn install“在多模块项目的根目录下)。
侧面说明:管理jar-set很棘手,使用像jHades这样的工具来验证你不会遇到不同jar文件中同一类的多个版本的麻烦。
答案 2 :(得分:-1)
您正在寻找maven exec plugin。
mvn exec:java -Dexec.mainClass="com.example.Main" [-Dexec.args="argument1"]
会运行你的程序
答案 3 :(得分:-1)
Maven无法做你想做的事情,只是因为一旦将project A
构建到最终的jar中,它就无法解决repositories
的依赖关系。
Maven并没有神奇地从互联网上下载库:它的工作原理是pom.xml
中pom.xml
的定义。没有project A
,就像你似乎建议的那样,它怎么知道从哪里下载库? Maven不是下载工具,它是一个项目管理工具,你所拥有的不再是一个项目,而是一个最终的库。
由于您可以控制maven-assembly-plugin
,因此您应该真正依赖Maven约定并构建胖jar或程序集(使用pom.xml
)。
顺便说一下,位于META-INF
下的pom
文件不能保证存在,事实上,如果你看一下Spring工件,它就不存在了。看一下Maven Archiver documentation:这个addMavenDescriptor
文件的存在是由false
布尔属性控制的。将此属性设置为pom
,您的主工件将不会包含此beginInvoke
文件。