Tuomas Toivonen
Tuomas Toivonen

Reputation: 23472

Spring application deployment fails on Weblogic 12c

My Spring application deploys fine on Weblogic 11g. However, when I try to deploy on Weblogic 12c, I keep getting ClassNotFoundException's one after another.

First of, I get java.lang.ClassNotFoundException: com.querydsl.core.types.Expression, which I solved by adding the missing dependency. Then I get familiar exception, but this time the missing class was from package com.mysema.querydsl. After introducing this dependency, I get the following exception: java.lang.ClassNotFoundException: org.apache.abdera.writer.Writer.

Why did the application got completely broken after migrating to Weblogic 12c (as Spring shouldn't be coupled with the container)?

Here are all the dependencies of the project before migrating:

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

Upvotes: 5

Views: 7331

Answers (3)

Kalpesh Soni
Kalpesh Soni

Reputation: 7257

This was fixed in later releases by spring data jpa

https://jira.spring.io/browse/DATAJPA-1175

use v1.10.12 or above

Upvotes: 3

Anitta
Anitta

Reputation: 1

I had a similar issue but with NamedParameterJdbcTemplate.

   java.lang.NoSuchMethodException: org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForLong(java.lang.String, org.springframework.jdbc.core.namedparam.SqlParameterSource)

Errors were encountered while performing this operation.

What worked for my project: in weblogic.xml file from WEB-INF add:

<wls:prefer-web-inf-classes>false</wls:prefer-web-inf-classes>
<wls:prefer-application-packages>
   <wls:package-name>org.springframework.jdbc.core.*</wls:package-name>
   <wls:package-name>org.springframework.jdbc.core.namedparam.*</wls:package-name>
</wls:prefer-application-packages>

You can read more about this → https://docs.oracle.com/cd/E24329_01/web.1211/e21049/weblogic_xml.htm#WBAPP602

--- Additional info ---

In the EAR module I have weblogic-application.xml placed under src/application/META-INF but somehow it's not taken into consideration. And the WAR module has weblogic.xml created under src/src/main/webapp/WEB_INF

Tried the first answer (add a new weblogic.xml in src/src/main/resources) got IncompatibleClassChangeError.

Upvotes: 0

Adam Sojka
Adam Sojka

Reputation: 391

The general problem is that Weblogic has many libraries bundled. When an application is deployed the class loader might either load the one bundled with Weblogic or from the application.

Weblogic 12c has additional libraries bundled and therefore an exception might be thrown because the jar contains older version of the same library and some classes/methods might not be present in that jar.

The workaround is to deploy EAR that packages your WAR file and specifying the preferred libraries. This way your libraries will loaded instead of the Weblogic previous version.

In order to deploy EAR you need to create a new Maven module with ear packaging and include weblogic-application.xml which needs to be placed under src/application/META-INF.

The file needs to specify preferred packages that should be loaded from the application and not Weblogic for example:

<prefer-application-packages>
    <package-name>com.querydsl.*</package-name>
    ...
</prefer-application-packages>

In the EAR module in it's pom.xml you need specify that this file needs to be included by providing the following information in ear plugin:

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

Last thing, the WAR module needs to have weblogic.xml created under /src/main/resources with two sections:

<context-root>**yourContext**</context-root>
<container-descriptor>
    <prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>

The "yourContext" need to match the same one provided in maven-ear-plugin and should be the web context of the application.

Upvotes: 2

Related Questions