javadeploymentjerseyglassfish-2.x

NoClassDefFoundError. How to set dependencies and deploy a java app?


My Java app requires org.objectweb.asm library. I specified 'asm' dependency in pom. That deploys the library together with the app. Still the app throws exception NoClassDefFoundError: org/objectweb/asm/ClassVisitor.

java.lang.NoClassDefFoundError: org/objectweb/asm/ClassVisitor
    at com.sun.jersey.api.core.PackagesResourceConfig.init(PackagesResourceConfig.java:112)
    at com.sun.jersey.api.core.PackagesResourceConfig.<init>(PackagesResourceConfig.java:78)
... many more

How can I fix the problem?

Details: I am using Glassfish 2.1.1. The app requires jersey 1.1.4, jersey requires asm 3.1. I assume 1.1.4 version is required by glassfish 2.1.1

If I run Glassfish updatetool and install Jersey on the server then my app loads and runs with no problems. My client doesn't have Jersey installed on their server and they can not use updatetool.

Glassfish 2.1.1 updatetool installs jersey 1.1.4 and asm-3.1.jar in glassfish/lib directory. When jersey is uninstalled, updatetool removes asm too.

If I include jersey and asm as dependencies and deploy my war file then jersey and asm jars go into local location, e.g. glassfish/domains/domain1/applications/j2ee-modules/MYAPPNAME/WEB-INF/lib/asm-3.1.jar.

Glassfish updatetool puts asm into lib folder: glassfish/lib directory the app start deploying and working correctly.

Here is my maven pom file dependency section:

<dependencies>
    <dependency>
        <groupId>asm</groupId>
        <artifactId>asm</artifactId>
        <version>3.1</version>
    </dependency>

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-bundle</artifactId>
        <version>1.1.4</version>
    </dependency>

    <dependency>
        <groupId>com.sun.jersey.jersey-test-framework</groupId>
        <artifactId>jersey-test-framework-grizzly2</artifactId>
        <version>1.17.1</version>
                    <scope>test</scope>
    </dependency>
    <dependency>  
                <groupId>javax.persistence</groupId>  
                <artifactId>persistence-api</artifactId>  
                <version>1.0</version>  
        <scope>provided</scope>
            </dependency>  
    <dependency>
        <groupId>org.jboss.spec</groupId>
        <artifactId>jboss-javaee-6.0</artifactId>
        <version>1.0.0.Final</version>
        <scope>provided</scope>
        <type>pom</type>
    </dependency>
            <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>        
</dependencies>

Solution

  • I had a conflict with an older jersey library stored in glassfish/lib folder:

    glassfish/lib/jersey-bundle-1.0.3.1.jar
    

    It was loaded and used instead of jars placed in a folder local to the app:

    glassfish/domains/domain1/applications/j2ee-modules/MYAPPNAME/WEB-INF/lib/
    

    Jersey jar from 'lib' folder was looking for 'asm' library in the same 'lib' folder, hence my locally placed asm-3.1.jar was never found.

    I expected that 'local' jars were loaded first. Appeared that the search order is different. Is that really the case? Please tell me if I am wrong.

    I found the problem by verifying which library is used with the following code:

    logger.debug(PackagesResourceConfig.class.getResource("PackagesResourceConfig.class"));
    

    Note PackagesResourceConfig class listed in the exception thrown.

    Hopefully this answer will help someone else to save their time.