码头:将对象从具有WebAppProvider的主要方法传递给Servlet [英] Jetty: Pass object from main method with WebAppProvider to Servlet
问题描述
我需要以一种主要方法传递嵌入式码头代码中的对象,以便在servlet中使用。
这是一个问题,因为使用了单独的类加载器
我的主要代码设置如下:
< pre class = lang-java prettyprint-override>
Server server = new Server();
//在此处设置连接器...
ContextHandlerCollection contexts = new ContextHandlerCollection();
RequestLogHandler requestLogHandler = new RequestLogHandler();
HandlerCollection handlers = new HandlerCollection();
handlers.setHandlers(new Handler [] {contexts,new DefaultHandler(),requestLogHandler});
server.setHandler(instrumentedHandler(handlers,metrics));
addRequestLogging(requestLogHandler);
DeploymentManager deploymentManager = new DeploymentManager();
deploymentManager.setContexts(contexts);
WebAppProvider webAppProvider =新的WebAppProvider();
webAppProvider.setMonitoredDirName(jettyHome + / webapps);
webAppProvider.setParentLoaderPriority(false);
webAppProvider.setExtractWars(true);
webAppProvider.setScanInterval(1);
webAppProvider.setDefaultsDescriptor(jettyHome + /webdefault.xml);
webAppProvider.setConfigurationManager(new PropertiesConfigurationManager());
deploymentManager.addAppProvider(webAppProvider);
server.addBean(deploymentManager);
//尝试在服务器上设置指标-但我无法在Servlet
server.setAttribute(MetricRegistry.class.getName(),metrics)中访问它们;
server.start();
server.join();
我尝试了一些问题,但它们不起作用。具体来说,在Servlet上下文中没有设置 org.eclipse.jetty.server.Server
属性。
(具体来说,我正在尝试在码头对象上设置dropwizard指标,但是我的其余应用程序需要相同的MetricRegistry对象,以便可以将所有指标和报告者放在一起)
使用 DeploymentManager
时,您无权访问 WebAppContext
,或者在主要起始代码中输入 ServletContextHandler
或 ContextHandler
。
您必须使用 DeploymentManager
中的功能来提供自定义的 AppLifeCycle.Binding
奖金是,这在热(重新)部署期间也能起作用。
package org.eclipse.jetty.cookbook;
import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
进口org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppLifeCycle;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.deploy.providers.WebAppProvider;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
公共类DeployWebApps
{
public static void main(String [] args)引发异常
{
服务器服务器=新服务器(8080);
ContextHandlerCollection contexts = new ContextHandlerCollection();
HandlerCollection handlers = new HandlerCollection();
handlers.setHandlers(new Handler [] {contexts,new DefaultHandler()});
server.setHandler(handlers);
路径confFile = Paths.get(System.getProperty( user.dir), example.conf);
ContextAttributeCustomizer contextAttributeCustomizer = new ContextAttributeCustomizer();
contextAttributeCustomizer.setAttribute( common.conf,confFile);
DeploymentManager deploymentManager = new DeploymentManager();
deploymentManager.setContexts(contexts);
deploymentManager.addLifeCycleBinding(contextAttributeCustomizer);
字符串jettyBaseProp = System.getProperty( jetty.base);
if(jettyBaseProp == null)
{
抛出新的FileNotFoundException(缺少系统属性'jetty.base');
}
路径jettyBase = new File(jettyBaseProp).toPath()。toAbsolutePath();
WebAppProvider webAppProvider =新的WebAppProvider();
webAppProvider.setMonitoredDirName(jettyBase.resolve( webapps)。toString());
deploymentManager.addAppProvider(webAppProvider);
server.addBean(deploymentManager);
//让启动后转储服务器。
//我们可以查找已部署的上下文,并在转储部分的处理程序属性中查找ContextAttributesCustomizer的
//示例。
server.setDumpAfterStart(true);
server.start();
server.join();
}
公共静态类ContextAttributeCustomizer实现AppLifeCycle.Binding
{
public final Map< String,Object>属性=新的HashMap<>();
public void setAttribute(字符串名称,对象值)
{
this.attributes.put(名称,值);
}
@Override
public String [] getBindingTargets()
{
return new String [] {AppLifeCycle.DEPLOYING};
}
@Override
public void processBinding(节点节点,应用程序应用)引发异常
{
ContextHandler handler = app.getContextHandler();
if(handler == null)
{
throw new NullPointerException(没有为应用程序创建处理程序: +应用程序);
}
属性.forEach((名称,值)-> handler.setAttribute(名称,值));
}
}
}
I need to pass an object from the embedded jetty code in a main method to be used in a servlet.
This is an issue because of the separate classloader used within the WebAppContext - otherwise I would just use a static variable.
My main code sets things up like this:
Server server = new Server();
// setup connectors here...
ContextHandlerCollection contexts = new ContextHandlerCollection();
RequestLogHandler requestLogHandler = new RequestLogHandler();
HandlerCollection handlers = new HandlerCollection();
handlers.setHandlers(new Handler[] { contexts, new DefaultHandler(), requestLogHandler });
server.setHandler(instrumentedHandler(handlers, metrics));
addRequestLogging(requestLogHandler);
DeploymentManager deploymentManager = new DeploymentManager();
deploymentManager.setContexts(contexts);
WebAppProvider webAppProvider = new WebAppProvider();
webAppProvider.setMonitoredDirName(jettyHome + "/webapps");
webAppProvider.setParentLoaderPriority(false);
webAppProvider.setExtractWars(true);
webAppProvider.setScanInterval(1);
webAppProvider.setDefaultsDescriptor(jettyHome + "/webdefault.xml");
webAppProvider.setConfigurationManager(new PropertiesConfigurationManager());
deploymentManager.addAppProvider(webAppProvider);
server.addBean(deploymentManager);
// Attempt to set the metrics on the server - but I can't access them in the Servlet
server.setAttribute(MetricRegistry.class.getName(), metrics);
server.start();
server.join();
I tried a few things from this question, but they did not work. Specifically, there is no org.eclipse.jetty.server.Server
attribute set on the servlet context.
(Specifically, I am trying to setup dropwizard metrics on the jetty objects, but I need the same MetricRegistry object for the rest of my application so I can keep all my metrics and reporters together)
When using the DeploymentManager
, you have no access to the WebAppContext
, or ServletContextHandler
, or ContextHandler
during your main start code.
You'll instead have to use the facilities in the DeploymentManager
to provide a custom AppLifeCycle.Binding
that does what you need it to do during the deployment phases.
Bonus is that this works during hot (re)deploy as well.
Here's a working example of this setup in embedded-jetty from the embedded-jetty-cookbook
package org.eclipse.jetty.cookbook;
import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppLifeCycle;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.deploy.providers.WebAppProvider;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
public class DeployWebApps
{
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
ContextHandlerCollection contexts = new ContextHandlerCollection();
HandlerCollection handlers = new HandlerCollection();
handlers.setHandlers(new Handler[]{contexts, new DefaultHandler()});
server.setHandler(handlers);
Path confFile = Paths.get(System.getProperty("user.dir"), "example.conf");
ContextAttributeCustomizer contextAttributeCustomizer = new ContextAttributeCustomizer();
contextAttributeCustomizer.setAttribute("common.conf", confFile);
DeploymentManager deploymentManager = new DeploymentManager();
deploymentManager.setContexts(contexts);
deploymentManager.addLifeCycleBinding(contextAttributeCustomizer);
String jettyBaseProp = System.getProperty("jetty.base");
if (jettyBaseProp == null)
{
throw new FileNotFoundException("Missing System Property 'jetty.base'");
}
Path jettyBase = new File(jettyBaseProp).toPath().toAbsolutePath();
WebAppProvider webAppProvider = new WebAppProvider();
webAppProvider.setMonitoredDirName(jettyBase.resolve("webapps").toString());
deploymentManager.addAppProvider(webAppProvider);
server.addBean(deploymentManager);
// Lets dump the server after start.
// We can look for the deployed contexts, along with an example of the
// result of ContextAttributesCustomizer in the dump section for "Handler attributes"
server.setDumpAfterStart(true);
server.start();
server.join();
}
public static class ContextAttributeCustomizer implements AppLifeCycle.Binding
{
public final Map<String, Object> attributes = new HashMap<>();
public void setAttribute(String name, Object value)
{
this.attributes.put(name, value);
}
@Override
public String[] getBindingTargets()
{
return new String[]{ AppLifeCycle.DEPLOYING };
}
@Override
public void processBinding(Node node, App app) throws Exception
{
ContextHandler handler = app.getContextHandler();
if (handler == null)
{
throw new NullPointerException("No Handler created for App: " + app);
}
attributes.forEach((name, value) -> handler.setAttribute(name, value));
}
}
}
这篇关于码头:将对象从具有WebAppProvider的主要方法传递给Servlet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!