8

我有一个捆绑为可执行 jar 文件并添加到 weblogic / tomcat 类路径的库,当服务器启动并从 jar 文件加载类时,如何从 jar 文件执行 main 方法。

我想要的是在加载 jar 文件并且服务器在没有任何用户干预的情况下启动时首先执行一些初始化代码。

注意:我知道我可以将我的 jar 捆绑到一个 war 文件中,但是我的库中有一些 aspectj 代码,我想在 jvm 中编织所有正在运行的应用程序,当我将我的 jar 捆绑到 war 文件中时,aspectj 代码只会编织进入war文件中的类,所以我在类路径中添加了我的库jar文件。

提前致谢。

4

4 回答 4

5

使用以下代码在 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到你的类路径中。否则在编译时将无法找到必要的接口(org.apache.catalina.LifecycleListenerorg.apache.catalina.LifecycleEvent)。完成编译后,像往常一样将 JAR 放在<tomcat-dir>/lib.

现在打开<tomcat-dir>/conf/server.xml并在该部分下添加以下<Server>内容:

<Listener className="com.yourpackage.TomcatStartupListener" />

现在,每当您的 Tomcat 服务器启动时,TomcatStartupListener您的 JAR 中的这个类就会被调用,并且您可以调用您的 main 方法。还有很多其他的事件类型!您可以使用以下任何事件类型:

  • before_init
  • after_init
  • before_start
  • 配置启动
  • 开始
  • after_start
  • before_stop
  • 停止
  • 配置停止
  • after_stop
  • before_destroy
  • after_destroy

由于类加载器在 Tomcat(甚至大多数 JVM)中的工作方式,这种方法是必要的。以下是该链接的要点:

There are three aspects of a class loader behavior
  Lazy Loading
  Class Caching
  Separate Namespaces

如果不加选择地加载所有 JAR 中的所有类,JVM 将变得非常沉重。因此,共享 JAR 中的类仅按需加载。您调用 main 方法的唯一方法是添加上述生命周期侦听器。

于 2013-06-08T07:24:26.173 回答
2

也许最简单的做法是在引用您的 .jar 文件的 .war 文件中部署一个简单的 servlet。servlet 可以配置为在部署/容器启动时启动,然后可以调用包含您的main()方法的类。

于 2013-05-31T11:57:44.910 回答
0

由于应用程序服务器/servlet 容器通常有很多不同的类加载器,因此您很可能需要一种不同的策略来将方面编织到代码中,而不是在独立应用程序中。

我建议将这些方面添加到构建时部署的每个 war 文件中。这可能遵循一种通用技术——而不是特定于服务器的技术。

此外,我不确定它实际上是否可以在服务器上完成(正确且受支持)。通常,构建服务器以将所有 Web 应用程序彼此分开。您可能会让它工作,但它可能会在服务器的下一次更新时中断。

如果您陈述要使用建议的方法解决的问题,建议替代技术可能会更容易。

在您发表评论后进行编辑:考虑标准的 Web 应用程序生命周期:您可以在部署时执行一些代码,例如在 servlet 中。如果你坚持你的代码包含在 中main,你可以从你的 webapp 的初始化代码中调用这个方法。

于 2013-05-31T13:12:51.863 回答
0

您需要注册一个 Java 代理。请参阅此链接:java.lang.instrument

java.lang.instrument提供允许 Java 编程语言代理检测在 JVM 上运行的程序的服务。

这是执行此操作的正确方法。

于 2013-06-11T12:46:14.060 回答