title: Upgrading Spring Security 2.5 to 3.1 - java.lang.NoClassDefFoundError: org/springframework/security/Authentication
body: <p>This problem is proving very tricky to resolve. Usual story, inherited a very poorly maintained java web application with no unit tests and a variety of ancient jar dependencies with no version info dumped in a lib directory built using Ant. In order to get better maintenance and understanding of the dependencies I migrated over to Maven. Subsequently, I realised the version of Spring was quite old (Spring 2.x and Spring Security 2.0.3). I upgraded successfully to Spring 2.5. I have now started migrating Spring up to 3.1.2.RELEASE, and Spring Security up to 3.1.3.RELEASE.</p>
  
  <p>Everything compiles, I don't get any namespace issues either (declared in headers of Spring XML configs), but fails when being deployed as a WAR file into Tomcat Container. The log file reports:</p>
  
  <pre><code>Could not instantiate bean class [com.mydomain.repository.ReportDaoImpl]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/security/Authentication
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:997)
  </code></pre>
  
  <p>I checked, and org.springframework.security.Authentication belongs to the old Spring Security jar (2.0.4)</p>
  
  <p>My current Maven dependencies are as follows:</p>
  
  <pre><code>&lt;spring.version&gt;3.1.2.RELEASE&lt;/spring.version&gt;
  
        &lt;dependency&gt;
          &lt;groupId&gt;org.springframework&lt;/groupId&gt;
          &lt;artifactId&gt;spring-webmvc&lt;/artifactId&gt;
          &lt;version&gt;${spring.version}&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework&lt;/groupId&gt;
          &lt;artifactId&gt;spring-aop&lt;/artifactId&gt;
          &lt;version&gt;${spring.version}&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework&lt;/groupId&gt;
          &lt;artifactId&gt;spring-context&lt;/artifactId&gt;
          &lt;version&gt;${spring.version}&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework&lt;/groupId&gt;
          &lt;artifactId&gt;spring-context-support&lt;/artifactId&gt;
          &lt;version&gt;${spring.version}&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework&lt;/groupId&gt;
          &lt;artifactId&gt;spring-core&lt;/artifactId&gt;
          &lt;version&gt;${spring.version}&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework&lt;/groupId&gt;
          &lt;artifactId&gt;spring-tx&lt;/artifactId&gt;
          &lt;version&gt;${spring.version}&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework&lt;/groupId&gt;
          &lt;artifactId&gt;spring-jdbc&lt;/artifactId&gt;
          &lt;version&gt;${spring.version}&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;!--  SPRING SECURITY --&gt;
  
               &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
          &lt;artifactId&gt;spring-security-acl&lt;/artifactId&gt;
          &lt;version&gt;3.1.3.RELEASE&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
          &lt;artifactId&gt;spring-security-config&lt;/artifactId&gt;
          &lt;version&gt;3.1.3.RELEASE&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
          &lt;artifactId&gt;spring-security-core&lt;/artifactId&gt;
          &lt;version&gt;3.1.3.RELEASE&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
          &lt;artifactId&gt;spring-security-taglibs&lt;/artifactId&gt;
          &lt;version&gt;3.1.3.RELEASE&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
          &lt;artifactId&gt;spring-security-web&lt;/artifactId&gt;
          &lt;version&gt;3.1.3.RELEASE&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
          &lt;artifactId&gt;spring-security-crypto&lt;/artifactId&gt;
          &lt;version&gt;3.1.3.RELEASE&lt;/version&gt;
      &lt;/dependency&gt;
  </code></pre>
  
  <p>My security.xml is minimal:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  
  &lt;beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
         http://www.springframework.org/schema/security
         http://www.springframework.org/schema/security/spring-security-3.1.xsd"&gt;
  
  &lt;http auto-config='true'&gt;
      &lt;intercept-url pattern="/**" access="ROLE_Admin" /&gt;
  &lt;/http&gt;
  
  &lt;authentication-manager&gt;
      &lt;authentication-provider&gt;
          &lt;user-service&gt;
              &lt;user name="admin" password="password" authorities="ROLE_Admin" /&gt;
          &lt;/user-service&gt;
      &lt;/authentication-provider&gt;
  &lt;/authentication-manager&gt;        
  </code></pre>
  
  <p></p>
  
  <p>All my other Spring Config files use the following namespace headers in their configs:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  
   &lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
      xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
      xsi:schemaLocation="
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"&gt;
  </code></pre>
  
  <p>As far as I know this application contains NO annotations regarding Spring. </p>
  
  <p>So how does the Spring Security 2.0.4 class org.springframework.security.Authentication get requested by a Spring 3.1 class org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory when instantiating a DAO object (which has nothing to do with Spring security settings). It may be that the DAO is picked because it is the first bean in order to get instantiated in the applicationContext.xml by the classloader (via Spring dependency injection container) but i cannot see how there is still a reference lurking somewhere in this application to an old 2.0.4 class. Since everything compiles ok, and the Maven pom only references 3.1 my take is that there must be some configuration somewhere still trying to pull in an old class. Anyone with Spring Security knowledge (in particular upgrading a large app from a version 2 to version 3) might have hit this problem before but I couldn't find exact match via google. Thanks for any suggestions on this. Currently stumped.</p>
  
  <p>Quick update:</p>
  
  <p>The applicationContext.xml has the namespace header as given above and the DAO is simply referenced as follows:</p>
  
  <pre><code>&lt;bean id="reportDao" class="com.mydomain.repository.ReportDaoImpl"&gt;
      &lt;property name="dataSource" ref="myDataSource" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>There is really nothing more to it. The applicationContext pulls in another context file applicationContext-datasource which declares (same namespace header again as above):</p>
  
  <pre><code> &lt;bean id="parentDataSource" class="org.apache.commons.dbcp.BasicDataSource"
      destroy-method="close"&gt;
      &lt;property name="driverClassName" value="${jdbc.driverClassName}" /&gt;
  &lt;/bean&gt;
  
  &lt;bean id="myDataSource" parent="parentDataSource"&gt;
      &lt;property name="url" value="${jdbc.url}" /&gt;
      &lt;property name="username" value="${jdbc.username}" /&gt;
      &lt;property name="password" value="${jdbc.password}" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>The ReportDao is over 1500 lines of poorly written procedural code. It is a POJO and implements rg.springframework.context.ApplicationContextAware. It also uses org.springframework.jdbc.core.support.JdbcDaoSupport for performing CRUD operations to the database.</p>
  
  <p>Running mvn -X  the output for dependencies (have switched to Spring [main] 3.0.7):</p>
  
  <pre><code>   org.springframework:spring-webmvc:jar:3.0.7.RELEASE:compile
      org.springframework:spring-asm:jar:3.0.7.RELEASE:compile
      org.springframework:spring-beans:jar:3.0.7.RELEASE:compile
      org.springframework:spring-expression:jar:3.0.7.RELEASE:compile
      org.springframework:spring-web:jar:3.0.7.RELEASE:compile
   org.springframework:spring-aop:jar:3.0.7.RELEASE:compile
      aopalliance:aopalliance:jar:1.0:compile
   org.springframework:spring-context:jar:3.0.7.RELEASE:compile
   org.springframework:spring-context-support:jar:3.0.7.RELEASE:compile
   org.springframework:spring-core:jar:3.0.7.RELEASE:compile
   org.springframework:spring-tx:jar:3.0.7.RELEASE:compile
   org.springframework:spring-jdbc:jar:3.0.7.RELEASE:compile
   org.springframework.security:spring-security-acl:jar:3.1.3.RELEASE:compile
   org.springframework.security:spring-security-config:jar:3.1.3.RELEASE:compile
   org.springframework.security:spring-security-core:jar:3.1.3.RELEASE:compile
   org.springframework.security:spring-security-taglibs:jar:3.1.3.RELEASE:compile
   org.springframework.security:spring-security-web:jar:3.1.3.RELEASE:compile
   org.springframework.security:spring-security-crypto:jar:3.1.3.RELEASE:compile
  </code></pre>
  
  <p>Looks ok I believe.</p>
  
  <p>The only spring jars (grepped to be certain) in the WEB-INF/lib directory of the deliverable WAR file are:</p>
  
  <pre><code>./spring-aop-3.0.7.RELEASE.jar
  ./spring-asm-3.0.7.RELEASE.jar
  ./spring-beans-3.0.7.RELEASE.jar
  ./spring-context-3.0.7.RELEASE.jar
  ./spring-context-support-3.0.7.RELEASE.jar
  ./spring-core-3.0.7.RELEASE.jar
  ./spring-expression-3.0.7.RELEASE.jar
  ./spring-jdbc-3.0.7.RELEASE.jar
  ./spring-security-acl-3.1.3.RELEASE.jar
  ./spring-security-config-3.1.3.RELEASE.jar
  ./spring-security-core-3.1.3.RELEASE.jar
  ./spring-security-crypto-3.1.3.RELEASE.jar
  ./spring-security-taglibs-3.1.3.RELEASE.jar
  ./spring-security-web-3.1.3.RELEASE.jar
  ./spring-tx-3.0.7.RELEASE.jar
  ./spring-web-3.0.7.RELEASE.jar
  ./spring-webmvc-3.0.7.RELEASE.jar
  </code></pre>
  
  <p>Again, looks sensible.</p>
  
  <p>Grepping the source code for "Authentication" did not help. This looks like a transitive runtime dependency issue. It goes unnoticed at compilation and isn't declared anywhere as a first level dependency. But somehow at runtime (in the Tomcat 6 container) when deployed a rogue reference to an old library file is requested.</p>
  
  <p>Going to delete my Tomcat instance and start from scratch just as a precaution.</p>