我在jetty上运行了同一个应用程序的两个实例。我希望他们使用不同的数据库,所以我想指定访问配置传递一个conf文件。这是我的部署xml文件之一:
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/app1Context</Set>
<Set name="war">/path/to/app.war</Set>
<!--<Get name="ServletContext">
<Call name="setInitParameter">
<Arg>db.config.file</Arg>
<Arg>/path/to/databasefile1.properties</Arg>
</Call>
</Get>-->
</Configure>
在这种情况下,应用程序运行正常,都在每个具体化的上下文中运行,但如果我取消注释:
<!--<Get name="ServletContext">
<Call name="setInitParameter">
<Arg>db.config.file</Arg>
<Arg>/path/to/databasefile1.properties</Arg>
</Call>
</Get>-->
Jetty在开始时抛出异常:
2018-01-24 12:05:22.947:WARN:oejx.XmlConfiguration:main: Config error at <Call name="setInitParameter"><Arg>db.config.file</Arg><Arg>/path/to/databasefile1.properties</Arg></Call> java.lang.reflect.InvocationTargetException in file:/path/to/descriptor.xml
2018-01-24 12:05:22.947:WARN:oejx.XmlConfiguration:main: Config error at <Get name="ServletContext"><Call name="setInitParameter"><Arg>db.config.file</Arg><Arg>/path/to/databasefile1.properties</Arg></Call></Get> java.lang.reflect.InvocationTargetException in file:/path/to/descriptor.xml
2018-01-24 12:05:22.947:WARN:oejd.DeploymentManager:main: Unable to reach node goal: started
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.eclipse.jetty.util.TypeUtil.call(TypeUtil.java:529)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.call(XmlConfiguration.java:728)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.configure(XmlConfiguration.java:417)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.get(XmlConfiguration.java:675)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.configure(XmlConfiguration.java:420)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.configure(XmlConfiguration.java:358)
at org.eclipse.jetty.xml.XmlConfiguration.configure(XmlConfiguration.java:259)
at org.eclipse.jetty.deploy.providers.WebAppProvider.createContextHandler(WebAppProvider.java:305)
at org.eclipse.jetty.deploy.App.getContextHandler(App.java:105)
at org.eclipse.jetty.deploy.bindings.StandardDeployer.processBinding(StandardDeployer.java:36)
at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:188)
at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:499)
at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:147)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:180)
at org.eclipse.jetty.deploy.providers.WebAppProvider.fileAdded(WebAppProvider.java:458)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:64)
at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:610)
at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:529)
at org.eclipse.jetty.util.Scanner.scan(Scanner.java:392)
at org.eclipse.jetty.util.Scanner.doStart(Scanner.java:313)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider.doStart(ScanningAppProvider.java:150)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.DeploymentManager.startAppProvider(DeploymentManager.java:561)
at org.eclipse.jetty.deploy.DeploymentManager.doStart(DeploymentManager.java:236)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131)
at org.eclipse.jetty.server.Server.start(Server.java:452)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:113)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
at org.eclipse.jetty.server.Server.doStart(Server.java:419)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1511)
at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1438)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1437)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.eclipse.jetty.start.Main.invokeMain(Main.java:222)
at org.eclipse.jetty.start.Main.start(Main.java:486)
at org.eclipse.jetty.start.Main.main(Main.java:79)
Caused by:
java.lang.IllegalStateException
at org.eclipse.jetty.servlet.ServletContextHandler$Context.setInitParameter(ServletContextHandler.java:1296)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.eclipse.jetty.util.TypeUtil.call(TypeUtil.java:529)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.call(XmlConfiguration.java:728)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.configure(XmlConfiguration.java:417)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.get(XmlConfiguration.java:675)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.configure(XmlConfiguration.java:420)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.configure(XmlConfiguration.java:358)
at org.eclipse.jetty.xml.XmlConfiguration.configure(XmlConfiguration.java:259)
at org.eclipse.jetty.deploy.providers.WebAppProvider.createContextHandler(WebAppProvider.java:305)
at org.eclipse.jetty.deploy.App.getContextHandler(App.java:105)
at org.eclipse.jetty.deploy.bindings.StandardDeployer.processBinding(StandardDeployer.java:36)
at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:188)
at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:499)
at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:147)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:180)
at org.eclipse.jetty.deploy.providers.WebAppProvider.fileAdded(WebAppProvider.java:458)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:64)
at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:610)
at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:529)
at org.eclipse.jetty.util.Scanner.scan(Scanner.java:392)
at org.eclipse.jetty.util.Scanner.doStart(Scanner.java:313)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)at org.eclipse.jetty.deploy.providers.ScanningAppProvider.doStart(ScanningAppProvider.java:150)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.DeploymentManager.startAppProvider(DeploymentManager.java:561)
at org.eclipse.jetty.deploy.DeploymentManager.doStart(DeploymentManager.java:236)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131)
at org.eclipse.jetty.server.Server.start(Server.java:452)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:113)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
at org.eclipse.jetty.server.Server.doStart(Server.java:419)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1511)
at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1438)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1437)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.eclipse.jetty.start.Main.invokeMain(Main.java:222)
at org.eclipse.jetty.start.Main.start(Main.java:486)
at org.eclipse.jetty.start.Main.main(Main.java:79)
我只是按照here
所述的说明操作关于可能发生的事情的任何想法?
由于
答案 0 :(得分:1)
几乎做对了。
关键是你试图在ServletContext存在或尝试启动之前访问真实的javax.servlet.ServletContext
。
在部署期间,当读取并处理${jetty.base}/webapps/<context>.xml
时,ServletContext尚不存在(servlet规范生命周期和所有),因此ServletContextHandler
提供/模仿ServletContext以允许您尽早设置这些类型的init-parameters和属性,然后在实际的ServletContext启动并推送到servlet规范生命周期时可以使用它们。
以下是您可以查看的工作示例。
首先,要转储ServletContext属性和init-parameters,我们可以看到我们的配置实际上在做什么。
package org.eclipse.jetty.demo;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/context-info")
public class ContextInfoServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
ServletContext context = req.getServletContext();
out.println("ServletContext attributes\n-----\n");
Collections.list(context.getAttributeNames())
.forEach((name) -> {
Object obj = context.getAttribute(name);
out.printf("%s: (%s) %s%n", name, obj.getClass().getName(), obj);
});
out.println();
out.println("ServletContext init-params\n-----\n");
Collections.list(context.getInitParameterNames())
.forEach(name -> out.printf("%s: %s%n", name, context.getInitParameter(name)));
}
}
现在为一个仅包含上述servlet的webapp工作${jetty.base}/webapps/<context>.xml
(Jetty XML Deployable)。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/</Set>
<Set name="war"><Property name="jetty.webapps"/>/root.war</Set>
<Call name="setAttribute">
<Arg>myVal</Arg>
<Arg class="java.lang.Integer">4242</Arg>
</Call>
<Call name="setAttribute">
<Arg>myPath</Arg>
<Arg class="java.io.File">
<New class="java.io.File">
<Arg><SystemProperty name="java.io.tmpdir"/></Arg>
</New>
</Arg>
</Call>
<Call name="setInitParameter">
<Arg>mySetting</Arg>
<Arg>default</Arg>
</Call>
<Call name="setInitParameter">
<Arg>anotherOption</Arg>
<Arg>an option that your webapp needs</Arg>
</Call>
</Configure>
使用以下${jetty.base}
start.ini
后
$ cat start.ini
--module=http
jetty.http.port=8080
--module=deploy
--module=annotations
--module=plus
--module=resources
这导致HTTP请求的以下输出发送到http://localhost:8080/context-info
(我已从org.eclipse.jetty.*
和javax.*
属性中移除了噪音,以免混淆事物)
$ curl http://localhost:8080/context-info
ServletContext attributes
-----
myVal: (java.lang.String) 4242
myPath: (java.io.File) C:\Users\joakim\AppData\Local\Temp
ServletContext init-params
-----
anotherOption: an option that your webapp needs
mySetting: default