如果作为 jar 启动,带有嵌入式 Jetty 的应用程序显示 "page not found"

Application with embedded Jetty showing "page not found" if launched as jar

我有一个使用嵌入式码头的应用程序。当我 运行 在 Netbeans IDE 中使用此应用程序时,我可以浏览我的站点 @ localhost:8080/

当我从命令行启动我的应用程序的 jar 文件时:java -jar app.jar 然后浏览 localhost:8080/ 码头服务器说“ 找不到页面

我在这里错过了什么?想不通问题。

编辑:

Netbeans 项目已上传到 Github

如果我在 Netbeans 中 运行 这个项目一切正常。 但是当我在 cmd 中使用 lib 文件夹和 运行 的 jar 文件时,如下所示: java -jar EmbeddedJettyJspJstl.jar

然后导航到 http://localhost:8080/test 我收到错误:

org.apache.jasper.JasperException: java.lang.ClassNotFoundException: org.apache.jsp.WEB_002dINF.jstl_jsp

org.apache.jasper.JasperException: 绝对 uri: http://java.sun.com/jsp/jstl/core 无法在 web.xml 或随此应用程序部署的 jar 文件中解析

我的 JSP 页面使用 JSTL,看起来它没有找到 jstl 库?

这是启动服务器的代码:

package server;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.AllowSymLinkAliasChecker;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author lkallas
 */
public class JettyServer {

    // Resource path pointing to where the WEBROOT is
    private static final String WEBROOT = "/webapp/";
    private static final Logger logger = LoggerFactory.getLogger(JettyServer.class);

    public void start() throws IOException, InterruptedException, URISyntaxException {

        Server server = new Server();

        // HTTP connector
        ServerConnector connector = new ServerConnector(server);
        connector.setHost("localhost");
        connector.setPort(8080);
        connector.setIdleTimeout(30000);

        // Set the connector
        server.addConnector(connector);

        // Setup JMX for web applications
        MBeanContainer mbContainer = new MBeanContainer(
                ManagementFactory.getPlatformMBeanServer());
        server.addBean(mbContainer);

        //Setting up web application
        WebAppContext webapp = new WebAppContext();
        webapp.setAttribute("javax.servlet.context.tempdir", getScratchDir());
        webapp.setDescriptor(WEBROOT + "WEB-INF/web.xml");
        webapp.setResourceBase(getWebRootResourceUri().toASCIIString());
        webapp.setContextPath("/");
        webapp.setWar(getWebRootResourceUri().toASCIIString());
        webapp.addAliasCheck(new AllowSymLinkAliasChecker());

        //For debugging
        logger.info("Descriptor file: {}", webapp.getDescriptor());
        logger.info("Resource base: {}", getWebRootResourceUri().toASCIIString());
        logger.info("WAR location: {}", webapp.getWar());

        HandlerList handlerList = new HandlerList();
        handlerList.setHandlers(new Handler[]{webapp, new DefaultHandler()});

        // This webapp will use jsps and jstl. We need to enable the
        // AnnotationConfiguration in order to correctly
        // set up the jsp container
        Configuration.ClassList classlist = Configuration.ClassList
                .setServerDefault(server);
        classlist.addBefore(
                "org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
                "org.eclipse.jetty.annotations.AnnotationConfiguration");

        // Set the ContainerIncludeJarPattern so that jetty examines these
        // container-path jars for tlds, web-fragments etc.
        // If you omit the jar that contains the jstl .tlds, the jsp engine will
        // scan for them instead.
        webapp.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/[^/]*taglibs.*\.jar$");

        // A WebAppContext is a ContextHandler as well so it needs to be set to
        // the server so it is aware of where to send the appropriate requests.
        server.setHandler(handlerList);

        try {
            server.start();

        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }

        server.dumpStdErr();

    }

    /**
     * Establish Scratch directory for the servlet context (used by JSP
     * compilation)
     */
    private File getScratchDir() throws IOException {
        File tempDir = new File(System.getProperty("java.io.tmpdir"));
        File scratchDir = new File(tempDir.toString(), "embedded-jetty");

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

    /**
     * Get webroot URI.
     *
     * @return
     * @throws FileNotFoundException
     * @throws URISyntaxException
     */
    private URI getWebRootResourceUri() throws FileNotFoundException, URISyntaxException {
        URL indexUri = this.getClass().getResource(WEBROOT);
        if (indexUri == null) {
            throw new FileNotFoundException("Unable to find resource " + WEBROOT);
        }
        logger.debug("WEBROOT: {}", indexUri.toURI().toASCIIString());
        return indexUri.toURI();
    }

}

我已经看过@http://www.eclipse.org/jetty/documentation/current/advanced-embedding.html

可能影响您的原因有很多。

但是您还没有发布任何代码来帮助我们确定具体原因。

Jetty 项目为此设置维护了一个示例,顺便说一句。

https://github.com/jetty-project/embedded-jetty-uber-jar

注意你的 context.setContextPath()(就像@Haider-Ali 指出的那样),还有你的 context.setBaseResource()

对于嵌入式 Jetty 中的 JSP,您可以查看其他示例项目

https://github.com/jetty-project/embedded-jetty-jsp

备注