java - 将现有 WAR 部署到嵌入式 Jetty

标签 java jsp jetty embedded-jetty

我的目的是将现有的 WAR 部署到嵌入式 Jetty 9.4.5。

不幸的是,我在尝试打开页面(JSP)时遇到以下错误:

An error occurred at line: [52] in the generated java file: [/tmp/embedded-jetty-jsp/jsp/org/apache/jsp/WEB_002dINF/jsp/MainLayout_jsp.java]
Type mismatch: cannot convert from HashSet<?> to Set<String>

An error occurred at line: [52] in the generated java file: [/tmp/embedded-jetty-jsp/jsp/org/apache/jsp/WEB_002dINF/jsp/MainLayout_jsp.java]
Cannot instantiate the type HashSet<?>

An error occurred at line: [52] in the generated java file: [/tmp/embedded-jetty-jsp/jsp/org/apache/jsp/WEB_002dINF/jsp/MainLayout_jsp.java]
Syntax error on token "<", ? expected after this token

Java 中的相关行如下:

private static final java.util.Set<java.lang.String> _jspx_imports_packages = new java.util.HashSet<>();

Jasper 似乎试图将代码编译为 Java 1.6 或更低版本,因此无法解释菱形运算符(我使用的是 Java 1.8.0_141)。

我尝试设置版本但没有成功:

ServletHolder holderJsp = new ServletHolder("jsp",JspServlet.class);
holderJsp.setInitOrder(0);
holderJsp.setInitParameter("logVerbosityLevel","DEBUG");
holderJsp.setInitParameter("compilerTargetVM","1.7");
holderJsp.setInitParameter("compilerSourceVM","1.7");
holderJsp.setInitParameter("keepgenerated","true");
webAppContext.addServlet(holderJsp,"*.jsp");

启动 Jetty 的代码是

public class JettyRunner {

  private static File getScratchDir() throws IOException {
     File tempDir = new File(System.getProperty("java.io.tmpdir"));
     File scratchDir = new File(tempDir.toString(), "embedded-jetty-jsp");

     if (!scratchDir.exists()) {
        if (!scratchDir.mkdirs()) {
           throw new IOException("Unable to create scratch directory: " + scratchDir);
        }
     }
     return scratchDir;
  }

  private static List<ContainerInitializer> jspInitializers() {
     JettyJasperInitializer sci = new JettyJasperInitializer();
     ContainerInitializer initializer = new ContainerInitializer(sci, null);
     List<ContainerInitializer> initializers = new ArrayList<ContainerInitializer>();
     initializers.add(initializer);
     return initializers;
  } 


  public static void main(String[] args) {
     Server server = new Server(8080);

     WebAppContext webAppContext = new WebAppContext();
     File warFile = new File("existing.war");
     webAppContext.setWar(warFile.getAbsolutePath());
     webAppContext.setContextPath("/acme");

     webAppContext.setConfigurations(new Configuration[] {
              new AnnotationConfiguration(),
              new WebInfConfiguration(),
              new WebXmlConfiguration(),
              new MetaInfConfiguration(),
              new FragmentConfiguration(),
              new EnvConfiguration(),
              new PlusConfiguration(),
              new JettyWebXmlConfiguration()
     });

     webAppContext.setAttribute("javax.servlet.context.tempdir", getScratchDir());
     webAppContext.setAttribute("org.eclipse.jetty.containerInitializers", jspInitializers());
     webAppContext.setAttribute(InstanceManager.class.getName(), new SimpleInstanceManager());
     webAppContext.addBean(new ServletContainerInitializersStarter(webAppContext), true);

     ServletHolder holderJsp = new ServletHolder("jsp",JspServlet.class);
     holderJsp.setInitOrder(0);
     holderJsp.setInitParameter("logVerbosityLevel","DEBUG");
     holderJsp.setInitParameter("compilerTargetVM","1.7");
     holderJsp.setInitParameter("compilerSourceVM","1.7");
     holderJsp.setInitParameter("keepgenerated","true");
     webAppContext.addServlet(holderJsp,"*.jsp");

     webAppContext.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",".*/[^/]*jstl.*\\.jar$");
     org.eclipse.jetty.webapp.Configuration.ClassList classlist = org.eclipse.jetty.webapp.Configuration.ClassList.setServerDefault(server);
     classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration", "org.eclipse.jetty.plus.webapp.EnvConfiguration", "org.eclipse.jetty.plus.webapp.PlusConfiguration");
     classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration", "org.eclipse.jetty.annotations.AnnotationConfiguration");

     HashLoginService hashLoginService = new HashLoginService();
     hashLoginService.setName("Test Realm");
     hashLoginService.setConfig("jetty-realm.properties");

     webAppContext.getSecurityHandler().setLoginService(hashLoginService);

     server.setHandler(webAppContext);          

     // Start Jetty
     server.start();
     server.join();
  }

}

任何提示将不胜感激!
谢谢,V。

---------------------------------------- 更新 1 --------------------------------------
我设置了server.setDumpAfterStart(true); (感谢@JoakimErdfelt 的提示!)并注释掉了我设置 compilerTargetVM 的代码。等等(所以我没有将 JspServlet 添加到 webAppContext!),我可以看到

|   += org.eclipse.jetty.server.session.SessionHandler483422889==dftMaxIdleSec=1800 - STARTED
|   |   += org.eclipse.jetty.security.ConstraintSecurityHandler@7c75222b - STARTED
|   |   |   +- org.eclipse.jetty.security.DefaultAuthenticatorFactory@4c203ea1
|   |   |   += org.eclipse.jetty.servlet.ServletHandler@27f674d - STARTED
|   |   |   |   += jsp@19c47==org.eclipse.jetty.jsp.JettyJspServlet,jsp=null,order=0,inst=true - STARTED
|   |   |   |   |   +- fork=false
|   |   |   |   |   +- compilerSourceVM=1.7
|   |   |   |   |   +- logVerbosityLevel=DEBUG
|   |   |   |   |   +- compilerTargetVM=1.7
|   |   |   |   |   +- scratchdir=/tmp/embedded-jetty-jsp/jsp
|   |   |   |   |   +- xpoweredBy=false

因此 Java 源代码设置为 1.7,但 JVM 仍然无法解释菱形运算符!
真糟糕...有什么想法吗?
非常感谢!

最佳答案

您的 WAR 中的 WEB-INF/lib/ 条目与 JSP 的更新版本冲突。

从 WAR 中删除以下条目。

WEB-INF/lib/jstl-1.1.2.jar
WEB-INF/lib/standard-1.1.2.jar

这些 jars 从一开始就不应该包含在您的 WAR 文件中。

这些是由 JSP 容器提供的。

另外,摆脱这个......

webAppContext.setConfigurations(new Configuration[] {
          new AnnotationConfiguration(),
          new WebInfConfiguration(),
          new WebXmlConfiguration(),
          new MetaInfConfiguration(),
          new FragmentConfiguration(),
          new EnvConfiguration(),
          new PlusConfiguration(),
          new JettyWebXmlConfiguration()
 });

...并添加此内容(在创建 WebAppContext 之前)...

    Configuration.ClassList classlist = Configuration.ClassList
            .setServerDefault( server );
    classlist.addAfter(
            "org.eclipse.jetty.webapp.FragmentConfiguration",
            "org.eclipse.jetty.plus.webapp.EnvConfiguration",
            "org.eclipse.jetty.plus.webapp.PlusConfiguration");

    classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
                        "org.eclipse.jetty.annotations.AnnotationConfiguration");

由于“设置”整个配置列表不合适,请改用修改例程。

示例取自 https://github.com/eclipse/jetty.project/blob/jetty-9.4.8.v20171121/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java#L186-L195

关于java - 将现有 WAR 部署到嵌入式 Jetty,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48790626/

相关文章:

eclipse - Tomcat 服务器启动失败

java - Spring MVC Portlet : form not saving data correctly

java - 从jsp将多行插入数据库mysql

jetty - 在 Ubuntu 12.04.4 上重启 Jetty

docker - 从另一个容器调用 docker 容器

intellij-idea - 在 IntelliJ 中,如何在内部 jetty 运行配置中设置服务器端口

java - 如何获取JavaFX WebEngine的文件资源

java - AsyncTask doInBackground() 方法中的空指针异常

java - 在 JButton 中执行 ActionEvent 需要双击

java - 什么是 JPA 提供程序?