title: SpringMVC, Shiro, and Java Configuration
body: <p>I am trying to use Shiro 1.2.2 with my SpringMVC 3.2.3   I have seen several examples of how to configure Shiro using ini files.  But we are using JavaConfig and I have only found one partial example on that.  I have several @Configuration files:</p>
  
  <pre><code>public class EdmWebInitializer implements WebApplicationInitializer {
  
      private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
      private static final String DISPATCHER_SERVLET_MAPPING = "/*";
  
      @Override
      public void onStartup(ServletContext servletContext) throws ServletException {
          AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
      root.scan( "com.company.config" );
      root.register( EdmConfiguration.class, SecurityConfig.class );
      servletContext.addListener( new ContextLoaderListener( root ) );
  
      ServletRegistration.Dynamic appServlet = servletContext.addServlet( DISPATCHER_SERVLET_NAME,
              new DispatcherServlet( root ) );
      appServlet.setLoadOnStartup( 1 );
  
      Set&lt;String&gt; mappingConflicts = appServlet.addMapping( DISPATCHER_SERVLET_MAPPING );
      servletContext
              .addFilter( "shiroFilter", new DelegatingFilterProxy( "shiroFilter", root ) )
              .addMappingForUrlPatterns( null, false, DISPATCHER_SERVLET_MAPPING );
  
      servletContext.addFilter( "Spring OpenEntityManagerInViewFilter",
              org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.class ).addMappingForUrlPatterns(
              null, false, "/*" );
  </code></pre>
  
  <p>My beans are defined here:</p>
  
  <pre><code>@Configuration
  @EnableWebMvc
  @ComponentScan(basePackages = { "com.company.service", "com.company.utility",
          "com.company.controller", "com.company.utility.startup",
          "com.company.security", "com.company.security.model" })
  @EnableTransactionManagement
  @ImportResource({ "classpath:applicationContext.xml"})
  @PropertySource({ "classpath:application.properties", "classpath:mail.properties" })
  public class EdmConfiguration extends WebMvcConfigurationSupport {
  
  
      @Resource
      private Environment environment;
  
      @Autowired
      private org.apache.shiro.web.mgt.WebSecurityManager securityManager;
  
      @Bean
      public DataSource dataSource() {
          BoneCPDataSource dataSource = new BoneCPDataSource();
  
      ...
          return dataSource;
      }
  
      @Bean
      public JpaTransactionManager transactionManager() throws ClassNotFoundException {
          JpaTransactionManager transactionManager = new JpaTransactionManager();
  
          transactionManager.setEntityManagerFactory( entityManagerFactoryBean().getObject() );
  
          return transactionManager;
      }
  
      @Bean
      public DelegatingFilterProxy springSecurityFilterChain() {
          return new DelegatingFilterProxy();
      }
  
      @Bean
      public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() throws ClassNotFoundException {
          LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
  
          entityManagerFactoryBean.setDataSource( dataSource() );
          entityManagerFactoryBean.setPackagesToScan( environment
                  .getRequiredProperty( PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN ) );
          entityManagerFactoryBean.setPersistenceProviderClass( HibernatePersistence.class );
  
          Properties jpaProperties = new Properties();
          ...
          entityManagerFactoryBean.setJpaProperties( jpaProperties );
  
          return entityManagerFactoryBean;
      }
  
      @Bean
      public PersistenceExceptionTranslator exTranslator() {
          return new HibernateExceptionTranslator();
      }
  
      @Bean(initMethod = "init")
      public StartupListener startupListener() {
          return new StartupListener();
      }
  
  
  
  
      @Bean
      public ContentNegotiationManagerFactoryBean contentNegotiationManager() {
          Properties properties = new Properties();
          properties.setProperty( "xml", "application/xml" );
          properties.setProperty( "json", "application/json" );
          properties.setProperty( "html", "application/html" );
  
          ContentNegotiationManagerFactoryBean contentNegotiationManager = new ContentNegotiationManagerFactoryBean();
          contentNegotiationManager.setFavorParameter( true );
          contentNegotiationManager.setMediaTypes( properties );
          contentNegotiationManager.setDefaultContentType( MediaType.APPLICATION_JSON );
  
          return contentNegotiationManager;
      }
  
  
  
      @Bean
      public JavaMailSenderImpl mailSender() {
          JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
          int port = Integer.parseInt( environment.getRequiredProperty( "mail.smtp.socketFactory.port" ) );
          mailSender.setHost( environment.getRequiredProperty( "mail.smtp.host" ) );
          mailSender.setPort( port );
          mailSender.setUsername( environment.getRequiredProperty( "mail.login.username" ) );
          mailSender.setPassword( environment.getRequiredProperty( "mail.login.password" ) );
  
          Properties properties = new Properties();
          properties.setProperty( "mail.smtp.auth", environment.getRequiredProperty( "mail.smtp.auth" ) );
          properties.setProperty( "mail.smtp.starttls.enable", "true" );
          mailSender.setJavaMailProperties( properties );
  
          return mailSender;
      }
  
  
      @Bean
      public VelocityEngine getVelocityEngine() throws VelocityException, IOException {
          VelocityEngineFactory factory = new VelocityEngineFactory();
          Properties props = new Properties();
          props.put( "resource.loader", "class" );
          props.put( "class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader" );
          factory.setVelocityProperties( props );
          factory.setResourceLoaderPath( "/com/edelweissco/dental/templates" );
          factory.setPreferFileSystemAccess( false );
          return factory.createVelocityEngine();
      }
  
      @Bean
      public StandardPasswordEncoder encoder() {
          return new org.springframework.security.crypto.password.StandardPasswordEncoder();
      }
  
      @Bean
      public ShiroFilterFactoryBean shiroFilter() {
          ShiroFilterFactoryBean shiroFilter = new org.apache.shiro.spring.web.ShiroFilterFactoryBean();
          shiroFilter.setSecurityManager( securityManager);
          return shiroFilter;
      }
  
      @Bean
      @DependsOn(value = "lifecycleBeanPostProcessor")
      public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
          DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
          creator.setProxyTargetClass(true); // it's false by default
          return creator;
      }
  </code></pre>
  
  <p>I have broken the Shiro configuraton into its own file:</p>
  
  <pre><code>    @Configuration
  public class SecurityConfig {
  
      @Bean
      public CustomSecurityRealm customSecurityRealm() {
          return new CustomSecurityRealm();
      }
  
      @Bean
      public SaltAwareJdbcRealm saltAwareJdbcRealm() {
          return new SaltAwareJdbcRealm();
      }
  
      @Bean
      public org.apache.shiro.authc.credential.DefaultPasswordService passwordService() {
          return new DefaultPasswordService();
      }
  
      @Bean
      public TempFixPasswordMatcher passwordMatcher() {
          TempFixPasswordMatcher tempFixPasswordMatcher = new TempFixPasswordMatcher();
          tempFixPasswordMatcher.setPasswordService( passwordService() );
          return tempFixPasswordMatcher;
      }
  
  
      @Bean
      public WebSecurityManager securityManager() {
          DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
          securityManager.setRealm( saltAwareJdbcRealm() );
          return securityManager;
      }
  
      @Bean
      public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
          return new LifecycleBeanPostProcessor();
      }
  
      @Bean
      public MethodInvokingFactoryBean methodInvokingFactoryBean() {
          MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
          methodInvokingFactoryBean.setStaticMethod( "org.apache.shiro.SecurityUtils.setSecurityManager" );
          methodInvokingFactoryBean.setArguments( new Object[]{ securityManager() } );
          return methodInvokingFactoryBean;
      }
  
      @Bean
      @DependsOn(value = "lifecycleBeanPostProcessor")
      public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
          return new DefaultAdvisorAutoProxyCreator();
      }
  
      @Bean
      public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
          AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
          authorizationAttributeSourceAdvisor.setSecurityManager( securityManager() );
          return authorizationAttributeSourceAdvisor;
      }
  </code></pre>
  
  <p>When I try to deploy I get exceptions such as :</p>
  
  <p>This is the full stack trace I get once I remove the @Transaction from my OfficeService:</p>
  
  <pre><code>org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'menuService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'menuRepository': Post-processing of the FactoryBean's object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy68]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy68
      at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:306)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
      at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
      at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
      at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
      at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
      at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
      at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4937)
      at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)
      at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
      at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
      at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
      at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
      at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1551)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301)
      at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:835)
      at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:771)
      at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:622)
      at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:569)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301)
      at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:835)
      at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:771)
      at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1455)
      at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:75)
      at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1296)
      at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1388)
      at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:819)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:303)
      at sun.rmi.transport.Transport$1.run(Transport.java:159)
      at java.security.AccessController.doPrivileged(Native Method)
      at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
      at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
      at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
      at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
      at java.lang.Thread.run(Thread.java:680)
  Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'menuRepository': Post-processing of the FactoryBean's object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy68]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy68
      at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:165)
      at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1454)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:306)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
      at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:442)
      at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:416)
      at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:550)
      at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)
      at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
      at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303)
      ... 55 more
  Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy68]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy68
      at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:217)
      at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:111)
      at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:477)
      at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362)
      at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:409)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1625)
      at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:162)
      ... 65 more
  Caused by: java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy68
      at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
      at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
      at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
      at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
      at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
      at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285)
      at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205)
      ... 72 more
  Nov 9, 2013 4:10:04 PM org.apache.catalina.core.ApplicationContext log
  INFO: Closing Spring root WebApplicationContext
  </code></pre>