在Java程序中包含第三方jar文件的最佳实践是什么?

在Java程序中包含第三方jar文件的最佳实践是什么?,java,jar,dependencies,classpath,packaging,Java,Jar,Dependencies,Classpath,Packaging,我有一个需要几个第三方库的程序,目前它是这样打包的: zerobot.jar (my file) libs/pircbot.jar libs/mysql-connector-java-5.1.10-bin.jar libs/c3p0-0.9.1.2.jar zerobot.jar(我的文件) libs/pircbot.jar libs/mysql-connector-java-5.1.10-bin.jar libs/c3p0-0.9.1.2.jar 据我所知,处理第三方LIB的“最佳”方法是将它

我有一个需要几个第三方库的程序,目前它是这样打包的:

zerobot.jar (my file) libs/pircbot.jar libs/mysql-connector-java-5.1.10-bin.jar libs/c3p0-0.9.1.2.jar zerobot.jar(我的文件) libs/pircbot.jar libs/mysql-connector-java-5.1.10-bin.jar libs/c3p0-0.9.1.2.jar 据我所知,处理第三方LIB的“最佳”方法是将它们放在jar文件清单中的类路径上,这将跨平台工作,不会减慢启动速度(捆绑它们可能会),也不会遇到法律问题(重新打包可能会)

问题在于那些自己提供第三方库的用户(例如用例,升级它们以修复bug)。其中两个库在文件中有版本号,这增加了麻烦

我目前的解决方案是,我的程序有一个引导过程,它生成一个新的类加载器,并使用它正确地实例化程序。这个自定义类加载器将lib/中的所有.jar文件添加到其类路径中

我目前的方法工作得很好,但我现在的应用程序中有两个自定义类加载器,最近对代码的一次更改导致了难以调试的问题,因此如果有更好的方法,我希望消除这种复杂性。我确信这是一种非常普遍的情况,这似乎也是过度工程


所以我的问题是,我应该怎么做呢?

您可以尝试Fat-Jar解决方案,它与“”完美配合。我已经用了几个项目没有任何问题。它的原理似乎与您当前的解决方案相同。

我们为jar提供脚本文件。例如,some.bat、some.sh等

从Java6开始,您可以使用通配符来指定类路径


这里有一篇很好的文章解释了这种方法:

我想我要走清单路线。在清单中声明条目jar的类路径,并包含以下条目:

libs/pircbot.jar libs/mysql-connector-java-5-bin.jar libs/c3p0.jar libs/pircbot.jar libs/mysql-connector-java-5-bin.jar libs/c3p0.jar 然后,如果用户想要升级到最新的库版本,他们必须重命名它们以匹配清单中声明的内容。我不认为这是一个太大的麻烦,它使事情在内部简单得多


我通常也不喜欢在./lib/中自动加载所有内容,这似乎有潜在的危险。

如果你的读者是技术型的(如果他们愿意加入新的jar文件,听起来他们是技术型的),那么你也许可以提供.sh和.bat文件,他们可以编辑这些文件来修改类路径?对他们来说,这将比定制类加载器更加透明。

@zweisteinen:他想跨平台。Java6意味着你将从OSX用户群的很大一部分中脱离出来,而这些用户群拥有的Mac永远不会正式拥有Java6(32位CPU Mac)。对于这个项目来说,OSX兼容性并不是一个大问题,而且我一直在用1.6编译。谢谢你的提示,不过,我将不得不检查我的其他项目工作在1.5!我将在jar清单中指定类路径,并要求最终用户在升级第三方库时正确命名它们。但是,我将此标记为已被接受,因为它包含最酷的信息。如果我读对了,它只处理我发行版的打包,而不是升级外部库的用户?@bpfurtado:+1,或使用“izpack”。。。也可以自己做同样的事情,这并不难。fat-jar只是关于打包,它不为包含的库提供升级机制。关于dubug使用自定义类加载器的困难,我只是在我的IDE中进行所有开发/调试,然后我使用fat jar进行部署,剩下的所有使用“打包”解决方案进行的测试都与“ClassNotFoundException”相关,什么都不会发生,因为“胖罐子”工作得很好。我还没有测试过胖罐子,但是很多将所有东西重新打包到一个罐子中的方法都会减慢速度。还值得注意的是,第三方库的许可证通常不允许这样的重新打包,特别是当应用程序本身不在同一许可证下(在我的情况下,它不是开源的)时。放慢速度?怎么用?你是说应用程序启动时间?因为我不认为它会减慢开发时间。关于许可证,无论您使用何种技术解决方案,您都会遇到问题。。。我以为你想要一个技术解决方案。Fat Jar做的和你们自己想做的完全一样,但它非常稳定,我从未见过它崩溃,我经常使用它。您不需要“重新发明轮子”,这样您就可以专注于应用程序的独特功能;)@为什么要使用新的类加载器?为什么不简单地使用默认的类加载器,它总是一个URLClassLoader(AFAIK)?这样你就只有一个类加载器了。我就是这样做的,我在数百台OS X和Windows机器上发布(如果sh!t击中风扇,我会改变我的方式;)我确实使用了URLClassLoader。我创建了一个新的类路径来注入动态类路径,您不能更改默认的类路径。我之前为插件系统编写的第二个类加载器。这不是一个坏方法,但当他们更新主程序jar时,会使事情变得复杂,因为他们的更改需要重新完成。我认为总体上要求他们重命名文件是最好的方法,但如果有投诉,我可能会走这条路。