如何让JSF在docker容器中使用spring-boot app?

时间:2016-10-12 14:55:09

标签: jsf docker spring-boot

我有一个使用spring-boot 1.4.0和JSF 2.2(Mojarra 2.2.13)在嵌入式tomcat(8.5)上运行的应用程序。

当我运行应用本地时,它运行正常 - 无论我是使用mvn spring-boot:run还是java -jar target/myapp.jar

从我的IDE启动它

但是,当我在Docker容器中启动应用程序 时(使用docker 1.12.1),JSF页面的所有内容都 除外。例如像/health这样的spring-boot-actuator页面工作得很好,但是当我试图访问/home.xhtml(一个JSF页面)时,我得到了:

Whitelabel错误页面

此应用程序没有/error的明确映射,因此您将此视为后备。

Wed 10月12日09:33:33 GMT 2016 出现意外错误(type = Not Found,status = 404)。 /home.xhtml Not Found in ExternalContext as a Resource

我使用io.fabric8:docker-maven-plugin构建docker镜像(基于alpine与openjdk-8-jre),其中包括docker容器内/maven下的构建工件和java -jar /maven/${project.artifactId}-${project.version}.jar以启动应用程序。

我使用端口9000而不是标准的tomcat端口(8080),这也是docker镜像公开的。

我已经比较了本地jar和docker容器中包含的jar,它们都具有相同的内容。

任何帮助将不胜感激。 提前致谢

3 个答案:

答案 0 :(得分:3)

XHTML文件和其他JSF文件放在错误的目录中。

至少在使用<packaging>jar</packaging>时,似乎所有JSF内容都必须放在src/main/resources/META-INF而不是src/main/webapp下,而大多数IDE会自动放置它。

当JSF内容在src/main/webapp中时,它不会被包含(或者不在正确的位置)到spring-boot-repackaged jar文件中。

我的src/main/resources现在看起来像这样:

src
└── main
    └── resources
        ├── application.yml
        └── META-INF
            ├── faces-config.xml
            └── resources
                ├── administration
                │   └── userlist.xhtml
                ├── css
                │   └── default.css
                ├── images
                │   └── logo.png
                └── home.xhtml

答案 1 :(得分:1)

我有完全相同的问题。直接从maven或打包的WAR文件运行Spring Boot应用程序运行正常,但从Docker容器运行它会导致同样的问题。

实际上,对我来说问题是访问动态资源(JSP等)总是导致尝试显示无法找到的错误页面,因此返回了404,但是正确返回了静态内容。 / p>

这听起来很愚蠢,但事实证明,当你启动它时,是否要将打包的WAR文件称为“.war”或“.jar”。我使用了一个Docker示例进行Spring Boot(由于某种原因)将WAR文件命名为“app.jar”。如果这样做,您将在Docker容器中遇到此问题。如果你把它称为“app.war”,它可以正常工作。

顺便说一句,这与Docker无关。如果您尝试在主机上具有.jar扩展名时直接在主机上启动应用程序,则会发生同样的情况(除非您在所需资源以提取的方式处于其中的位置启动它)。

使用

启动我的应用程序
java -Duser.timezone=UTC -Djava.security.egd=file:/dev/./urandom -jar application.jar

导致错误。从.jar重命名为.war并使用

java -Duser.timezone=UTC -Djava.security.egd=file:/dev/./urandom -jar application.war

让它发挥作用。

答案 2 :(得分:0)

对我有用的是在添加资源时将 webapp 文件夹复制到 META-INF

<resource>
  <directory>src/main/webapp</directory>
  <targetPath>META-INF/resources</targetPath>
</resource>

然后添加更改 documentRoot 到它在 docker 容器中可用的路径:

@Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
  webServerFactoryCustomizer() {
    return factory -> factory.setDocumentRoot(new File("/workspace/META-INF/resources"));
}

现在我可以在使用 spring-boot:build-image 和 jar 包装的同时使用 jsf 页面

ps:我仍然有一堆异常,在将 spring boot+liquibase 升级到最新版本后就消失了,但我认为这不属于这个主题