Saturday, 16 April 2011

Unexpected Spring Exception

One of my golden rules of coding is never to use a technique, api, pattern or algorithm until I’ve used it to write some sample code. With this in mind I took a simple EJB3 stateless session bean I’d previously written with the aim of adding a Spring SpringBeanAutowiringInterceptor, which I’d never used before. This shouldn’t have been too difficult as the code built, ran and passed all its tests. So, I wrote the code and created the simplest of JUnit tests that loaded my Spring context from a simple XML file:

    ApplicationContext ctx = new FileSystemXmlApplicationContext("appConfig.xml");
    WineService instance = ctx.getBean
(WineService.class);
    System.out.println
("Loaded WineService: " + instance);

This loaded a <bean /> structure that contained a single bean:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:jee="http://www.springframework.org/schema/jee" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
 http://www.springframework.org/schema/context 
 http://www.springframework.org/schema/beans/spring-context-3.0.xsd
 http://www.springframework.org/schema/jee  
 http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
    

 <bean id="logEventService" class="marin.events.LogEventService" />
  
</beans>
…and, remarkably, as this code builds and runs, it threw the following exception:
Exception in thread "Main Thread" org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from file [C:\java_projects2\Tips\marin-tips-ejb3-hello-world\..\marin-tips-ejb3-hello-world\src\main\resources\appConfig.xml]; nested exception is java.lang.NoClassDefFoundError: weblogic/management/WebLogicMBean
 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:412)
 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:212)
 at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:126)
 at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:92)
 at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)
 at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:458)
 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:388)
 at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:140)
 at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:84)
 at marin.tips.ejb3.stateless.springexample_winesearch.service.WineServiceImpl.main(WineServiceImpl.java:80)
Caused by: java.lang.NoClassDefFoundError: weblogic/management/WebLogicMBean
 at java.lang.ClassLoader.defineClass1(Native Method)
 at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
 at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
 at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
 at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
...
The missing class, according to the stack trace, is the weblogic.management.WebLogicMBean, which has nothing to do with my code. Confused? I know I was...

The fix was to add an extra couple of JAR files to my classpath, even though they weren’t need by my code...

From the evidence, I’d guess that Spring is somehow walking the entire classpath and scanning every dependency, looking for every class is every available JAR. When it finds a missing dependency it throws an exception, even the the missing class is not used.

Maybe this should be looked into by those clever guys at Spring, or maybe I’ve got the wrong end of the stick. So, to summarize, the fix for a NoClassDefFoundError exception is to fix the classpath.

No comments: