我可以使用系统属性设置码头类加载语义吗?
Can I set jetty classloading semantics using system properties?
在我们的项目中,我们仅使用 Java API(没有外部 xml 等)启动嵌入式 Jetty,然后向其部署 war 包.现在,由于从 .war
加载的 jar 与实际类路径中的不同,我得到了 ClassCastException
s。阅读关于类加载的 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());
在我们的项目中,我们仅使用 Java API(没有外部 xml 等)启动嵌入式 Jetty,然后向其部署 war 包.现在,由于从 .war
加载的 jar 与实际类路径中的不同,我得到了 ClassCastException
s。阅读关于类加载的 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());