2011-01-10 22 views
8

为什么这是一个坏主意提交Java的jar文件到存储库(CVS,SVN ..)Java的jar文件到存储库(CVS,SVN ..)

+0

请问您是否可以澄清,如果您正在讨论由您自己的源代码生成的第三方罐子或罐子? – 2011-01-10 16:52:52

+0

两者。从我们拥有的源和第三方/开源jar文件生成的jar文件。 – Neel 2011-01-10 16:55:57

+1

这可以永远辩论,我的首选是包括jar和不使用依赖引擎,因为他们只是为一个难以置信的简单问题管理引入另一层复杂性。 – Randyaa 2011-01-10 17:17:06

回答

8

因为你可以从源头上重建它们。如果您正在讨论项目所需的第三方JAR文件,那么最好将它们提交到存储库中,以便该项目是独立的。

+7

对于依赖关系,解决方案不在SCM中,而是在使用依赖管理工具(如Ivy或Maven)中,以便在SCM中定义它们的定义,而在其他地方使用有效的JAR。 – Riduidel 2011-01-10 16:35:59

3

它们是二进制文件:

  • 最好是引用来源,因为这是你使用的是什么源控制了。
  • 系统无法告诉您文件之间的差异
  • 如果它们是从同一个存储库中的源代码编译的,它们将成为合并冲突的来源。
  • 某些系统(如SVN)对大型二进制文件处理不好。

换句话说,更好地引用源代码,并调整您的构建脚本以使一切正常。

2

将jar文件提交给SCM的决定通常受使用的构建工具的影响。如果以传统方式使用Maven,那么你并没有真正的选择。但是如果您的构建系统允许您选择,我认为将您的依赖关系提交给SCM以及取决于它们的源代码是一个好主意。

这适用于与您的项目分开发布周期的第三方罐子和内部罐子。例如,如果你有一个包含公共实用类的内部jar文件,我会在每个使用它的项目下将它提交给SCM。

如果使用CVS,请注意它不能有效地处理二进制文件。 SVN存储库不会区分二进制文件和文本文件。

http://svnbook.red-bean.com/en/1.5/svn.forcvs.binary-and-trans.html

更新响应张贴由Mark答案:

WRT圆点1:我会说这是不是很常见的,甚至大型项目有数百依赖。无论如何,磁盘使用率(通过在每个使用它的项目中保留一个依赖项的副本)不应该成为您的主要关注点。与处理Maven存储库复杂性所花费的时间相比,磁盘空间便宜。无论如何,本地Maven仓库将消耗比实际使用的依赖关系更多的磁盘空间。

项目符号3:Maven不会节省您等待网络流量的时间。事实恰恰相反。通过源代码管理中的依赖关系,您可以执行结帐,然后从一个分支切换到另一个分支。你很少需要再次结账相同的罐子。如果你这样做,它只需要几分钟。 Maven是一个缓慢构建工具的主要原因是即使在没有需要的情况下,它也可以执行所有的网络访问。

Bullet Point 4:你的观点不是反对在SCM中存储jar的争论,Maven只有在你学会了它之后才会很容易,它只是在出现问题时才有效。然后变得困难,你的效率收益可能会很快消失。就效率而言,Maven在事情正常时有一个小的好处,当它没有时会有很大的缺点。

Bullet Point 5:像SVN这样的版本控制系统不会为每个文件的每个版本保留一个单独的副本。它将它们有效地存储为增量。您的SVN存储库很可能会增长到“难以管理”的大小。

子弹点6:你这里的点不是反对存储文件的论点是SCM。您提到的用例可以通过自定义Ant构建轻松处理。

4

源代码管理系统设计用于保存文本源代码。他们可以保存二进制文件,但这不是他们设计的。在某些情况下,将二进制文件放在源代码管理中是有道理的,但通常以不同的方式更好地管理Java依赖项。

理想的设置是让您在源代码管理之外管理您的依赖项。你应该能够在源代码之外管理你的依赖关系,并简单地从源代码中“指向”所需的依赖关系。这有几个优点:

  • 你可以有一些依赖于相同的二进制项目不保持每个二进制的单独副本。一个中等规模的项目有数百个依赖的二进制文件是很常见的。这会导致大量的重复,浪费本地和备份资源。
  • 版本的二进制文件可以在您的本地环境或企业实体内集中管理。
  • 在许多情况下,源控制服务器不是本地资源。添加一堆二进制文件会减慢速度,因为它会增加需要通过较慢连接发送的数据量。
  • 如果您正在创建一场战争,可能会有一些需要进行开发的jar,但不包括部署,反之亦然。良好的依赖管理工具可以让您轻松高效地处理这些类型的问题。
  • 如果您依赖于来自另一个项目的二进制文件,它可能会频繁更改。这意味着你可以不断用新版本覆盖二进制文件。由于版本控制将保留每个副本,因此它可能会迅速增长到无法管理的大小 - 尤其是如果您有任何类型的持续集成或自动构建脚本来创建这些二进制文件。
  • 依赖关系管理系统为您如何依赖二进制文件提供了一定程度的灵活性。例如,在本地计算机上,当它位于文件系统上时,可能需要依赖最新版本的依赖项。但是,当您部署应用程序时,需要将依赖项打包为jar并包含在文件中。

Maven的依赖关系管理功能为您解决了这些问题,并可帮助您根据需要查找和检索二进制依赖项。常春藤是另一个工具,也是这样做的,但对于Ant来说。

7

所以,你有一个使用一些外部依赖的项目。这种依赖性是众所周知的。他们都有

  • A组(通常,组织/锐意创建它们)
  • 的标识符(自己的名字)
  • 一个版本

在Maven的术语,这些信息被称为神器(你的Jar)坐标。我所讨论的依赖关系是内部的(对于Web应用程序,它可以是你的服务/域层)或外部的(log4j,jdbc驱动程序,Java EE框架,你的名字,...)。所有这些依赖关系(也称为构件)实际上都处于其最低级别,即CVS/SVN/GIT无法有效存储的二进制文件(JAR/WAR/EAR)。事实上,SCM使用版本化内容的假设,即差异化操作效率最高的内容)仅为文本。因此,当存储二进制数据时,它们很少存储优化(与仅存储版本差异的文本相反)。

因此,我倾向于建议您使用依赖管理构建系统,如maven,IvyGradle。使用这样一个工具,你将会在你的SCM文件(或者XML文件)中声明你的所有依赖关系(事实上,在这个文件中,你将声明你的依赖关系的工件坐标)。但你的依赖关系不在SCM中。相反,每个开发人员都将在开发机器上下载它们。

这会将一些网络负载从SCM服务器转移到互联网(该带宽通常比内部企业网络更受限制),并询问工件的长期可用性问题。这两个答案都得到了解决(至少在很多工作中,但我相信常春藤和Gradle能够连接到这样的工具 - 而且似乎有人在这个问题上提出了一些问题)使用企业代理,如Nexus,Artifactory和其他。

这些工具的美妙之处在于,它们在内部网络中提供了所有必需工件的视图,尽可能让您在这些存储库中部署自己的工件,从而使您的代码的共享变得轻松而独立来源(这可能是一个优势)。

总结这个长答复:使用Ivy/Maven/Gradle而不是简单的Ant构建。这些工具将允许您定义您的依赖关系,并完成下载这些依赖项的所有工作,并确保您使用声明的版本。在我个人的笔记中,我发现这些工具的那一天,我对Java中依赖关系处理的想法是从噩梦到天堂,因为我现在只需要说我使用这个工具的非常版本,而maven(在我的情况),做所有下载它并存储在我的计算机上的正确位置的后台工作。