我可以使用系统属性设置码头类加载语义吗?

Can I set jetty classloading semantics using system properties?

在我们的项目中,我们仅使用 Java API(没有外部 xml 等)启动嵌入式 Jetty,然后向其部署 war 包.现在,由于从 .war 加载的 jar 与实际类路径中的不同,我得到了 ClassCastExceptions。阅读关于类加载的 Jetty 页面 (https://www.eclipse.org/jetty/documentation/current/jetty-classloading.html) 我想看看我是否可以配置 WebAppClassLoader 来增加被认为是 'system' 类 的 类 集合.有一个 Java API 可以做到这一点(WebAppContext.setServerClasses()),如果您使用 xml 配置文件,还有一种方法可以做到这一点:

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

但我想知道是否可以仅使用 Java 系统属性来完成。

谢谢!

WebAppContext 上没有配置服务器或系统的系统属性类。

这是因为那种变化被认为属于特定的 WebApp,而不是所有的 WebApp。

但是,您有一个替代方案,如果您在嵌入式码头中使用 DeploymentManager,那么您很幸运,您在代码中有一个选项。

您需要创建一个自定义 AppLifeCycle.Binding,它在任何部署的 WebAppContext 上设置这些属性(我建议绑定到 deploying)。

这是一个强制 WebAppContext 始终使用来自 server/system 类加载器的日志记录库的示例。

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 的示例(上面 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());