无法在 JBoss 6.4 EAP 中部署 Spring 引导 EAR
Can't Deploy Spring Boot EAR in JBoss 6.4 EAP
编辑
好的,看起来 SpringBootServletInitializer
没有被检测到,因为它在 EAR 的 JAR 中,而不是 WAR。我所做的是制作一个新模块并将其包含在我的 WAR 中。这包含一个带有服务文件夹的 META-INF 目录。该服务文件夹有一个文件 (javax.servlet.ServletContainerInitializer
),其内容为 org.springframework.web.SpringServletContainerInitializer
。然后尝试部署 WAR,但失败并显示以下内容:
Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: JBAS018104: Deployment error processing SCI for jar: test-1.0.0-SNAPSHOT.jar
at org.jboss.as.web.deployment.ServletContainerInitializerDeploymentProcessor.loadSci(ServletContainerInitializerDeploymentProcessor.java:202)
... 7 more
Caused by: java.lang.ClassCastException: org.springframework.web.SpringServletContainerInitializer cannot be cast to javax.servlet.ServletContainerInitializer
at org.jboss.as.web.deployment.ServletContainerInitializerDeploymentProcessor.loadSci(ServletContainerInitializerDeploymentProcessor.java:194)
... 7 more
再次,看起来 Servlet API 与另一个冲突 - 但据我所知,类路径上只有一个(我什至按照此测试提供的范围限定了它)。
原创
目前我在 JBoss 6.4 EAP 中部署 Spring-Boot (1.3.2.RELEASE) EAR 时遇到一些问题。 EAR 文件简单地包装了一个瘦 WAR 和 /lib 文件夹中的所有 JAR。
我之前进行了部署 WAR 文件所需的更改,但不幸的是,我们已经 运行 要求部署必须是 EAR。
部署为 WAR
为了将应用程序部署为 WAR,我更改了以下内容:
pom.xml
<!-- JavaEE 7 for JPA 2.1 -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<!-- Exclude Tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Include Servlet 3 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
jboss-部署-structure.xml
<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclude-subsystems>
<subsystem name="jpa"/>
</exclude-subsystems>
<exclusions>
<module name="javaee.api"/>
</exclusions>
</deployment>
</jboss-deployment-structure>
Application.java
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
private static final Class<Application> APPLICATION_CLASS = Application.class;
public static void main(String[] args) {
SpringApplication.run(APPLICATION_CLASS, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(APPLICATION_CLASS);
}
}
这些更改工作正常,我现在可以将 WAR 部署到 JBoss 6.4。
部署为 EAR
这就是麻烦的开始。我使用 maven-ear-plugin 创建了一个新模块来构建 EAR 文件:
<build>
<finalName>my-application</finalName>
<plugins>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10.1</version>
<configuration>
<version>6</version>
<skinnyWars>true</skinnyWars>
<defaultLibBundleDir>lib</defaultLibBundleDir>
<fileNameMapping>no-version</fileNameMapping>
<modules>
<webModule>
<groupId>com.test.app</groupId>
<artifactId>my-application</artifactId>
<bundleFileName>my-application.war</bundleFileName>
<context-root>/my-app</context-root>
</webModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>
我还在/src/main/application/META-INF下添加了jboss-deployment-structure.xml
,这样它就会包含在EAR中(它需要在最高级别)。尝试在 "success" 中部署此结果,但 JBoss 从未尝试在 EAR 中部署 WAR。好像需要一个web.xml
因此查看文档,似乎我需要定义一个 web.xml,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.test.app.Application</param-value>
</context-param>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
如果我想使用 Servlet 2.5,现在还有一些额外的配置 - 但我不想这样做。
尝试部署它会导致以下异常:
10:29:40,586 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/company-api-entity]] (ServerService Thread Pool -- 56) JBWEB000289: Servlet appServlet threw load() exception: java.lang.ClassCastException: org.springframework.web.servlet.DispatcherServlet cannot be cast to javax.servlet.Servlet
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1154) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1100) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3593) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
at org.apache.catalina.core.StandardContext.start(StandardContext.java:3802) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
at org.jboss.as.web.deployment.WebDeploymentService.doStart(WebDeploymentService.java:163) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.as.web.deployment.WebDeploymentService.access[=18=]0(WebDeploymentService.java:61) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.as.web.deployment.WebDeploymentService.run(WebDeploymentService.java:96) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [rt.jar:1.8.0_45]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_45]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_45]
at org.jboss.threads.JBossThread.run(JBossThread.java:122)
这似乎是加载的 servlet 版本不匹配,但我似乎无法验证它是否存在(或排除)。我已经尝试将范围设置为提供(因此 JBoss 版本接管),但这会导致以下错误:
11:18:47,141 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/company-api-entity]] (ServerService Thread Pool -- 52) JBWEB000289: Servlet appServlet threw load() exception: java.util.MissingResourceException: Can't find bundle for base name javax.servlet.LocalStrings, locale en_IE
at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1564) [rt.jar:1.8.0_45]
at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1387) [rt.jar:1.8.0_45]
at java.util.ResourceBundle.getBundle(ResourceBundle.java:773) [rt.jar:1.8.0_45]
at javax.servlet.GenericServlet.<clinit>(GenericServlet.java:95) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar:1.0.2.Final-redhat-2]
显然它使用的是 JBoss 3.0 servlet 规范,但似乎缺少实际的 servlet 3.0 JAR。
有什么我想念的吗? WAR 是否真的需要 web.xml,还是有其他方法?我正在尝试的可能吗?
如有任何帮助,我们将不胜感激。
已解决问题。从 WAR 部署开始,我做了一个额外的 EAR 模块。我不应该使用 skinnyWar,而是将所有 JAR 留在 WAR 中。这允许 Spring 正确地 bootstrap Spring Boot servlet。
这具有以下配置:
<build>
<finalName>my-application</finalName>
<plugins>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10.1</version>
<configuration>
<modules>
<webModule>
<groupId>com.test.app</groupId>
<artifactId>my-application</artifactId>
<bundleFileName>my-application.war</bundleFileName>
<context-root>/my-app</context-root>
</webModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>
我还确保我的父模块(根 pom)中没有编译范围的依赖项。
然后我确保在我的 EAR 中有以下文件:
src/main/application/META-INF/jboss-deployment-structure.xml
虽然这是在我的 WAR 中,但我遇到的主要问题是我仍在使用 <deployment>
而不是 <sub-deployment>
<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<sub-deployment name="my-application.war">
<exclude-subsystems>
<subsystem name="jpa"/>
</exclude-subsystems>
<exclusions>
<module name="javaee.api"/>
</exclusions>
</sub-deployment>
</jboss-deployment-structure>
这正确地排除了 javaee.api
模块和 jpa
子系统。
此后,EAR 正确部署到 JBoss。
编辑
好的,看起来 SpringBootServletInitializer
没有被检测到,因为它在 EAR 的 JAR 中,而不是 WAR。我所做的是制作一个新模块并将其包含在我的 WAR 中。这包含一个带有服务文件夹的 META-INF 目录。该服务文件夹有一个文件 (javax.servlet.ServletContainerInitializer
),其内容为 org.springframework.web.SpringServletContainerInitializer
。然后尝试部署 WAR,但失败并显示以下内容:
Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: JBAS018104: Deployment error processing SCI for jar: test-1.0.0-SNAPSHOT.jar
at org.jboss.as.web.deployment.ServletContainerInitializerDeploymentProcessor.loadSci(ServletContainerInitializerDeploymentProcessor.java:202)
... 7 more
Caused by: java.lang.ClassCastException: org.springframework.web.SpringServletContainerInitializer cannot be cast to javax.servlet.ServletContainerInitializer
at org.jboss.as.web.deployment.ServletContainerInitializerDeploymentProcessor.loadSci(ServletContainerInitializerDeploymentProcessor.java:194)
... 7 more
再次,看起来 Servlet API 与另一个冲突 - 但据我所知,类路径上只有一个(我什至按照此测试提供的范围限定了它)。
原创
目前我在 JBoss 6.4 EAP 中部署 Spring-Boot (1.3.2.RELEASE) EAR 时遇到一些问题。 EAR 文件简单地包装了一个瘦 WAR 和 /lib 文件夹中的所有 JAR。
我之前进行了部署 WAR 文件所需的更改,但不幸的是,我们已经 运行 要求部署必须是 EAR。
部署为 WAR
为了将应用程序部署为 WAR,我更改了以下内容:
pom.xml
<!-- JavaEE 7 for JPA 2.1 -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<!-- Exclude Tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Include Servlet 3 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
jboss-部署-structure.xml
<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclude-subsystems>
<subsystem name="jpa"/>
</exclude-subsystems>
<exclusions>
<module name="javaee.api"/>
</exclusions>
</deployment>
</jboss-deployment-structure>
Application.java
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
private static final Class<Application> APPLICATION_CLASS = Application.class;
public static void main(String[] args) {
SpringApplication.run(APPLICATION_CLASS, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(APPLICATION_CLASS);
}
}
这些更改工作正常,我现在可以将 WAR 部署到 JBoss 6.4。
部署为 EAR
这就是麻烦的开始。我使用 maven-ear-plugin 创建了一个新模块来构建 EAR 文件:
<build>
<finalName>my-application</finalName>
<plugins>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10.1</version>
<configuration>
<version>6</version>
<skinnyWars>true</skinnyWars>
<defaultLibBundleDir>lib</defaultLibBundleDir>
<fileNameMapping>no-version</fileNameMapping>
<modules>
<webModule>
<groupId>com.test.app</groupId>
<artifactId>my-application</artifactId>
<bundleFileName>my-application.war</bundleFileName>
<context-root>/my-app</context-root>
</webModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>
我还在/src/main/application/META-INF下添加了jboss-deployment-structure.xml
,这样它就会包含在EAR中(它需要在最高级别)。尝试在 "success" 中部署此结果,但 JBoss 从未尝试在 EAR 中部署 WAR。好像需要一个web.xml
因此查看文档,似乎我需要定义一个 web.xml,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.test.app.Application</param-value>
</context-param>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
如果我想使用 Servlet 2.5,现在还有一些额外的配置 - 但我不想这样做。
尝试部署它会导致以下异常:
10:29:40,586 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/company-api-entity]] (ServerService Thread Pool -- 56) JBWEB000289: Servlet appServlet threw load() exception: java.lang.ClassCastException: org.springframework.web.servlet.DispatcherServlet cannot be cast to javax.servlet.Servlet
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1154) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1100) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3593) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
at org.apache.catalina.core.StandardContext.start(StandardContext.java:3802) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]
at org.jboss.as.web.deployment.WebDeploymentService.doStart(WebDeploymentService.java:163) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.as.web.deployment.WebDeploymentService.access[=18=]0(WebDeploymentService.java:61) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at org.jboss.as.web.deployment.WebDeploymentService.run(WebDeploymentService.java:96) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [rt.jar:1.8.0_45]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_45]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_45]
at org.jboss.threads.JBossThread.run(JBossThread.java:122)
这似乎是加载的 servlet 版本不匹配,但我似乎无法验证它是否存在(或排除)。我已经尝试将范围设置为提供(因此 JBoss 版本接管),但这会导致以下错误:
11:18:47,141 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/company-api-entity]] (ServerService Thread Pool -- 52) JBWEB000289: Servlet appServlet threw load() exception: java.util.MissingResourceException: Can't find bundle for base name javax.servlet.LocalStrings, locale en_IE
at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1564) [rt.jar:1.8.0_45]
at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1387) [rt.jar:1.8.0_45]
at java.util.ResourceBundle.getBundle(ResourceBundle.java:773) [rt.jar:1.8.0_45]
at javax.servlet.GenericServlet.<clinit>(GenericServlet.java:95) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar:1.0.2.Final-redhat-2]
显然它使用的是 JBoss 3.0 servlet 规范,但似乎缺少实际的 servlet 3.0 JAR。
有什么我想念的吗? WAR 是否真的需要 web.xml,还是有其他方法?我正在尝试的可能吗?
如有任何帮助,我们将不胜感激。
已解决问题。从 WAR 部署开始,我做了一个额外的 EAR 模块。我不应该使用 skinnyWar,而是将所有 JAR 留在 WAR 中。这允许 Spring 正确地 bootstrap Spring Boot servlet。
这具有以下配置:
<build>
<finalName>my-application</finalName>
<plugins>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10.1</version>
<configuration>
<modules>
<webModule>
<groupId>com.test.app</groupId>
<artifactId>my-application</artifactId>
<bundleFileName>my-application.war</bundleFileName>
<context-root>/my-app</context-root>
</webModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>
我还确保我的父模块(根 pom)中没有编译范围的依赖项。
然后我确保在我的 EAR 中有以下文件:
src/main/application/META-INF/jboss-deployment-structure.xml
虽然这是在我的 WAR 中,但我遇到的主要问题是我仍在使用 <deployment>
而不是 <sub-deployment>
<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<sub-deployment name="my-application.war">
<exclude-subsystems>
<subsystem name="jpa"/>
</exclude-subsystems>
<exclusions>
<module name="javaee.api"/>
</exclusions>
</sub-deployment>
</jboss-deployment-structure>
这正确地排除了 javaee.api
模块和 jpa
子系统。
此后,EAR 正确部署到 JBoss。