在多个项目中共享JAR的最佳方式是什么?

如果您有多个项目都使用同一组JAR库,那么为每个项目反复包含相同的JAR是很繁琐的。 如果我正在处理20个不同的项目,我宁愿没有20个相同的JAR文件集。 让所有这些项目(以及新项目)引用同一组JAR的最佳方法是什么?

我有一些想法,但每个都有一些缺点:

  • 将所有JAR放在一个文件夹中,让每个项目都在该文件夹中查找。
  • 使用Eclipse创建“用户库”并让每个项目引用该用户库。
  • 创建一个引用每个JAR的“库”项目,并让每个项目引用该库项目。

使用Maven或Ivy来处理这些共享jar。 如果您对过多地更改项目持谨慎态度,可以使用Ivy为您管理额外的类路径。


两者都有很好的Eclipse插件:

m2eclipse的

Maven类路径容器http://img229.imageshack.us/img229/4848/mavendependencies.png

IvyDE

IvyDE类路径容器http://img76.imageshack.us/img76/3180/cpnode.jpg

我用过的效果很好。

您会注意到它们都引用工作区的jar,因此删除了复制。


更新 (由评论提示):

我推荐这种方法的原因是我坚信, 声明依赖关系然后手动包含它们会更简单,更清晰。 与此相关的一次性成本很小 – 常春藤比Maven小 – 但从长远来看它确实有回报。

另一个更小的好处是处理传递和冲突的依赖关系。 很容易忘记为什么需要在类路径中使用commons-logging-1.1.jar以及是否需要升级到1.1.1。 而且,引入例如 Hibernate + Annotation + Spring组合所需的所有依赖项也没有多大乐趣。 专注于编程,而不是建设。

信不信由你,你的“乏味”方法可能是最简单,最干净,最耗时的方法。

在跳上maven的潮流之前,你应该考虑做你现在正在做的事情的真正错误。 你提到它很繁琐,你周围有很多jar文件。 我使用Maven在一个大型多模块项目上创建了构建过程,然后在接下来的18个月中不断地与它进行斗争。 相信我这很乏味,周围有很多jar文件。

自从回到Ant并将jar子与使用它们的项目一起提供源代码控制之后,它就变得更顺畅了。

我将一堆jar文件存储在我的机器上的一个目录中,然后当我创建一个新项目或者需要向现有项目添加一个新jar时,它只需要大约30秒:

  • 将jar从JAR_REPO复制到项目lib目录。
  • 将jar添加到build.properties
  • 将jar添加到build.xml中的classpath
  • 添加jar以在Eclipse中构建路径。

在一个项目的过程中,30秒是微不足道的,但这意味着我有一个项目可以从源代码控制中检出,只需工作,无需任何自定义Eclipse配置或Maven安装或用户特定设置。

这种方法为我和我的项目团队节省了大量时间,主要是因为它简单,可靠且易于理解。


更新 :评论提示澄清

@Robert Munteanu:感谢您的反馈和最新评论。 这可能听起来有点争论,但我担心我不能同意你Maven更简单,更清楚,或者从长远来看它会节省你的时间。

从你的post:
“我坚信声明依赖关系然后手动包含它们会更简单明了。与此相关的一次性成本很小 – 常春藤比Maven小 – 但从长远来看它确实有回报。”

Maven为您下载jar文件可能比自己下载更容易,但这是唯一的优势。 否则,Maven并不简单,不够清晰,从长远来看,它的复杂性和局限性将使您付出代价。

明晰

下面的两个依赖声明做同样的事情。 我发现Ant比Maven更清晰。

ant风格:

    

Maven风格:

  log4j log4j ${log4j.version} compile   org.springframework spring ${spring.version} compile  

简单

使用Ant版本,您可以将鼠标hover在$ {log4j.jar}属性上,它将显示jar文件的绝对路径。 您可以搜索compile.classpath的用法。 你需要知道的还有很多。

毫无疑问,Maven比我建议的方法更复杂。 当你开始使用Maven时,这些只是需要回答的一些问题。

  • groupId是什么意思?
  • artifactId是什么意思?
  • jar子从哪里来?
  • jar子现在在哪里?
  • 提供的范围是什么? 谁在提供它?
  • 这个jar文件是如何在我的WAR文件中结束的?
  • 为什么这个依赖项没有版本元素?
  • 我不明白这个错误信息。 这对地球意味着什么?
  • 地球上的那个jar文件来自哪里? 我没有声明。
  • 为什么我的classpath上有相同jar文件的2个版本?
  • 为什么项目不再建造? 自从我上次构建它以来没有任何改变。
  • 如何添加不在Maven存储库中的第三方jar?
  • 再次告诉我从哪里获得Eclipse插件。

传递依赖

“另一个更小的好处是处理传递和冲突的依赖关系。”

根据我的经验,传递依赖性比它们的价值更麻烦。 您最终得到了同一个jar文件的多个版本,最终得到了您不想要的可选jar文件。 我最终声明了所有提供范围以避免麻烦的事情。

长期收益

“专注于编程,而不是建设。”

我同意。 由于回到Ant并将我的jar文件放在源代码管理中,我已经能够花费更少的时间处理构建问题。

这些是我花更少时间做的事情:

  • 阅读可怜的Maven文档。
  • 阅读更差的Codehaus Mojo文档。
  • 设置共享内部存储库。
  • 教育团队成员。
  • 编写Maven插件来填补空白。
  • 尝试解决有缺陷的插件(发布,组装)。
  • 为Maven安装Eclipse插件。
  • 等待插件让我重新控制Eclipse。

无论如何,抱歉长篇大论。 也许现在我已经脱离了我的胸膛,我可以为我漫长而痛苦的Maven经历带来一些关闭。 🙂

这取决于您的需求,但有几个可行的选择。 我的工作使用外部文件夹,所有项目都引用该文件夹,这使得生活更容易在eclipse之外运行构建。 只要您不介意轻微的日食依赖性,用户库就是一种稍微更好的做事方式。 我没有看到它自己的图书馆项目有很多好处,但是如果你有一些所有其他项目已经加载的通用’util’类型项目,你可以把所有外部jar放在那个项目中。

一种方法是将所有jar文件放在机器上的一个位置,在eclipse ide中,定义一个环境变量,比如说LIB_LOCATION指向该目录并让你的项目使用相对于该变量的jar。 这样,只要您正确定义变量,您就可以轻松使用,无需多个jar子,可以跨机器移植。 我一直在为一组体面的大小项目尝试maven,似乎我必须至少和以前一样努力。 插件中的错误和有线行为,m2eclipse和q4eclipse。

您可以编辑“已安装的JRE”以包含JAR文件(“添加外部JAR”),将文件添加到jdk \ jre \ lib \ ext \目录或指定包含其路径的CLASSPATH环境变量。

我推荐“图书馆”项目方法。

但更好的是 – 每个外部jar都有一个单独的lib项目 – 这使您可以跟踪第三方jar之间的deps,并了解在升级依赖项时需要更改的内容。

确保签入这些项目,以便所有用户使用相同版本的第三方库,这样您就可以轻松地重新生成一个版本的软件(在版本控制中使用标签/标签来​​分组哪些项目的版本)

我们已经决定了一种更繁琐的方法,但它允许我们在内部拥有一切,但可能只适用于一小部分开发人员。

每组jar文件都设置为一个Eclipse项目,该项目在jar集之后适当地命名,添加到构建路径中,源jars和javadoc jar在构建路径中的每个jar上正确设置,然后每个项目包含所需的那些库项目那个项目。 然后将生成的多项目工作空间导出为ProjectSet.psf文件,然后可以在原始Eclipse中读入该文件,从而再次引入整个工作空间。 然后我们在CVS中拥有所有上述项目,包括jar文件。

这对我们来说非常好。

如果您在一个更大的组织中,Maven中的依赖项处理可能对您有用。 您应该明确拥有本地文件缓存,这样如果您的互联网连接丢失,整个世界都不会停止。

另请注意,新的Eclipse 3.5出现在这个sommer中,将有一个“Create Runnable Jar”,可以在生成的runnable jar旁边输出所需的jar,并在Manifest中正确设置Class-PAth行。 我希望节省大量时间 – 检查一下。