使用嵌入式Jetty提供的GWT前端运行Java守护程序
你好,编码员 背景信息和代码 我试图创建一个守护程序类型的程序(例如,它不断运行,轮询要做的事情),该程序由GWT应用程序(战争中的servlet)管理,而GWT应用程序又由嵌入式Jetty服务器(使用使用嵌入式Jetty提供的GWT前端运行Java守护程序,java,gwt,daemon,classloader,Java,Gwt,Daemon,Classloader,你好,编码员 背景信息和代码 我试图创建一个守护程序类型的程序(例如,它不断运行,轮询要做的事情),该程序由GWT应用程序(战争中的servlet)管理,而GWT应用程序又由嵌入式Jetty服务器(使用WebAppContext)提供服务。我在让GWT应用程序知道守护程序对象时遇到问题 为了进行测试,我目前有两个项目:一个是守护进程和嵌入式Jetty服务器(EmbJetTest),另一个是GWT应用程序(DefaultApp)。这是代码的当前状态: 首先,EmbJetTest像这样创建一个嵌入式
WebAppContext
)提供服务。我在让GWT应用程序知道守护程序对象时遇到问题
为了进行测试,我目前有两个项目:一个是守护进程和嵌入式Jetty服务器(EmbJetTest
),另一个是GWT应用程序(DefaultApp
)。这是代码的当前状态:
首先,EmbJetTest
像这样创建一个嵌入式Jetty服务器,使用ServletContextListener
将守护程序对象注入web应用程序上下文:
EmbJetTest.server = new Server(8080);
// Create and start the daemon
Daemon daemon = new Daemon();
Thread thread = new Thread(daemon);
thread.start();
// war handler
WebAppContext waContext = new WebAppContext();
waContext.setContextPath("/webapp");
waContext.setWar("./apps/DefaultApp.war");
waContext.addEventListener(new DaemonLoader(daemon));
// Add it to the server
EmbJetTest.server.setHandler(waContext);
EmbJetTest.server.setThreadPool(new QueuedThreadPool(10));
// Start the server; join() blocks until we shut down
EmbJetTest.server.start();
EmbJetTest.server.join();
// Stop the daemon thread
daemon.stopLoop();
守护进程
目前是一个非常简单的对象,具有两个属性DaemonLoader
是以下ServletContextListener
实现:
private Daemon daemon;
public DaemonLoader(Daemon daemon)
{
this.daemon = daemon;
}
@Override
public void contextDestroyed(ServletContextEvent arg0) {
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
arg0.getServletContext().setAttribute("daemon", this.daemon);
}
然后,在GWT应用程序中的一个servlet中,我有以下代码:
Daemon daemon = (Daemon) this.getServletContext().getAttribute("daemon");
但是,当我访问localhost:8080/webapp/*并调用servlet时,该代码抛出一个ClassCastException
,即使这些类是相同类型的。指示这是因为这两个类使用不同的类加载器加载
问题:
我的问题有两方面
提前感谢。为什么不在GWT web应用程序中的单独线程中运行守护程序的功能呢?这样,您就可以避免所有的类加载痛苦(正如您所发现的,不同
.war
文件中的应用程序在它们自己的类加载程序中运行)
只要为你的守护进程和你现有的servlet一起创建一个servlet(在同一个
.war
),并在servlet初始化和销毁时启动/停止线程。好吧,如果有人感兴趣,我实际上解决了类加载器问题——最初,我将编译好的Daemon.class放在GWT应用程序的WEB-INF/classes文件夹中。我删除了这个文件,现在看来GWT应用程序使用了EmbJetTest项目中的守护进程类
尽管如此,我认为更值得注意。:) 我突然想到,守护进程可以有自己的通信协议,servlet可以使用它来控制守护进程,但如果不需要的话,我宁愿不在守护进程中设计一些通信接口——但如果我这样做,我会这样做。:)如果你给守护进程自己的控制协议(通过一个控制servlet),那么你将有更多的灵活性。我不确定如何在GWT应用程序中加载守护进程类。如前所述,即使没有访问servlet,它也需要加载和运行。此外,我不确定这是否会使问题复杂化,但需要加载和运行的类将通过配置文件指定。您可以通过指定servlet在web应用程序初始化时启动,这样您就不需要访问应用程序。配置将通过web.xml和其中的适当参数进行。指定一个类名作为初始化参数,并在最简单的情况下使用(比如)class.forName(name).newInstance()。我认为这很理想,我越是考虑它。嵌入式Jetty实例和相关代码根本不需要了解守护进程——这会将守护进程和所有管理代码绑定到同一个项目中。启动servlet可以读取配置文件并加载适当的守护程序类。可能也会使测试更容易,因为dev.mode无论如何都会加载所有内容。