简体   繁体   English

无法在JBoss 6.4 EAP中部署Spring Boot EAR

[英]Can't Deploy Spring Boot EAR in JBoss 6.4 EAP

Edit 编辑

Alright, so it looks like the SpringBootServletInitializer isn't detected because it's inside a JAR in the EAR, not the WAR. 好吧,所以看起来没有检测到SpringBootServletInitializer因为它位于EAR中的JAR内部,而不是WAR。 What I did was make a new module and included it in my WAR. 我做的是制作一个新模块并将其包含在我的WAR中。 This contained a META-INF directory with a services folder. 这包含一个带有services文件夹的META-INF目录。 That services folder has a single file ( javax.servlet.ServletContainerInitializer ) with the contents org.springframework.web.SpringServletContainerInitializer . 该services文件夹有一个文件( javax.servlet.ServletContainerInitializer ),其内容为org.springframework.web.SpringServletContainerInitializer This then tries to deploy the WAR, but fails with the following: 然后尝试部署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

Again, it looks like the Servlet API is conflicting with another - but there's only the one on the classpath from what I can tell (and I even scoped it as provided for this test). 同样,看起来Servlet API与另一个相冲突 - 但是我可以告诉它只有类路径上的那个(我甚至将它作为此测试提供的范围)。

Original 原版的

Currently I'm having a few issues deploying a Spring-Boot (1.3.2.RELEASE) EAR in JBoss 6.4 EAP. 目前我在JBoss 6.4 EAP中部署Spring-Boot(1.3.2.RELEASE)EAR时遇到了一些问题。 The EAR file simply wraps a skinny WAR and all the JARs in a /lib folder. EAR文件只是将一个瘦的WAR和所有JAR包装在/ lib文件夹中。

I had previously made the changes required to deploy the WAR file, but we've unfortunately run into the requirement that the deployment has to be an EAR. 我之前已经进行了部署WAR文件所需的更改,但遗憾的是我们遇到了部署必须是EAR的要求。

Deploying as a WAR 部署为WAR

To deploy the application as a WAR, I changed the following: 要将应用程序部署为WAR,我更改了以下内容:

pom.xml 的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-deployment-structure.xml 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 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);
    }

}

These changes worked fine, and I could now deploy the WAR to JBoss 6.4. 这些更改工作正常,我现在可以将WAR部署到JBoss 6.4。

Deploying as an EAR 部署为EAR

This is where the trouble starts. 这就是麻烦开始的地方。 I created a new module to build the EAR file using the maven-ear-plugin: 我使用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>

I also added the jboss-deployment-structure.xml under /src/main/application/META-INF, so that it would be included in the EAR (it needs to be at the highest level). 我还在/ src / main / application / META-INF下添加了jboss-deployment-structure.xml ,以便它包含在EAR中(它需要处于最高级别)。 Trying to deploy this results in "success", but JBoss never tries to deploy the WAR inside the EAR. 尝试部署这会导致“成功”,但JBoss从不尝试在EAR中部署WAR。 It seems that a web.xml is needed. 似乎需要一个web.xml。

So looking at the docs, it seems that I need to define a web.xml like follows: 所以看看文档,似乎我需要定义一个如下的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>

Now there is some additional configuration if I want to drop to Servlet 2.5 - but I don't want to do this. 现在有一些额外的配置,如果我想要下载到Servlet 2.5 - 但我不想这样做。

Attempting to deploy this results in the following exception: 尝试部署此结果会导致以下异常:

    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$000(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$1.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)

This would seem that there's a mismatch in the servlet versions being loaded, but I can't seem to verify that it is (or exclude it). 这似乎是加载的servlet版本不匹配,但我似乎无法验证它是(或排除它)。 I've tried setting the scope to provided (so the JBoss version takes over), but this results in the following error: 我已经尝试将范围设置为提供(因此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]

Clearly it's using the JBoss 3.0 servlet spec, but it would seem the actual servlet 3.0 JAR is missing. 显然,它使用的是JBoss 3.0 servlet规范,但似乎缺少实际的servlet 3.0 JAR。

Is there something that I'm missing? 有什么东西我不见了吗? Does the WAR actually need a web.xml, or is there some other way? WAR实际上是否需要web.xml,还是有其他方式? Is what I'm trying even possible? 我正在尝试甚至可能吗?

Any help would be greatly appreciated. 任何帮助将不胜感激。

Fixed the issue. 修复了这个问题。 Starting from the WAR deployment, I made an additional EAR module. 从WAR部署开始,我制作了一个额外的EAR模块。 I shouldn't have used a skinnyWar, and instead left all the JARs inside the WAR. 我不应该使用skinnyWar,而是将所有JAR保留在WAR中。 This allows Spring to properly bootstrap the Spring Boot servlet. 这允许Spring正确引导Spring Boot servlet。

This has the following configuration: 这具有以下配置:

<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>

I also made sure that there were no compile scoped dependencies in my parent module (the root pom). 我还确保在我的父模块(根pom)中没有编译范围的依赖项。

I then made sure to have the following file in my EAR: 然后我确保在我的EAR中有以下文件:

src/main/application/META-INF/jboss-deployment-structure.xml

While this was in my WAR, the main problem I had was that I was still using <deployment> instead of <sub-deployment> 虽然这是在我的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>

This properly excludes the javaee.api module and the jpa subsystem. 这正确地排除了javaee.api模块和jpa子系统。

After this, the EAR deployed correctly to JBoss. 在此之后,EAR正确部署到JBoss。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM