问题描述
我正在打包一个Web应用程序存档(.war),以便可以通过在主类中使用以下代码启动Jetty 9的嵌入式副本,通过外壳中的java -jar webapp.war
启动它:
I'm packaging a Web Application Archive (.war) so that it can be started via java -jar webapp.war
in a shell by launching an embedded copy of Jetty 9 using this code in a main class:
int port = Integer.parseInt(System.getProperty("port", "80")); // I know this has implications :)
String contextPath = System.getProperty("contextPath", "");
Server server = new Server(port);
ProtectionDomain domain = Deployer.class.getProtectionDomain();
URL location = domain.getCodeSource().getLocation();
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/" + contextPath);
webapp.setWar(location.toExternalForm());
server.setHandler(webapp);
server.start();
server.join();
但是,当第一个包含JSTL taglib声明的JSP被编译时,我会遇到此错误:
However, I'm running into this error when the first JSP containing a JSTL taglib declaration gets compiled:
org.apache.jasper.JasperException: /WEB-INF/html/user/login.jsp(2,62) PWC6188: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:92)
at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:378)
at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:172)
at org.apache.jasper.compiler.TagLibraryInfoImpl.generateTLDLocation(TagLibraryInfoImpl.java:431)
at org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:240)
at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:502)
at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:582)
at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1652)
at org.apache.jasper.compiler.Parser.parse(Parser.java:185)
at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:244)
at org.apache.jasper.compiler.ParserController.parse(ParserController.java:145)
at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:212)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:451)
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:625)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:492)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:378)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:698)
etc...
该JSP的前几行如下:
The first couple lines of that JSP are as follows:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" isELIgnored="false" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
我已经查看了很多时间(这似乎不是一个新问题),并尝试了以下解决方案:
I've looked around quite a bit (this doesn't seem to be a new issue) and have tried the following solutions:
- 精简我的依赖关系并查找冲突(当前我仅依赖于
jetty-server
,jetty-webapp
和jetty-jsp
,所有版本为9.0.4.v20130625
) - 在web应用程序的web.xml文件中指定一个直接指向JSTL的显式
<taglib>
映射(通过阅读JSP规范就可以了) - 按照此答案 修改服务器类路径
- 利用诸如
addServerClass
和setParentLoaderPriority
之类的WebAppContext方法的优势
- Slimming down my dependencies and looking for conflicts (currently I'm only depending on
jetty-server
,jetty-webapp
, andjetty-jsp
, all version9.0.4.v20130625
) - Specifying an explicit
<taglib>
mapping in the webapp's web.xml file that points to JSTL directly (got this idea from reading the JSP spec) - Modifying the server classpath as per this answer
- Taking advantage of methods of WebAppContext such as
addServerClass
andsetParentLoaderPriority
根据使用JSTL的Jetty文档应该可以正常工作,但我认为嵌入式上下文可能会改变JSTL的加载方式并导致失败.
According to Jetty's documentation, using JSTL should just work, but I think the embedded context may be changing the way JSTL gets loaded and causing it to fail.
将感谢您的任何想法或建议.此安装程序将替换一个较旧的安装程序,该安装程序在Windows上成功完成了相同的操作,但由于包含了引入此错误.不幸的是,我无法找到没有引入上述JSTL URI堆栈跟踪的依赖关系(groupId org.mortbay.jetty
artifactId jsp-2.1-glassfish
版本2.1.v20100127
)的快速替代品.
Would appreciate any ideas or suggestions. This setup would be replacing an older setup that did the same thing successfully on Windows but was not functioning on Linux due to the inclusion of an old dependency that brought in this bug. Unfortunately, I haven't been able to find a quick replacement for that dependency (groupId org.mortbay.jetty
artifactId jsp-2.1-glassfish
version 2.1.v20100127
) that doesn't introduce the JSTL URI stack trace mentioned above.
更新:我找到了次优的解决方案.受此线程启发,降级到Jetty 7现在有了我启动并运行.这是个好消息,但令人沮丧的是,如果以后我需要Jetty 8或Jetty 9专有的任何功能,则必须取消此部署基础结构.在Jetty 9中对JSTL taglib问题的任何见解仍将不胜感激.
UPDATE: I've found a suboptimal solution. A downgrade to Jetty 7 inspired by this thread now has me up and running. This is great news, but it's discouraging that if I later required any functionality exclusive to Jetty 8 or Jetty 9 that I'd have to scrap this deployment infrastructure. Any insight on JSTL taglib issue in Jetty 9 would still be appreciated.
推荐答案
遗憾的是,到目前为止,没有任何答案对我有用.但是我终于找到了解决我问题的方法.这听起来像是一种hack,而且绝对感觉像是一种.
Sadly, none of the answers so far have worked for me. But I finally found a solution to my issue. This is going to sound like a hack, and it definitely feels like one.
但是,如果我按照问题中的描述进行了所有设置,直到JSTL无法解决,我就可以采取措施使一切正常运行,就像魔术一样.
But if I get everything set up just as I described in my question, up to the point where the JSTL won't resolve, I can then take one step that makes everything work, almost like magic.
导致这种隐患的步骤是将.war
文件的扩展名更改为.jar
.一旦这样做,JSTL就可以很好地解析,并且一切正常.
That cringe-inducing step is changing the extension on the .war
file to .jar
. Once I do that, the JSTL resolves just fine, and everything works.
因此,现在我生成一个.war
,您可以将其放入servlet容器中,也可以重命名为.jar
并独立运行.它可以在Unix和Windows上运行,但是由于James Cook提到的jsp-2.1-glassfish
库中存在一个错误,因此我以前的操作方式在Unix上不起作用.
So right now I produce a .war
that you can stick into a servlet container or you can rename to .jar
and run standalone. And it works on both Unix and Windows, whereas the way I was doing this before wouldn't work on Unix due to a bug present in the jsp-2.1-glassfish
library mentioned by James Cook.
我pom中的相关内容:
The relevant bits from my pom:
<properties>
<jetty.version>9.0.5.v20130815</jetty.version>
<war.class>com.domain.package.DeployWebapp</war.class>
<war.class.path>com/domain/package</war.class.path>
</properties>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>${jetty.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jsp</artifactId>
<version>${jetty.version}</version>
<scope>provided</scope>
</dependency>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>main-class-placement</id>
<phase>prepare-package</phase>
<configuration>
<tasks>
<move todir="${project.build.directory}/${project.artifactId}-${project.version}/${war.class.path}">
<fileset dir="${project.build.directory}/classes/${war.class.path}">
<include name="DeployWebapp.class" />
</fileset>
</move>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>jetty-classpath</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>org.eclipse.jetty,javax.servlet,javax.el,org.glassfish.web,org.eclipse.jetty.orbit,org.ow2.asm,javax.annotation</includeGroupIds>
<outputDirectory>
${project.build.directory}/${project.artifactId}-${project.version}
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<attachClasses>true</attachClasses>
<archiveClasses>true</archiveClasses>
<archive>
<manifest>
<mainClass>${war.class}</mainClass>
</manifest>
</archive>
<packagingExcludes>META-INF/*.SF</packagingExcludes>
<packagingExcludes>META-INF/*.DSA</packagingExcludes>
<packagingExcludes>META-INF/*.RSA</packagingExcludes>
</configuration>
</plugin>
这篇关于如何获得嵌入式Jetty 9以成功解析JSTL URI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!