8

我想要做的是构建一个JAR包含我的项目的可执行文件。我已经在它旁边包含了它的依赖项,也在JAR文件中,所以我的目录列表看起来像这样:

〜/项目/Java/web-app/out:

web-app.jar

依赖1.jar

依赖项2.jar

依赖项3.jar

我知道并且确信我的问题不是由依赖关系引起的,因为我的应用程序运行正常,直到我启动嵌入式 Jetty 的那一刻。

我用来启动 Jetty 的代码是这样的:

public class ServerExecutionGoal implements ExecutionGoal {    

    private final static Logger logger = Logger.getLogger(ServerExecutionGoal.class);    

    private WebAppContext getWebAppContext() throws IOException {    
        WebAppContext context = new WebAppContext();    
        System.out.println("context = " + context);    
        context.setResourceBase(new PathMatchingResourcePatternResolver().getResource("classpath:/webapp").getURL().toExternalForm());    
        context.setContextPath("/");    
        context.setLogger(new StdErrLog());    
        return context;    
    }    

    @Override    
    public void execute(Map<String, Object> stringObjectMap) throws ExecutionTargetFailureException {    
        logger.info("Instantiating target server ...");    
        final Server server = new Server(8089);    
        final ContextHandlerCollection handlerCollection = new ContextHandlerCollection();    
        try {    
            handlerCollection.setHandlers(new Handler[]{new RequestLogHandler(), getWebAppContext()});    
        } catch (IOException e) {    
            throw new ExecutionTargetFailureException("Could not create web application context", e);    
        }    
        server.setHandler(handlerCollection);    
        try {    
            logger.info("Starting server on port 8089 ...");    
            server.start();    
            server.join();    
            logger.info("Server started. Waiting for requests.");    
        } catch (Exception e) {    
            throw new ExecutionTargetFailureException("Failed to properly start the web server", e);    
        }    
    }    

    public static void main(String[] args) throws ExecutionTargetFailureException {    
        new ServerExecutionGoal().execute(null);    
    }    

}    

我可以验证“webapp”文件夹在我的 JAR 中正确重定位到/webapp,并且当通过我的 IDE (IntelliJ IDEA 11) 运行代码时context.setResourceBase(new PathMatchingResourcePatternResolver().getResource("classpath:/webapp").getURL().toExternalForm())有效地映射到有问题的资源。此外,我可以证明它可以解析为:

jar:file:~/Projects/Java/web-app/out/web-app.jar!/webapp

并且可以访问(我读过)。

但是,当我启动应用程序的 main 方法并启动 Jetty 时,http://localhost:8089我得到以下信息:

HTTP 错误:503

访问 / 时出现问题。原因:

Service Unavailable

由码头提供支持://

我哪里错了?

我知道通过将“resourceBase”设置为“。” 地址 " http://localhost:8089" 将充当位置 " ~/Projects/Java/web-app/out/" 的接口,在单击时我可以在其中看到所有JAR文件的列表,包括 " web-app.jar",我可以下载它。

我看过以下问题,答案不适用:

  1. 嵌入式码头应用程序无法从 jar 工作:我得到 NullPointerException,因为Start.class.getProtectionDomain().getCodeSource()解析为null.
  2. Embedded Jetty WebAppContext FilePermission 问题:不仅没有回答,而且情况显然不适用,因为我没有权限问题(我可以获得文件列表的事实应该证明这一点)。
  3. 嵌入码头服务器问题:也没有答案,也不适用,因为我没有任何依赖问题(正如我之前在上面的评论中指出的那样)。

我认为我应该以某种方式使 Jetty 能够访问该/webapp文件夹,该文件夹位于我的src/main/resources/目录下并捆绑到我的 Web 应用程序中。我是否应该放弃捆绑的 Web 应用程序并将展开的上下文路径部署到 Jetty 可访问的某个地方(这根本不可取,因为它给我和我的客户带来了许多问题)。

4

2 回答 2

1

我不确定,如果WebAppContextJetty 可以与PathMatchingResourcePatternResolver!

在我的一个项目中,我通过编写自己的javax.servlet.Filter. 加载请求的资源来解决这个问题Class#getResourceAsStreamClass#getResourceAsStream从 jars 内部以及资源路径(例如 maven)内部读取资源。

希望这个技巧对你有帮助,干杯 Thilo

于 2017-05-04T18:05:05.267 回答
0

我相信,几个月前我遇到了类似的问题,我使用了 Jetty v9.4.12.v20180830。

这是我的解决方案:

如果您有以下生成的 JAR 结构:

 app.jar
   +----- com /
   |        +--- ( classes ... )
   |
   +----- config /
   |        |
   |        +--- display.properties
   |
   +----- webapp /
            |
            +--- index.html

然后以下代码将引用正确的文件夹:

ServletContextHandler webappContext = new ServletContextHandler(ServletContextHandler.SESSIONS);  
URL webRootLocation = YourJettyStarterClass.class.getResource("/webapp/index.html");  
URI webRootUri = URI.create(webRootLocation.toURI().toASCIIString().replaceFirst("/index.html$", "/"));  
webappContext.setContextPath("/");
webappContext.setBaseResource(Resource.newResource(webRootUri));
webappContext.setWelcomeFiles(new String[] { "index.html" });  

重要的部分:

URL webRootLocation = YourJettyStarterClass.class.getResource("/webapp/index.html");   
于 2019-06-28T19:47:45.143 回答