Java 更改类文件时重新启动tomcat?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1873920/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Restart tomcat when a class file is changed?
提问by flash
Why do we need to restart a tomcat server whenever a class file is changed, is there no other way?
为什么每次更改class文件都需要重启tomcat服务器,没有其他办法了吗?
采纳答案by Pascal Thivent
You can configure Tomcat and make your webapp "reloadable". To do so, add reloadable=true
to the <Context>
element of your webapp. About the reloadable
attribute, the documentationsays:
您可以配置 Tomcat 并使您的 web 应用程序“可重新加载”。为此,请添加reloadable=true
到<Context>
您的 web 应用程序的元素。关于reloadable
属性,文档说:
Set to
true
if you want Catalina to monitor classes in/WEB-INF/classes/
and/WEB-INF/lib
for changes, and automatically reload the web application if a change is detected. This feature is very useful during application development, but it requires significant runtime overhead and is not recommended for use on deployed production applications. That's why the default setting for this attribute is false. You can use the Managerweb application, however, to trigger reloads of deployed applications on demand.
设置为
true
,如果你想卡塔利娜监测类/WEB-INF/classes/
和/WEB-INF/lib
更改,并自动如果检测到变化重新加载Web应用程序。此功能在应用程序开发过程中非常有用,但它需要大量的运行时开销,不推荐用于已部署的生产应用程序。这就是此属性的默认设置为 false 的原因。但是,您可以使用ManagerWeb 应用程序按需触发已部署应用程序的重新加载。
回答by Carl Smotricz
There certainly is! Start Tomcat in development mode, then each webapp will restart itself upon being redeployed.
肯定有!在开发模式下启动 Tomcat,然后每个 webapp 将在重新部署时重新启动。
From the Tomcat docs:
从 Tomcat 文档:
The servlet which implements Jasper is configured using init parameters in your global $CATALINA_BASE/conf/web.xml.
实现 Jasper 的 servlet 使用全局 $CATALINA_BASE/conf/web.xml 中的 init 参数进行配置。
...
...
development - Is Jasper used in development mode (will check for JSP modification on every access)? true or false, default true.
development - Jasper 是否在开发模式下使用(每次访问时都会检查 JSP 修改)?true 或 false,默认为 true。
There are settings you can change to adjust what exactly Tomcat will look for to check for updates. I usually deploy individual class files to their appropriate directory under WEB-INF/classes
and then
您可以更改一些设置来调整 Tomcat 检查更新的确切内容。我通常将单个类文件部署到相应的目录下WEB-INF/classes
,然后
touch WEB-INF/web.xml
touch WEB-INF/web.xml
to kick-start a restart of the application; I think web.xml
is one of the files Tomcat checks by default.
启动应用程序的重新启动;我认为web.xml
是Tomcat默认检查的文件之一。
回答by spork
If you're using WAR files to deploy, you can set autoDeploy=true
in the Tomcat config, which causes Tomcat to watch the web application root ("webapps" by default) for new or changed WAR files. If such a file is found, it is automatically deployed.
如果您使用 WAR 文件进行部署,则可以autoDeploy=true
在 Tomcat 配置中进行设置,这会导致 Tomcat 监视 Web 应用程序根目录(默认为“webapps”)以查找新的或更改的 WAR 文件。如果找到这样的文件,它会自动部署。
As Pascal Thivent said, though, you can use the Tomcat Manager application (/manager/html) to start, stop, deploy, and undeploy specific applications. If the files you're changing are in a specific application, this is a good way to get Tomcat to recognize the changes.
不过,正如 Pascal Thivent 所说,您可以使用 Tomcat 管理器应用程序 (/manager/html) 来启动、停止、部署和取消部署特定应用程序。如果您要更改的文件在特定应用程序中,这是让 Tomcat 识别更改的好方法。
回答by Thorbj?rn Ravn Andersen
If you develop, your IDE should be able to do this transparently on a suitable server. E.g. the Dynamic Web Project in Eclipse knows how to talk to Tomcat.
如果您进行开发,您的 IDE 应该能够在合适的服务器上透明地执行此操作。例如,Eclipse 中的动态 Web 项目知道如何与 Tomcat 对话。
If you deploy, then create WAR-files and deploy those. Tomcat knows how to redeploy a WAR-file.
如果部署,则创建 WAR 文件并部署它们。Tomcat 知道如何重新部署 WAR 文件。
回答by Kelly S. French
On a more general note, the reason you have to do this is because in Java, when a classloader loads a class, it cannot unload it. What Tomcat has to do is use a new classloader and reload all the classes it needs.
更一般地说,您必须这样做的原因是因为在 Java 中,当类加载器加载一个类时,它无法卸载它。Tomcat 要做的是使用一个新的类加载器并重新加载它需要的所有类。
回答by Nick Hristov
Besides setting autoDeploy=true in server.conf , you also should be careful not to put any classes in the shared classloader. Classes which are loaded by the shared class loader cannot be re-loaded.
除了在 server.conf 中设置 autoDeploy=true 之外,您还应该注意不要在共享类加载器中放置任何类。由共享类加载器加载的类无法重新加载。
回答by ha9u63ar
Your question doesn't actually say whether you are concerned about a production downtime (i.e. reduce it by reloading the classes) or you want non-stop development. So I will try to clarify using the following points:
您的问题实际上并没有说明您是担心生产停机时间(即通过重新加载类来减少停机时间)还是想要不间断开发。因此,我将尝试使用以下几点进行澄清:
1) using <Context reloadable=true...
in your catalina.home/conf
directory you can make sure that your webapp reloads when a any class changes. You can add the resource change watchlist in <WatchedResources>
element.
1)<Context reloadable=true...
在您的catalina.home/conf
目录中使用,您可以确保您的 webapp 在任何类更改时重新加载。您可以在<WatchedResources>
元素中添加资源更改监视列表。
2) But this will reload the context, re-initialise the classloader, empty it's cache, and everything will be as if the webapplication has just started.
2) 但是这将重新加载上下文,重新初始化类加载器,清空它的缓存,一切都好像 web 应用程序刚刚启动一样。
This approach will still leave your server unusable, because you have reloaded the Servlet's context. The true "Reload" is
这种方法仍然会使您的服务器无法使用,因为您已经重新加载了 Servlet 的上下文。真正的“重装”是
1) You swap the byte code of the class, with some restrictions 2) JVM will return that class when "loadClass()" is called for that classloader.
1) 您交换类的字节码,但有一些限制 2) 当为该类加载器调用“loadClass()”时,JVM 将返回该类。
This is java instrumentation. You can write your own agent which can hook into your JVM either at the beginning or in flight. However, you cannot define new method, and change static variables. These are JVM native restrictions (for Oracle HotSpot JVM, that I know of). You can use a different JVM e.g. DCEVM which doesn't have such restriction. So it's up to you how you want to handle your problem. If you know what you are doing (!), you can get away with replacing classes one-by-one. And you can even define a "Brand New Class", reference that class object/method in an existing/loaded class and instrument it to to pick up changes.
这是java仪器。您可以编写自己的代理,该代理可以在开始时或运行中连接到您的 JVM。但是,您不能定义新方法,也不能更改静态变量。这些是 JVM 本机限制(对于 Oracle HotSpot JVM,我知道)。您可以使用不同的 JVM,例如 DCEVM,它没有这种限制。因此,您想如何处理问题取决于您。如果你知道你在做什么(!),你可以通过一个一个地替换类而逃脱。您甚至可以定义一个“全新类”,在现有/加载的类中引用该类对象/方法,并对其进行检测以获取更改。
I hope this helps. All the answers here are what you need to make your decision.
我希望这有帮助。这里的所有答案都是您做出决定所需要的。