指定ServletContext setInitParameter时,Jetty 9.4.3无法启动

时间:2018-01-24 12:42:17

标签: servlets parameters jetty

我在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

所述的说明操作

关于可能发生的事情的任何想法?

由于

1 个答案:

答案 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