我应该将源文件和类文件打包在同一个JAR文件中吗?

5

分离的Jars

在创建JAR文件时,我一直将源代码分开并作为可选项提供。

例如:

  • Foo.jar
  • Foo-source.jar

这似乎是做事情的明显方式,并且非常普遍。优点如下:

  1. 使二进制jar包保持较小
  2. 源代码可能不是开放/公共的
  3. 对于类加载器来说更快?(我不知道,只是猜测)

单个Jar

我开始怀疑这些优点是否总是值得的。我正在开发一个非常小的开源组件。在这个项目中,我列出的任何优点都不是问题:

  1. 类+源代码仍然非常小(并将保持这种状态)
  2. 源代码是公开的
  3. 此jar的类加载速度无关紧要

然而,将源代码与类放在一起确实带来了新的优点:

  1. 单个依赖项
  2. 没有源代码和类之间版本不匹配的问题
  3. 使用此jar的开发人员将始终拥有手头的源代码(用于调试或检查)

这些新的优点对我来说非常有吸引力。是的,我可以将源代码、类甚至javadoc压缩成一个zip文件,并让我的组件客户端决定他们想要使用哪个(就像Google在guava库中所做的那样),但这真的值得吗?

我知道这有点违反传统的软件工程逻辑,但我认为单个jar文件的优点超过了其他选择。

我错了吗?有更好的方法吗?


1
给用户提供选择的选项。如果您正在使用ant构建,可以轻松生成所有3个jar文件,然后让用户选择他们想要的。让用户拥有自由选择的权利。 - Sean
我认为缺乏选择是一种优势。下载时不会混淆,只有一个可用的下载选项。 - matt burns
5个回答

2
当然值得!只需要花费大约2秒钟时间或几分钟修改构建脚本就可以将源代码、类以及甚至javadoc打包成一个zip文件,让组件的客户自行决定使用哪个(就像Google使用Guava库一样)。
这是大多数分发源代码和二进制文件的人处理此问题的方式。
编辑:
你需要考虑的不是你的观点,而是从部署/使用软件的人的角度来考虑这个问题。
他们不会在部署平台上使用源代码。
因此,在二进制JAR文件中放置源代码是浪费磁盘空间、减慢部署速度和应用程序启动速度。
如果他们想解决这个问题,他们会遇到麻烦。他们如何重新构建JAR文件以摆脱源代码?他们如何知道哪些是安全的可以省略?
从部署者/用户的角度来看,没有任何好处,只有负面影响。
最后,你提到的人们无法跟踪源代码与二进制版本的观点并不正确。大多数对源代码感兴趣的人完全有能力做到这一点。此外,还有一些简单的方法可以解决这个问题,比如使用包括软件版本号的JAR文件名,或将版本号放入清单中。

抱歉,我并不是因为懒得更改构建脚本而说“不值得”,事实上,目前就是这样。我必须更改它以制作单个JAR文件!我也知道大多数项目都是这样的。这也是我通常的工作方式... - matt burns
根据我的情况(在问题中描述),您能告诉我为什么单独的文件更好吗? - matt burns
我会接受这个答案,因为你提出了一些很好的观点,比如减缓部署速度。我也认为这是99%情况下最好的建议。 - matt burns
@Stephen:“这需要大约2秒钟” - 我希望它能够自动化。我试图看看是否可以配置maven-sources-plugin来处理与.class文件相同的.jar文件中的.java文件。 - Ustaman Sangat
@UstamanSangat - 你有没有读完那句话的剩余部分?嗯? - Stephen C

1
我刚刚发现了一个潜在的陷阱,涉及到使用单个jar包中的java类。如果你有java文件在一个jar包中,并且该jar包被包含在后续javac执行的classpath中,你必须确保java文件的时间戳小于class文件的时间戳。这种情况可能会发生在将java或class文件复制/移动到打包成jar之前。如果java文件比class文件更新,那么即使在classpath上找到java文件(而不是javac的参数),javac也会尝试编译该java文件,然后在编译阶段可能会出现重复的class错误。因此,我建议将源代码和class文件分别放在不同的jar包中。注意,在javac中相关的标志不能让你优先选择class而不是源代码。http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#searching

0

有多小才算小?为什么你的jar文件应该和其他文件不同呢?

除非你有充分的理由,例如源码或者特定的调试问题,建议不要这样做,最好选择不带源码的版本。

我之所以这么说是因为,如果你的jar文件与其他文件没有区别,那么你需要做出一个假设,即其他人也应该遵循你的方式。如果是这样的话,jar文件的大小并不重要,因为它会被复制到所有“小”jar文件中。然后我的WAR文件就比实际需要的要大得多了,虽然这不是什么大问题,但在生产环境下我肯定不会选择这种方法,因为我可以轻松地在开发环境中下载源码。


0

我更喜欢“分离的Jars”。

因为二进制类jar是用于在JVM上运行的,但源代码不是。源代码应该由您的源代码控制系统(SVN)进行仔细维护。如果需要发布源代码,请将其压缩到单独的jar中。许多开源项目都会将类jar和源代码jar分开。


当然,源代码仍将在源代码控制下维护。我并不打算将其作为分发源代码的方法,只是为客户提供一个简单的方式来查看相应二进制文件的源代码。 - matt burns

0
如果你想让别人测试和检查/改进你的代码,那么可以将源代码和二进制文件一起提供。如果不需要,就把源代码和 jar 文件分开存放。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接