Jetty: передача объекта из основного метода с помощью WebAppProvider в сервлет - PullRequest
0 голосов
/ 27 апреля 2018

Мне нужно передать объект из встроенного кода причала в метод main, который будет использоваться в сервлете.

Это проблема из-за отдельного загрузчика классов, используемого в WebAppContext - иначе я бы просто использовал статическую переменную.

Мой основной код настраивает так:

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();

Я попробовал несколько вещей из этого вопроса , но они не сработали. В частности, в контексте сервлета не установлен атрибут org.eclipse.jetty.server.Server.

(В частности, я пытаюсь настроить метрики dropwizard на объектах Jetty, но мне нужен тот же объект MetricRegistry для остальной части моего приложения, чтобы я мог хранить все свои метрики и репортеры вместе)

1 Ответ

0 голосов
/ 27 апреля 2018

При использовании DeploymentManager у вас нет доступа к WebAppContext, или ServletContextHandler, или ContextHandler во время основного кода запуска.

Вместо этого вам придется использовать средства в DeploymentManager для предоставления пользовательского AppLifeCycle.Binding, который делает то, что вам нужно, на этапах развертывания.

Бонус в том, что это работает и во время горячего (пере) развертывания.

Вот рабочий пример этой установки во встроенной пристани из поваренная книга встроенной пристани

DeployWebApps.java

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));
        }
    }
}
...