是否有可能打包在一个大罐子里的所有jar依赖关系?(Is it possible to packag

2019-06-24 11:25发布

我知道这是不是“最佳做法”,但我可以包含所有依赖于一个大罐子?

Answer 1:

有一个叫实用单罐其中你想要做什么,尽管我反对建议。 性能通常是可怕的。



Answer 2:

My feeling is that calling One-Jar's performance awful and poor is unjust. For moderately sized application one can expect startup will take a couple of seconds longer (which does not affect JVM splash screen though). Memory overhead of tens of megabytes is negligible for most environments, except perhaps embedded systems. Also, One-Jar is capable of automatically extracting some files to the file system, which saves the need to develop an installer in my case.

Below is an attempt to quantify the performance impact introduced by One-Jar to my application. It is Swing-based GUI application, consists of 352 classes obfuscated with ProGuard 4.5b2. One-Jar 0.96 is used to bundle resulting classes with 12MB worth of libraries (ODFDOM, Saxon HE, Xerces, Jaxen, VLDocking, Apache Commons, etc). I have compared performance of the obfuscated jar with the same jar processed by One-Jar.

  • From JVM start to the start of of main() method: 0.5s without One-Jar and 1.7s with One-Jar. From JVM start to the appearance of application window on the screen: 2.3s without One-Jar and 3.4s with One-Jar. So One-Jar adds 1.1s to startup time.
  • One-Jar will not increase the delay between JVM start and splash image appearing on the screen (if implemented via jar manifest), so the startup time increase is not too annoying for interactive applications.
  • We are talking about a class loader, so there should be no impact on code execution speed, unless you are extensively using dynamic class loading.
  • Looking at JVM statistics (via jconsole) shows that One-Jar'red version takes more heap memory. For my application the overhead is in the order of tens of MBs. I saw figures like 16MB vs 40MB, 306MB vs 346MB, 131MB vs 138MB, depending on now much user data the application is handling and now long time ago garbage collector has been executed.

The above timing was obtained by taking a timestamp just before starting JVM from Linux shell, in beginning of main() method, and in windowOpened() event handler of my application window. The measurements were taken on a not particularly fast D820 laptop, with dual core 1GHz CPU and 2G or RAM running Ubuntu 8.04.

Hope it helps.



Answer 3:

我使用Maven的组装插件与JAR-具有依赖性描述符



Answer 4:

使用好老蚂蚁:只要使用zipgroupfileset通过Ant 邮编任务

<zip destfile="out.jar">
    <zipgroupfileset dir="lib" includes="*.jar"/>
</zip>

这将拼合所有包含的jar库的内容。



Answer 5:

一JAR加载所有的依赖罐子成在启动时内存中。 这可能听起来很没效率的,但没有人向我抱怨它,因为它是在2004年发布了预加载的可能的效果在于为类加载应用程序的总体加快,由于ClassLoader不必反复扫描类路径资源和类的应用程序运行时:一切都hashmapped。

这是很简单的建立一个延迟加载这将点播加载:但我,说“集结它,衡量,它提高,它在必要时”,至今一直没有需要改进的学校。

我会记住这一点对未来的版本(或如果别人想解决它,那将是巨大的,因为没有一个非常大的应用程序来衡量,很难知道,如果变化是改进)。



Answer 6:

如果你想这样做有一个工具叫瓶瓶链接它会为你做这个。 从来没有使用过它,但它是难以忘记的名字。



Answer 7:

  • 您可以其unjar文件,并使用命令行重新包装它们

  • 您可以使用[uberjar]

  • 您可以使用fatjar



Answer 8:

通常你可以,但有时也有不寻常的法律技术原因不能。

  • 法律:例如,我们发现,当时我们想,我们不能JavaMail JAR文件捆绑在一起,成一个大包与我们的应用程序的其他部分,但该许可协议说,我们必须让他们分开。

  • 技术:另一个问题可能是自定义的类装载器查找特定的资源或类别的特定jar文件内。 这种情况经常发生在应用程序服务器或ESB产品容器的情况下。

如何:要做到这一点,就不能解压缩一切到一个目录,然后从那里重建一个罐子。 您可能需要调整的META-INF文件夹中的一些设置删除请求加载额外的罐子,并处理其中不同的罐子都有一个默认的类来运行的情况。 有一些第三方实用程序可能有帮助,但除非你知道自己在做什么 ,你要小心。



Answer 9:

Eclipse的3.4和机会让你可以做到这一点。 右键点击你的项目,选择提取,然后导航到运行的JAR选项。 选择下一步。 选择适当的设置和你关闭和运行。 此外,我似乎记得,这一功能是使用FatJar(如上所述)使用相同或类似的库来实现的。



Answer 10:

只是为了完整性, ProGuard的会为你做这个,以及可选混淆和收缩的JAR。 后者的功能是用于创建最终部署的JAR文件特别有用。



Answer 11:

还记得.jar文件是在幕后.zip文件。 您可以使用您喜欢的压缩工具(重新)将它们打包。 在这种情况下,你将不得不处理清单文件自己。



文章来源: Is it possible to package all the jar dependencies in one big jar?