Spring 应用程序部署在 Weblogic 12c 上失败

Tuo*_*nen 5 java spring weblogic jar maven

我的 Spring 应用程序在 Weblogic 11g 上部署得很好。然而,当我尝试在 Weblogic 12c 上部署时,我不断收到ClassNotFoundException一个又一个的 。

首先,我得到了java.lang.ClassNotFoundException: com.querydsl.core.types.Expression,我通过添加缺少的依赖项解决了这个问题。然后我得到熟悉的异常,但这次缺少的类来自 package com.mysema.querydsl。引入此依赖项后,我得到以下异常:java.lang.ClassNotFoundException: org.apache.abdera.writer.Writer

为什么应用程序在迁移到 Weblogic 12c 后完全崩溃了(因为 Spring 不应该与容器耦合)?

以下是迁移前项目的所有依赖:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <spring.version>4.3.2.RELEASE</spring.version>
    <spring-data-jpa.version>1.10.2.RELEASE</spring-data-jpa.version>
    <spring-security.version>4.1.3.RELEASE</spring-security.version>
    <cxf.version>3.1.7</cxf.version>
    <jackson.version>1.9.13</jackson.version>
    <esapi.version>2.1.0.1</esapi.version>
    <hibernate-entitymanager.version>5.1.1.Final</hibernate-entitymanager.version>
    <hibernate-commons-annotations.version>5.0.1.Final</hibernate-commons-annotations.version>
    <spring-boot-starter-jdbc.version>1.5.2.RELEASE</spring-boot-starter-jdbc.version>
    <slf4j.version>1.7.21</slf4j.version>
    <log4j.version>1.2.17</log4j.version>
    <log.directory>logs</log.directory>
</properties>

<dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>3.0-alpha-1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Security -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-acl</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-ldap</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>2.2.0</version>
        </dependency>


        <!-- DB -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>${spring-data-jpa.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-jdbc</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-orm</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate-entitymanager.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.common</groupId>
            <artifactId>hibernate-commons-annotations</artifactId>
            <version>${hibernate-commons-annotations.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- DB end -->

        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <!-- Oracle JDBC -->
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc7</artifactId>
            <version>12.1.0.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
    </dependencies>
Run Code Online (Sandbox Code Playgroud)

Ada*_*jka 2

普遍的问题是 Weblogic 捆绑了许多库。部署应用程序时,类加载器可能加载与 Weblogic 捆绑在一起的类加载器,也可能加载来自应用程序的类加载器。

Weblogic 12c 捆绑了其他库,因此可能会引发异常,因为该 jar 包含同一库的旧版本,并且该 jar 中可能不存在某些类/方法。

解决方法是部署 EAR,将 WAR 文件打包并指定首选库。这样您的库将被加载,而不是 Weblogic 以前的版本。

为了部署 EAR,您需要创建一个带有 Ear 打包的新 Maven 模块,并包含需要放置在 src/application/META-INF 下的 weblogic-application.xml。

该文件需要指定应从应用程序而不是 Weblogic 加载的首选包,例如:

<prefer-application-packages>
    <package-name>com.querydsl.*</package-name>
    ...
</prefer-application-packages>
Run Code Online (Sandbox Code Playgroud)

在 EAR 模块的 pom.xml 中,您需要通过在ear插件中提供以下信息来指定需要包含该文件:

      <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ear-plugin</artifactId>
            <version>2.10.1</version>
            <configuration>
                <defaultLibBundleDir>lib</defaultLibBundleDir>
                <earSourceDirectory>src/application</earSourceDirectory>
                <modules>
                    <webModule>
                        <groupId>your-group-id</groupId>
                        <artifactId>your-artifact-id</artifactId>
                        <contextRoot>/**yourContext**</contextRoot>
                    </webModule>
                </modules>
            </configuration>
        </plugin>
    </plugins>
Run Code Online (Sandbox Code Playgroud)

最后一件事,WAR 模块需要在 /src/main/resources 下创建 weblogic.xml,其中包含两个部分:

<context-root>**yourContext**</context-root>
<container-descriptor>
    <prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
Run Code Online (Sandbox Code Playgroud)

“yourContext”需要与 maven-ear-plugin 中提供的相同,并且应该是应用程序的 Web 上下文。