简体   繁体   English

如何允许类加载器从已更改的jar加载类?

[英]How to allow the classloader to load classes from a changed jar?

We have a server side Java6 app running on quite a few linux servers. 我们有一个运行在许多Linux服务器上的服务器端Java6应用程序。 Occasionally, someone will accidentally upgrade the jar file while the application is running. 有时,有人会在应用程序运行时意外升级jar文件。

When that happens, the next attempt to load a class that hasn't been used yet (often the ShutdownHandler code) fails with a ClassNotFoundException. 发生这种情况时,下一次尝试加载尚未使用的类(通常为ShutdownHandler代码)的尝试将失败,并显示ClassNotFoundException。

I would like to tell the classloader that it is ok to read the changed jar file to get the classes it needs. 我想告诉类加载器,可以读取更改后的jar文件来获取所需的类。 I don't mind if this results in the classloader re-reading already loaded classes, although that isn't required. 我不介意这是否导致类加载器重新读取已加载的类,尽管这不是必需的。

You must create your own class loader for this, and the jar must be outside of the classpath in order not to interfere with the existing class loaders. 您必须为此创建自己的类加载器,并且jar必须位于类路径之外 ,以免干扰现有的类加载器。

When it is detected that the jar has changed (look at the file stamp ever X seconds) then tell your application to stop, discard the old classloader, create a new class loader, and tell your application to start inside the new classloader. 当检测到jar发生更改时(每隔X秒钟查看一次文件戳记),然后告诉您的应用程序停止,丢弃旧的类加载器,创建一个新的类加载器,并告诉您的应用程序在新的类加载器中启动。

You must do it like this, or instanceof with friends will not work correctly. 您必须这样做,否则与朋友的instanceof无法正常工作。 (If you want to learn more about this, look into all the fine details of JNDI). (如果您想了解更多有关此的知识,请查看JNDI的所有详细信息)。

Your EASIEST way to do this, would be to write it as a web application (WAR) and deploy it to a servlet container where the things you need to do is done as part of the setup and tear down of the web application. 实现此目的的最简便方法是将其编写为Web应用程序(WAR),然后将其部署到Servlet容器中,在该容器中您需要做的事情是Web应用程序的安装和拆卸的一部分。 You do not need the servlet container to have a web server presense (http port listener etc). 您不需要Servlet容器即可显示Web服务器(http端口侦听器等)。

Most modern servlet containers allow for automatic redeployment. 大多数现代的servlet容器都允许自动重新部署。 A good, small one is Jetty. 一个好的,小的是Jetty。

The problem is likely to be that the original file which was opened has been deleted. 问题可能是已打开的原始文件已被删除。 (and replaced) While the new jar might have the same file name, its not the original file. (并替换)新的jar可能具有相同的文件名,但不是原始文件。 You should be able to customise a ClassLoader to allow this, but unless your application server supports this already, its unlikely to work. 您应该能够自定义ClassLoader以允许此操作,但是除非您的应用程序服务器已经支持此功能,否则它不太可能起作用。

The real answer is to not change an application while it is running. 真正的答案是在运行时不要更改应用程序。

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

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