以编程方式执行服务器 Jar (Caucho Resin)

Posted

技术标签:

【中文标题】以编程方式执行服务器 Jar (Caucho Resin)【英文标题】:Executing Server Jar Programatically (Caucho Resin) 【发布时间】:2015-03-22 09:08:04 【问题描述】:

我已经成功使用了 Caucho Resin Web 服务器,我正在考虑将它打包成一个 Java 应用程序。 它们提供了一个 jar 文件和代码,以便以编程方式启动服务器。

Example: example/TestResin.java

package example;

import com.caucho.resin.*;

public class TestResin 

  public static void main(String []args)
  
    ResinEmbed resin = new ResinEmbed();

    HttpEmbed http = new HttpEmbed(8080);
    resin.addPort(http);

    WebAppEmbed webApp = new WebAppEmbed("/", "/var/www/htdocs");
    resin.addWebApp(webApp);

    resin.start();
    resin.join();
  

但是我得到以下错误

java.lang.NoClassDefFoundError: javax/transaction/TransactionManager
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at com.caucho.server.resin.EnvInit.init(EnvInit.java:49)
    at com.caucho.server.resin.EnvInit.<init>(EnvInit.java:44)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at java.lang.Class.newInstance(Class.java:374)
    at com.caucho.loader.Environment.initializeEnvironment(Environment.java:971)
    at com.caucho.resin.ResinEmbed.start(ResinEmbed.java:320)
    at com.mycompany.server.Resin.main(Resin.java:23)
Caused by: java.lang.ClassNotFoundException: javax.transaction.TransactionManager
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 22 more
Exception in thread "main" java.lang.NoClassDefFoundError: javax/enterprise/inject/spi/BeanManager
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at com.caucho.env.service.ResinSystem.<init>(ResinSystem.java:138)
    at com.caucho.env.service.ResinSystem.<init>(ResinSystem.java:99)
    at com.caucho.server.resin.Resin.<init>(Resin.java:236)
    at com.caucho.server.resin.ResinEmbedded.<init>(ResinEmbedded.java:46)
    at com.caucho.resin.ResinEmbed.start(ResinEmbed.java:322)
    at com.mycompany.server.Resin.main(Resin.java:23)
Caused by: java.lang.ClassNotFoundException: javax.enterprise.inject.spi.BeanManager
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 18 more
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)

解决方案:

添加了 glassfish 安装目录中的 javaee-16.jar 库,一切正常。 显然从 Oracle 下载 glassfish-api.jar 不起作用,因为只包含方法声明而没有实现。

【问题讨论】:

【参考方案1】:

使用它来解释 jar,就像使用 java -jar ... 运行它一样:

File f = new File("resin-3.1.0/lib/resin.jar");
URL url = new URL("file", null, f.getAbsolutePath());
ClassLoader cl = new URLClassLoader(new URL[] url);
Class<?> mcls = cl.loadClass("a.b.c.Main");
Method mmethod = mcls.getMethod("main", new Class[] String[].class);
mmethod.invoke(mcls);

这里,Resin 将在它自己的类加载器中运行。

【讨论】:

有趣的方法,如果使用提供的嵌入式类不能正常工作并且我不知道如何解决错误,我会使用它。【参考方案2】:

这是一个流程生命周期问题,应该为您的应用仔细考虑。有几种方法可以做到这一点:

通过Runtime.getRuntime().exec() 或同等工具在您的应用程序中执行。从本质上讲,是在您的应用运行的 JVM 之外生成一些进程。 在外部编写脚本和/或cron 作业。即,在您的应用之外从外部生成一些进程。 从应用程序中的线程运行 Web 服务器的 main() 方法。 (您可以通过检查 jar 的清单以获取其 Main Class 来确定这一点。)这意味着您正在运行的 JVM 中将其作为一个(或多个线程)运行。

根据这些,我们可以确定您应该考虑的两个维度是:

    从您的应用程序内部或外部生成/控制。 从您的 JVM 内部或外部运行。

最重要的是,您必须确定最适合您的应用程序的方式,因为您知道谁将运行它、将如何部署它,是长时间运行还是短时间运行,是频繁或不频繁产生等。建议您谨慎选择。通常,人们会将此作为事后的想法,这往往会导致很多麻烦。

【讨论】:

【参考方案3】:

添加了 glassfish 安装目录中的 javaee-16.jar 库,一切正常。

【讨论】:

以上是关于以编程方式执行服务器 Jar (Caucho Resin)的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式提取Jar文件的模块名称的最佳方法是什么?

PySpark 2.x:以编程方式将 Maven JAR 坐标添加到 Spark

如何以编程方式执行“npm run”命令?

如何在wildfly服务器中以编程方式热重载静态资源(如xhtml)以获取爆炸战争中存在的库

java ejb TimerService:getTimers返回的已取消计时器(树脂caucho)

编程基础;程序的执行方式;编程基本概念