我有一个库,它被捆绑为一个可执行的 jar 文件并添加到 weblogic/tomcat 类路径,当服务器启动并从 jar 文件加载类时,我如何从 jar 文件执行 main 方法。
我想要的是在加载 jar 文件和启动服务器时首先执行一些初始化代码,而无需任何用户干预。
注意:我知道我可以将我的 jar 打包到一个 war 文件中,但是我的库中有一些 aspectj 代码,我想在 jvm 中编织所有正在运行的应用程序,当我将我的 jar 打包到 war 文件中时,aspectj 代码只会编织到 war 文件中的类,所以我在类路径中添加了我的库 jar 文件。
提前致谢。
最佳答案
使用以下代码在您的 JAR 中添加一个类:
public class TomcatStartupListener implements org.apache.catalina.LifecycleListener {
public void lifecycleEvent(org.apache.catalina.LifecycleEvent event) {
if (event.getType().equals("after_start")) {
// call your main method here
}
}
}
注意:为了编译这个,你需要添加<tomcat-dir>/lib/catalina.jar
到你的类路径。否则在编译时将无法找到必要的接口(interface)( org.apache.catalina.LifecycleListener
和 org.apache.catalina.LifecycleEvent
)。完成编译后,像往常一样将 JAR 放在 <tomcat-dir>/lib
下.
现在打开<tomcat-dir>/conf/server.xml
并在 <Server>
下添加以下内容部分:
<Listener className="com.yourpackage.TomcatStartupListener" />
现在,每当您的 Tomcat 服务器启动时,这个 TomcatStartupListener
您的 JAR 中的类将被调用,您可以调用您的主要方法。还有很多其他事件类型!您可以使用以下任何一种事件类型:
- 初始化前
- 初始化之后
- 开始前
- 配置开始
- 开始
- 开始后
- 停止前
- 停止
- 配置停止
- 停后
- before_destroy
- 销毁后
由于 classloaders work in Tomcat 的方式,这种方法是必要的(甚至大多数 JVM)。以下是该链接的要点:
There are three aspects of a class loader behavior
Lazy Loading
Class Caching
Separate Namespaces
如果不加区别地加载所有 JAR 中的所有类,JVM 将变得非常繁重。因此,共享 JAR 中的类只能按需加载。调用 main 方法的唯一方法是添加上述生命周期监听器。
关于java - 服务器启动时在类路径中引导可执行 jar 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16856704/