1

I've got an EAR which contains a WAR and an EJB (jar). The EJB and the WAR share some libraries, so I wanted to produce a skinnyWar using maven-ear-plugin.

I have my ear pom configured with the shared libs as dependencies, and have the <skinnyWars> option set to true.

I see my EAR is properly built; the common libs are extracted from my WAR and placed in the EAR.

My problem, when I launch my EAR on Websphere 8.5, is that the WAR is unable to find classes which remain in the WAR/WEB-INF/lib folder.

I have checked the MANIFEST.MF in the war/META-INF/ and see that all the libs are listed (both those in the war/web-inf/lib folder as well as the common libs), however I keep getting ClassNotFoundException whenever I try to access classes from within the WEB-INF/lib/xxx.jar.

(snippets from the pom.xml)

<dependencies>
    <dependency>
        <groupId>com.webinfo</groupId>
        <artifactId>WebInfoWebApp</artifactId>
        <version>${project.version}</version>
        <type>war</type>
    </dependency>

    <dependency>
        <groupId>com.webinfo</groupId>
        <artifactId>WebInfoEJB</artifactId>
        <version>${project.version}</version>
        <type>ejb</type>
    </dependency>


    <!-- In order to make skinnyWars, need to list all the common dependencies of the EAR here -->
    <!-- Use the ejb pom to list all the ejb dependencies here automatically -->
    <dependency>
        <groupId>com.webinfo</groupId>
        <artifactId>WebInfoEJB</artifactId>
        <version>${project.version}</version>
        <type>pom</type>
    </dependency>
</dependencies>

<build>
    <plugins>
        <!-- EAR plugin -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ear-plugin</artifactId>
            <version>2.10</version>
            <configuration>
                <defaultLibBundleDir>/</defaultLibBundleDir>
                <skinnyWars>true</skinnyWars>
                <archive>
                    <manifestFile>META-INF/MANIFEST.MF</manifestFile>
                    <manifest>
                        <addClasspath>true</addClasspath>
                    </manifest>
                </archive>

                <modules>

                    <webModule>
                        <groupId>com.webinfo</groupId>
                        <artifactId>WebInfoWebApp</artifactId>
                        <bundleFileName>WebInfoWeb.war</bundleFileName>
                    </webModule>

                    <ejbModule>
                        <groupId>com.webinfo</groupId>
                        <artifactId>WebInfoEJB</artifactId>
                        <bundleFileName>WebInfoEJB.jar</bundleFileName>
                    </ejbModule>
                </modules>

            </configuration>
        </plugin>
    </plugins>
</build>

EAR manifest.mf:

Class-Path: WebInfoWeb.war WebInfoEJB.jar core_business-5.1.0.jar core
 _common-5.1.0.jar core-5.1.0.jar ICS_SSEClient-3.5.15.jar com.ibm.uti
 l.ini-1.0.jar ICS_SecuredUserContext-3.5.15.jar ICS_SecuredUserContex
 tClient-3.5.15.jar ICS_ManageClient-3.5.15.jar ICS_ConfigurationClien
 t-3.5.15.jar ICS_Common-3.5.15.jar

WAR manifest.mf:

Class-Path: WebInfoJava-3.9.0-SNAPSHOT.jar com.ibm.util.ini-1.0.jar ow
 asp-esapi-full-java-1.4.jar regexp-1.2.jar com.ibm.regex.REUtil-1.3.0
 .jar ojdbc6-11.2.0.3.0.jar AdobeFDF-1.0.jar core_business-5.1.0.jar c
 ore_common-5.1.0.jar core-5.1.0.jar ICS_SSEClient-3.5.15.jar ICS_Secu
 redUserContext-3.5.15.jar ICS_SecuredUserContextClient-3.5.15.jar ICS
 _ManageClient-3.5.15.jar ICS_ConfigurationClient-3.5.15.jar ICS_Commo
 n-3.5.15.jar

Exception:

java.lang.ClassNotFoundException: com.calculator.sendmail.SendMailCommunicationBusinessFactory

But SendMailCommunicationBusinessFactory is located in WebInfoJava-3.9.0-SNAPSHOT.jar which is in the war/WEB-INF/lib folder.

Am I doing something incorrect in the way the classpath is setup/configured?

Eric B.
  • 23,425
  • 50
  • 169
  • 316
  • Try setting the class loading policy of your ear and war module to local first (parent last). – Nick Vasic Feb 10 '15 at 07:24
  • Your build is somehow incorrect. You should either have libs in the Ear or in the `WEB-INF/lib`, not in both places at the same time. If you have libs in the `WEB-INF` they don't have to be in the Manifest classpath, but if they are in Ear - they have to be. Unless you are using Java EE 6 application and put libs into `EAR\lib` folder, then they will be also automatically in the classpath. So in general you have to fix your build. – Gas Feb 10 '15 at 08:15
  • @Gas Why can I not have libs in both places? Not all libs are shared, so some will remain in WEB-INF/lib. My shared libs are not in the EAR/lib folder, but rather in the EAR root folder. I would have expected that having libs in WEB-INF/lib and EAR / with the above MANIFEST.MF would work, but it doesn't seem to. Is it the WAR manifest that needs to have the CLASS-PATH or the EAR manifest? – Eric B. Feb 10 '15 at 14:55
  • @NickVasic I tried that, but didn't make any difference. – Eric B. Feb 10 '15 at 15:10
  • @Gas I tried moving all the EARs libs into EAR/lib, saw that the WAR manfiest CLASS-PATH had been updated to reflect this, but still it does not recognize any classes in my WAR/WEB-INF/lib jars – Eric B. Feb 10 '15 at 15:13
  • Are you using multiple class loaders within your application? Try using 'Single class loader' WAR class loader policy to load ear and war jars using a single class loader. Otherwise the parent class loader (which is your application class loader) cannot see the classes loaded by the child loaders (WAR class loaders). The required classes are looked up by the child classloader first and if not there, then the resolution moves in the parent direction (application then server), not the other way around.Additionally, you can view module class loader stack in WAS console to check the order. – Nick Vasic Feb 10 '15 at 21:23
  • EAR/lib is automatically added to module classpaths, so if you have libraries there, you don't need to have them in the manifest. If you have libs at Ear root, you need to add them in the WAR Manifest classpath. You shouldn't place SAME libs in many places as you may have class loading issues. As classes from the ear are loaded by application class loader, and war has its own module classloader. Shared classes should be in the Ear, and web module libs should be in the WEB-INF/lib (and dont put these jars in any manifest). Also classes in WEB-INF/lib will not be visible in your EJB module. – Gas Feb 11 '15 at 16:47

0 Answers0