Могу ли я установить семантику загрузки класса причала, используя системные свойства? - PullRequest
0 голосов
/ 21 сентября 2019

В нашем проекте мы запускаем встроенный Jetty, используя только API Java (без внешнего xml и т. Д.), А затем внедряем в него военные пакеты.Теперь у меня есть ситуация, когда я получаю ClassCastException с из-за отличия загруженных банок от .war от того, что находится на фактическом пути к классам.Чтение страницы Jetty по загрузке классов (https://www.eclipse.org/jetty/documentation/current/jetty-classloading.html) Я хотел посмотреть, смогу ли я настроить WebAppClassLoader для расширения набора классов, которые считаются «системными» классами. Для этого есть Java API (WebAppContext.setServerClasses()) и способ сделать это, если вы используете конфигурационный файл xml:

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
 <Set name="serverClasses">foo.bar.,com.acme.</Set>
 ...

Но я хотел бы знать, возможно ли это сделать, используя только системные свойства Java.

Спасибо!

1 Ответ

0 голосов
/ 21 сентября 2019

Нет системных свойств для настройки серверов или системных классов в WebAppContext.

Это связано с тем, что такого рода изменения относятся к определенному WebApp, а не ко всем WebApp.

Но у вас есть альтернатива, если вы используете DeploymentManager в своем встроенном причале, вам повезло, у вас есть опция в коде.

Вы захотитесоздайте пользовательский AppLifeCycle.Binding, который устанавливает эти свойства для любого развернутого WebAppContext (я бы рекомендовал привязать к deploying).

Вот пример, который вынуждает WebAppContext всегда использоватьведение журналов библиотек из загрузчика классов сервера / системы.

import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppLifeCycle;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.webapp.WebAppContext;

public class CentralizedWebAppLoggingBinding implements AppLifeCycle.Binding
{
    public String[] getBindingTargets()
    {
        return new String[]
        { "deploying" };
    }

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

        if (handler instanceof WebAppContext)
        {
            WebAppContext webapp = (WebAppContext)handler;
            webapp.addSystemClass("org.apache.log4j.");
            webapp.addSystemClass("org.slf4j.");
            webapp.addSystemClass("org.apache.commons.logging.");
        }
    }
}

А вот пример использования DeploymentManager из встроенного Jetty (также с приведенным выше CentralizedWebAppLoggingBinding.

ContextHandlerCollection contexts = new ContextHandlerCollection();

DeploymentManager deployer = new DeploymentManager();
if(debugIsEnabled)
{
    DebugListener debug = new DebugListener(System.err, true, true, true);
    server.addBean(debug);
    deployer.addLifeCycleBinding(new DebugListenerBinding(debug));
}
deployer.setContexts(contexts);
deployer.setContextAttribute(
    "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
    ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$");

WebAppProvider webAppProvider = new WebAppProvider();
webAppProvider.setMonitoredDirName(jettyBase + "/webapps");
webAppProvider.setDefaultsDescriptor(jettyHome + "/etc/webdefault.xml");
webAppProvider.setScanInterval(1);
webAppProvider.setExtractWars(true);
webAppProvider.setConfigurationManager(new PropertiesConfigurationManager());
webAppProvider.addLifeCycleListener(new CentralizedWebAppLoggingBinding());
...