在多个项目中共享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行。 我希望节省大量时间 – 检查一下。