打包并运行具有spring依赖关系的Java应用程序

时间:2009-02-19 09:26:38

标签: java spring ant build-process packaging

我构建了一个独立的Java应用程序,它有一堆依赖项(Apache Commons libs等)以及对Spring框架的依赖,而Spring框架又有一堆依赖项。

我在Eclipse中构建了它,它运行良好。现在我需要将它部署到生产中,所以我试图找出用所有依赖项打包它的最佳方法,以及如何调用它(它将从命令行调用)。

蛮力的方式是将我的项目导出为jar,找到所有依赖的jar(及其依赖项!),将它们复制到公共目录,编写一个包含类路径中每个项目的shell脚本并运行它。显然这看起来很愚蠢。

我应该使用Ant,Maven吗?我应该将所有依赖的Spring jar包装成一个大文件吗?处理此问题的任何提示都会有所帮助。

10 个答案:

答案 0 :(得分:4)

Java部署在2009年仍然是愚蠢和乏味的。所以通常的选择是编写这个小脚本。如果将所有JAR放入一个目录(例如lib\),则可以使用自动构建类路径的公共脚本(请参阅this blog entry)。我建议在开头添加cd /d %~dp0以进入脚本的目录。

Maven 2有一个插件,可以将你的应用程序组装成一个“超级JAR”(mvn assembly:assembly)。除非您使用DB2 JCC驱动程序(其中包含转换为com.ibm的“COM.ibm。”包。 - > ClassNotFoundException),否则此方法有效。

最后一个解决方案,如果你已经有一个有效的ANT build.xml,那就是解压所有相关的JAR并自己创建一个“超级JAR”。

答案 1 :(得分:2)

使用Ant,您可以执行以下操作:

  1. 将所有依赖项组合在一起。
  2. 使用您的应用程序打包JAR文件,并在jar中嵌入对MANIFEST.MF文件中具有“Class-Path”-directive的依赖项的引用。这应该消除了在启动时构建类路径的需要。
  3. 将它们作为存档捆绑在一起,然后分发它。使用“java -jar your.jar”直接运行jar就足够了。
  4. 为了管理您的依赖项,您可以使用Ivy。与Maven非常相似,它能够在构建时从您配置的任何存储库中检索依赖项,包括Maven存储库或您自己的私有存储库。

答案 2 :(得分:1)

我们发现依赖管理和打包的最佳解决方案是将Maven与Assembly插件一起使用。这提供了一种非常优雅的方法来将项目打包,以及所有运行时依赖项和支持脚本到二进制分发中。使用程序集的最大优点之一是可以根据需要将项目拆分为不同的组件。如果您正在使用Spring Integration,那么您可以将多个组件拆分为多台计算机。汇编插件允许您根据需要进行配置。

答案 3 :(得分:1)

所有这些Maven爱,没有人提到常春藤?哦,亲爱的!

嗯,这里是Ant Ivy,而这里是comparison to Maven2。几乎每个人都在建议之前,请先看看它。

答案 4 :(得分:0)

您可以使用正确设置类路径的启动器。然后,您可以更灵活地打包JAR。你可以轻松地将它们全部放在一个目录中,这比创建一个“混蛋”的ueber jar要干净得多......

其中一个发射器是commons-launcher

答案 5 :(得分:0)

我们正在使用带有m2eclipse插件的Maven 2;效果很好。插件有一个依赖图表视图,会显示冲突等。

现在,如果您想将所有依赖项打包到单个jar中,可以查看Jar Jar Links(不开玩笑!)。

答案 6 :(得分:0)

如果您制作JAR可执行文件并添加包含ClassPath的清单,则很多问题都会消失。不幸的是,你必须将JAR及其依赖项压缩在一起,但是你的CLASSPATH问题会得到解决。

创建OSGi包怎么样?我自己还没有看过它,但它应该是打包Java应用程序的下一个东西。它用在像Spring的dm Server这样的应用服务器上。也许它也可以帮助你。

答案 7 :(得分:0)

在我的ANT构建脚本中,我生成* .bat和* .sh启动脚本,其中包含基于构建的lib目录内容在构建时动态构建的JAR列表。

例如,要创建具有适当分隔符的jar列表:

<path id="jar-classpath">
    <fileset dir="${build.war.dir}/WEB-INF/lib">
        <include name="**/*.jar" />
    </fileset>
</path>

<pathconvert refid="jar-classpath" targetos="unix" property="exec.classpath.unix">
       <map from="${build.war.dir}\WEB-INF\lib\" to="../lib/"/>
</pathconvert>

<pathconvert refid="jar-classpath" targetos="windows" property="exec.classpath.windows">
        <map from="${build.war.dir}\WEB-INF\lib\" to="../lib/"/>
</pathconvert>

然后,您可以在java调用脚本中使用${exec.classpath.unix}${exec.classpath.windows}值。

答案 8 :(得分:0)

maven-assembly-plugin可能不是最佳选择。你应该看看onejar-maven-plugin,如下所述:

http://blog.jayway.com/2009/03/22/executable-jar-with-onejar-maven-plugin/

它允许你所有的依赖jar都保留jar,你的代码在你自己的jar中。所有这些罐子放在一个更大的罐子里,这个罐子是可执行的。

答案 9 :(得分:0)

您也可以使用Gradle,以下是如何在那里完成的:

mainClassName = "my.App"

task runnableJar(type: Jar, dependsOn: [':assemble']) {
    from files(sourceSets.main.output.classesDir)
    from files(sourceSets.main.output.resourcesDir)
    from configurations.runtime.asFileTree.files.collect { zipTree(it) }

    manifest {
        attributes 'Main-Class': mainClassName
    }
}