Issue with NoClassDefFoundError error in a web environment Spring/Wicket/Derby/Jetty

11,739

Solution 1

So the 'Could not initialize class org.apache.derby.jdbc.EmbeddedDriver' error was actually the main symptom of some other, less obvious, class loading issues.

I was using Jetty as the web server and Spring as the framework under java6.

I believe there was a class loading issue, related to the MBeanServer class.

And I did ignore an error that happened at startup: "Caused by: java.lang.LinkageError: loader constraint violation: loader (instance of org/mortbay/jetty/webapp/WebAppClassLoader) previously initiated loading for a different type with name "javax/management/MBeanServer" at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632) at java.lang.ClassLoader.defineClass(ClassLoader.java:616) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)"

I searched for the class in my WEB-INF/lib directory. It was included as part of mx4j:jar. Mx4j was a dependency for jetty-management.jar. I didn't really need jetty-management so I removed that reference from my pom file.

Basically the inclusion of MBeanServer (from mx4j) caused some kind of class loading issue where org.apache.derby.jdbc.EmbeddedDriver couldn't be loaded properly. I removed it from my web application and the application started working properly.

Solution 2

The message Could not initialize class org.apache.derby.jdbc.EmbeddedDriver means that at that point the JVM has already tried and failed to initialize this class.

The JVM will fail to initialize a class if an exception is thrown and not caught within the class's static initializer. The only reasons that the JVM would be attempting to initializing the EmbeddedDriver class more than once would be:

  • some exception initializing the class was thrown, this exception was caught elsewhere and the program continued,
  • some exception initializing the class was thrown, but the program then entered a finally block, and within this finally block the JVM attempted to load the class again.

The static initializer for EmbeddedDriver (source) calls a boot() method. However, this boot() method calls a fair bit of other code, so it's difficult to tell where the problem could be. I had a look at some of the source of org.apache.commons.dbcp.BasicDataSource, but it seems the line numbers in your stacktrace don't agree with the source. I don't know which version of commons-dbcp you are using.

If you've got no other output messages nor stacktraces to go on, your best bet may be to attach the source of Derby to your debugger and step through it to see what's going on.


As an aside, it's quite possible to 'print' a class that hasn't been initialized. Consider the following classes:
class St1 {
    static {
        System.out.println("In static initializer");
    }
}

public class St2 {
    public static void main(String[] args) {
        System.out.println(St1.class);
        System.out.println(new St1());
    }
}

When I run class St2, I get the following output:

class St1
In static initializer
St1@65690726
Share:
11,739
Berlin Brown
Author by

Berlin Brown

He is a software developer interested in a variety of different technologies. He has worked with the CDC, Geographic Information Systems (GIS) and now works for a Financial Services firm. You can find him freenode as blbrown and also visit botlist and botnode.com. Berlin can be found in Atlanta, Georgia. See http://twitter.com/#!/berlinbrowndev2 and http://berlinbrowndev.blogspot.com/

Updated on June 04, 2022

Comments

  • Berlin Brown
    Berlin Brown almost 2 years

    I am trying to build a simple JDBC Spring Template application, the web framework I am using is wicket and under the jetty 6 web server (through the Jetty Maven Plugin). Also, I am building the app with Eclipse.

    For some reason, I am getting a NoClassDefFoundError with the Derby jdbc class. I am assuming I would get a class not found exception was not found, so am guessing something else is happening. The derby class is part of the classpath, the WEB-INF/lib directory. What do you think the issue is?

    My thoughts on the problem: It is not a "jar not found in the classpath" error but more an issue with Java or spring dynamically loading that class and when it gets loaded.

    I am using Eclipse as the development tool but it probably isn't part of the problem. I am still using Maven on the command line and getting the same issue.

    Here is the error:

    WicketMessage: Can't instantiate page using constructor public wicketspring.easy.HomePage()

    Root cause:

    java.lang.NoClassDefFoundError: Could not initialize class org.apache.derby.jdbc.EmbeddedDriver
         at java.lang.Class.forName0(Native Method)
         at java.lang.Class.forName(Class.java:169)
         at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1130)
         at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880)
         at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:113)
         at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:79)
         at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:577)
         at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:619)
         at wicketspring.easy.jdbc.JdbcWicketSpringHandler.data(JdbcWicketSpringHandler.java:39)
         at WICKET_wicketspring.easy.jdbc.JdbcWicketSpringHandler$$FastClassByCGLIB$$f1187cb6.invoke(<generated>)
         at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
         at org.apache.wicket.proxy.LazyInitProxyFactory$CGLibInterceptor.intercept(LazyInitProxyFactory.java:319)
         at WICKET_wicketspring.easy.jdbc.JdbcWicketSpringHandler$$EnhancerByCGLIB$$e8f0e174.data(<generated>)
         at wicketspring.easy.HomePage.<init>(HomePage.java:91)
         at wicketspring.easy.HomePage.<init>(HomePage.java:47)
    

    Here is the applicationContext.xml for Spring:

    <beans>
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
            <property name="url"><value>jdbc:derby:wicketspringdb</value></property>
            <property name="username"><value></value></property>
            <property name="password"><value></value></property>
        </bean> 
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource" />
        </bean> 
    </beans>
    <beans> 
        <import resource="classpath:common.xml"/>
        <bean id="jdbcHandler" class=wicketspring.easy.jdbc.JdbcWicketSpringHandler">
            <property name="jdbcTemplate" ref="jdbcTemplate" />
        </bean>
    
    </beans>
    
    
    ...
    Another stack trace system out.
    
    Page.java:74) - At [2b] -- java.lang.NoClassDefFoundError: Could not initialize class org.apache.derby.jdbc.EmbeddedDriver
    java.lang.NoClassDefFoundError: Could not initialize class org.apache.derby.jdbc.EmbeddedDriver
            at wicketspring.easy.HomePage.<init>(HomePage.java:72)
            at wicketspring.easy.HomePage.<init>(HomePage.java:47)
            at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
            at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:
    39)
            at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorIm
    pl.java:27)
    

    ...

    Here is the java code, the code compiles and I can print out the class but I can't instantiate it. Strange?

    Java Code:

    package wicketspring.easy;
    
    import java.util.List;
    
    import org.apache.wicket.Application;
    import org.apache.wicket.PageParameters;
    import org.apache.wicket.markup.html.WebPage;
    import org.apache.wicket.markup.html.basic.Label;
    import org.apache.wicket.markup.html.list.ListItem;
    import org.apache.wicket.markup.html.list.ListView;
    import org.apache.wicket.model.CompoundPropertyModel;
    import org.apache.wicket.proxy.IProxyTargetLocator;
    import org.apache.wicket.proxy.LazyInitProxyFactory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import model.LoadableDetachableList;
    import model.SelectionOptionBean;
    import wicketspring.easy.jdbc.JdbcWicketSpringHandler;
    import wicketspring.easy.service.IStateListService;
    import wicketspring.easy.service.StateListServiceImpl;
    
    import org.apache.derby.jdbc.EmbeddedDriver;
    
    public class HomePage extends WebPage {
    
        private final JdbcWicketSpringHandler jdbcWicketSpringHandler;
    
        public HomePage(final PageParameters parameters) {
    
            super(parameters);        
            jdbcWicketSpringHandler = (JdbcWicketSpringHandler) LazyInitProxyFactory.createProxy(JdbcWicketSpringHandler.class,
                    new IProxyTargetLocator() {
                        private static final long serialVersionUID = 1L;
                        public Object locateProxyTarget() {
                            return ((WicketApplication) Application.get()).context().getBean("jdbcHandler");
                        }
                    });    
    
            /// WEIRD BECAUSE IT REACHES THIS POINT!!!
            LOGGER.debug("At [1] -- " + EmbeddedDriver.class);
            try {
                LOGGER.debug("At [2] -- " + new org.apache.derby.jdbc.EmbeddedDriver());
            } catch (NoClassDefFoundError ne) {
                    // STACK TRACE ERROR HERE!!!!
                LOGGER.debug("At [2b] -- " + ne);
                ne.printStackTrace();
            } catch (Exception e) {
                LOGGER.debug("At [2] -- " + e);
                e.printStackTrace();
            }
            try {
    
                LOGGER.debug("At -- " + Class.forName("org.apache.derby.jdbc.EmbeddedDriver"));     
            } catch (NoClassDefFoundError ne) {
                LOGGER.debug("At [3b] -- " + ne);
                ne.printStackTrace();
            } catch (Exception e) {
                LOGGER.debug("At [3] -- " + e);
                e.printStackTrace();
            }
    
            /// ERROR FOR STACKOVERFLOW IS GENERATED FROM THIS LINE!!!!
            LOGGER.debug("At HomePage - jdbcHandler [3]: " + jdbcWicketSpringHandler.toStringJdbcTemplate());
            LOGGER.debug("At HomePage - jdbcHandler [3]: " + jdbcWicketSpringHandler.data());        
    
            ...
    
    } // End of Class //
    

    Edit: I might be missing a jar file that is a dependency of Spring Jdbc or dbcp.

    Here is my WEB-INF/lib listing:

    antlr-2.7.6.jar
    aopalliance-1.0.jar
    avalon-framework-4.1.3.jar
    axis-1.4.jar
    axis-jaxrpc-1.4.jar
    cglib-nodep-2.2.jar
    commons-collections-3.1.jar
    commons-dbcp-1.2.2.jar
    commons-logging-1.1.jar
    commons-pool-1.3.jar
    derby-10.6.1.0.jar
    dom4j-1.6.1.jar
    hibernate-core-3.5.1-Final.jar
    jetty-6.1.4.jar
    jetty-management-6.1.4.jar
    jetty-util-6.1.4.jar
    jta-1.1.jar
    log4j-1.2.14.jar
    logkit-1.0.1.jar
    mx4j-3.0.1.jar
    mx4j-tools-3.0.1.jar
    servlet-api-2.5-6.1.4.jar
    servlet-api-2.5.jar
    slf4j-api-1.5.8.jar
    slf4j-log4j12-1.4.2.jar
    spring-2.5.6.jar
    spring-aop-2.5.6.jar
    spring-beans-2.5.6.jar
    spring-context-2.5.6.jar
    spring-core-2.5.6.jar
    spring-jdbc-2.5.6.jar
    spring-test-2.5.6.jar
    spring-tx-2.5.6.jar
    testRunWrapper-1.0.0.jar
    wicket-1.4.13.jar
    wicket-ioc-1.4.13.jar
    wicket-spring-1.4.13.jar
    xml-apis-1.0.b2.jar