简体   繁体   English

如果替换了底层jar,Java程序会崩溃

[英]Java program crashes if underlying jar is replaced

I have a piece of software, contained in a single .jar that is doing its job but sometimes I need to quickly push a bug fix necessitating replacing the .jar file in a central location, unfortunately if there is a currently running execution of this jar file if I replace it then it crashes with "class not found" error. 我有一个软件,包含在单个.jar中,它正在完成它的工作但有时我需要快速推送一个bug修复,必须在一个中心位置替换.jar文件,不幸的是,如果当前正在运行这个jar的执行文件,如果我替换它然后崩溃与“类未找到”错误。 I thought that once a jar file is executed the JVM will cache it in memory and won't do any reads from the disk but apparently this is not the case, how can (if possible at all) this be remedied? 我认为一旦执行了一个jar文件,JVM就会将它缓存在内存中,并且不会从磁盘上进行任何读取,但显然情况并非如此,如何(如果可能的话)可以解决这个问题?

EDIT: 编辑:

The application is not web-based. 该应用程序不是基于Web的。 It's normal Java SE. 这是正常的Java SE。

JAR files are not loaded into memory in bulk, as other shared object libraries are. JAR文件不会像其他共享对象库一样批量加载到内存中。 Their classes are loaded into memory on a demand basis, so if you remove a JAR file and a class lookup needs to occur, the file handle the class loader will be invalid (because the open file it referenced is now gone) and you will get an error. 它们的类是根据需求加载到内存中的,所以如果你删除一个JAR文件并且需要进行类查找,那么类加载器的文件句柄将是无效的(因为它引用的打开文件现在已经消失了)你会得到一个错误。

Operating systems manage the file handles, so replacing an open file with a new copy is not going to fool anyone. 操作系统管理文件句柄,因此用新副本替换打开的文件不会欺骗任何人。 You need to close the file first, which often can only be done by garbage collecting the class loader. 您需要先关闭文件,这通常只能通过垃圾收集类加载器来完成。 If you are using the system class loader, then that means shutting down the JVM. 如果您正在使用系统类加载器,那么这意味着关闭JVM。

People have written frameworks to create custom class loaders that can be disposed independently of the system class loader; 人们已经编写了用于创建自定义类加载器的框架,这些加载器可以独立于系统类加载器进行处理; however, this does complicate class loading. 但是,这确实使类加载变得复杂。 While it can accomplish what you are asking, it cannot do so without restructuring your existing program to accommodate the lookup of classes in the framework's class loaders (and accommodating the loss and gain of class loaders over time). 虽然它可以完成你所要求的,但是如果不重构你现有的程序来适应框架类加载器中的类的查找(并且随着时间的推移容纳类加载器的损失和收益),它就不能这样做。

If you want to try such a framework, see Christian's post. 如果你想尝试这样的框架,请参阅Christian的帖子。 If you want to learn a bit more about how one project uses class loaders to facilitate its needs, take a peek under the covers of Apache's Tomcat, which restricts web applications within their own class loaders. 如果您想更多地了解一个项目如何使用类加载器来满足其需求,请查看Apache的Tomcat,它将Web应用程序限制在自己的类加载器中。

Often you might find that the correct answer really is to stop the service prior to deployment, and start it after deployment. 通常,您可能会发现正确的答案实际上是在部署之前停止服务,并在部署之后启动它。

我能想到的唯一两种可能是使用JRebelOSGi

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM