过去几天我一直在尝试不同的事情,但我还是没有设法让它发挥作用。
我正在尝试创建一个带有嵌入式jetty的jar,可以运行java -jar MyApp.jar
。 Servlet工作,没有taglib行的jsp文件可以正常工作,否则我得到500 Server not found错误:
org.apache.jasper.JasperException: 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
的build.gradle
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'application'
sourceCompatibility = 1.8
targetCompatibility = 1.8
mainClassName = "hello.App"
jar {
manifest {
attributes 'Main-Class': 'hello.App'
}
}
task fatJar(type: Jar) {
manifest {
attributes 'Main-Class': 'hello.App'
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it :zipTree(it) } }
with jar
}
repositories {
mavenCentral()
}
def jettyVersion = '9.4.5.v20170502'
dependencies {
compile group: 'org.eclipse.jetty', name: 'jetty-webapp', version: jettyVersion
compile group: 'org.eclipse.jetty', name: 'jetty-servlets', version: jettyVersion
compile group: 'org.eclipse.jetty', name: 'jetty-annotations', version: jettyVersion
compile group: 'org.eclipse.jetty', name: 'apache-jsp', version: jettyVersion
compile group: 'org.eclipse.jetty', name: 'apache-jstl', version: jettyVersion
compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.2'
compile group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.7.7'
}
的web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd" version="3.0">
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>hello.HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
JettyServer.java
package hello.jetty;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JettyServer {
private static final Logger log = LoggerFactory.getLogger(JettyServer.class);
public static final String WEBAPP_RESOURCES_LOCATION = "webapp";
private static final int DEFAULT_PORT_START = 8080;
private static final int DEFAULT_PORT_STOP = 8090;
private final int startPort;
private final int stopPort;
public JettyServer() {
this(DEFAULT_PORT_START, DEFAULT_PORT_STOP);
}
public JettyServer(int startPort, int stopPort) {
this.startPort = startPort;
this.stopPort = stopPort;
}
public void start() throws Exception {
Server server = new Server(startPort);
WebAppContext root = new WebAppContext();
root.setContextPath("/");
root.setDescriptor(WEBAPP_RESOURCES_LOCATION + "/WEB-INF/web.xml");
URL webAppDir = Thread.currentThread().getContextClassLoader().getResource(WEBAPP_RESOURCES_LOCATION);
if (webAppDir == null) {
throw new RuntimeException(String.format("No %s directory was found in the JAR file", WEBAPP_RESOURCES_LOCATION));
}
root.setResourceBase(webAppDir.toURI().toString());
root.setParentLoaderPriority(true);
//Enable JSP & JSTL support
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");
root.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$" );
server.setHandler(root);
server.start();
log.info("Jetty server started");
log.debug("Jetty web server port: {}", startPort);
log.debug("Port to stop Jetty with the 'stop' operation: {}", stopPort);
Monitor monitor = new Monitor(stopPort, new Server[]{server});
monitor.start();
server.join();
log.info("Jetty server exited");
}
public void stop() {
stop(DEFAULT_PORT_STOP);
}
public void stop(Integer stopPort) {
try {
Socket s = new Socket(InetAddress.getByName("127.0.0.1"), stopPort);
log.info("Jetty stopping...");
s.setSoLinger(false, 0);
OutputStream out = s.getOutputStream();
out.write(("stop\r\n").getBytes());
out.flush();
s.close();
} catch (ConnectException e) {
log.info("Jetty not running!");
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
public static void main(String[] args) throws Exception {
JettyServer jettyServer = new JettyServer();
jettyServer.start();
}
}
的index.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="en">
<body>
<%= new java.util.Date() %>
<br>
<br>
<c:out var="${1+2}" />
</body>
</html>
如何让jetty显示index.jsp文件?
更新:以下是gradle拉入的jar文件:
jetty-webapp-9.4.5.v20170502.jar
jetty-servlets-9.4.5.v20170502.jar
jetty-annotations-9.4.5.v20170502.jar
apache-jsp-9.4.5.v20170502.jar
apache-jstl-9.4.5.v20170502.jar
logback-classic-1.1.2.jar
jcl-over-slf4j-1.7.7.jar
jetty-xml-9.4.5.v20170502.jar
jetty-servlet-9.4.5.v20170502.jar
jetty-continuation-9.4.5.v20170502.jar
jetty-http-9.4.5.v20170502.jar
jetty-util-9.4.5.v20170502.jar
jetty-io-9.4.5.v20170502.jar
jetty-plus-9.4.5.v20170502.jar
javax.annotation-api-1.2.jar
asm-5.1.jar
asm-commons-5.1.jar
jetty-schemas-3.1.jar
javax.servlet-api-3.1.0.jar
apache-jsp-8.5.9.1.jar
ecj-4.4.2.jar
taglibs-standard-spec-1.2.5.jar
taglibs-standard-impl-1.2.5.jar
logback-core-1.1.2.jar
jetty-security-9.4.5.v20170502.jar
jetty-jndi-9.4.5.v20170502.jar
asm-tree-5.1.jar
apache-el-8.5.9.1.jar
jetty-server-9.4.5.v20170502.jar
slf4j-api-1.7.7.jar
在阅读本文时,我注意到apache-jsp在那里有两个不同的版本。可能有重复的罐子是我的问题?如果是这样,我如何让gradle排除其中一个?
答案 0 :(得分:0)
这些不是重复的罐子,它们是两个不同的组ID,分别来自org.eclipse.jetty,一个来自org.mortbay.jasper。
我假设您的胖罐包含已从依赖罐中解压缩的所有类等。因此,您将不得不向org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern添加一个模式,该模式引用jar中这些类的位置:通常该模式包含jar文件名的模式列表检查tlds,但在你的情况下,tlds不包含在jar文件中。此外,我会仔细检查类加载器是否是URLClassloader:jetty遍历类加载器层次结构,寻找URLClassLoaders,它应该询问并匹配模式。
最后,IIWY,我不会这样做:)我会预先编译所有的jsps并将它们打包到你的胖罐中,这样你就可以消除所有即时发现和编译的问题。