2013-11-19 3 views
1

Я пытался найти ответ на эту проблему в течение нескольких дней, и я надеюсь, что кто-то может указать мне в правильном направлении. У меня есть приложение SpringMVC, которое использует конфигурацию Java, и я работал нормально, пока не попытался интегрировать Apache-Shiro в него. Я могу создавать и запускать свои тесты. Но мое развертывание выходит из строя из-за проблем с Proxy/CGLIB.SpringMVC Proxy issue

Вот исключение я получаю от развертывания/перезагрузки:

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.$Proxy69]: 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.$Proxy69 
     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.$Proxy69]: 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.$Proxy69 
      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.$Proxy69 
      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 

Вот моя текущая настройка:

pom.xml

<org.springframework.version>3.2.3.RELEASE</org.springframework.version> 
<shiro.version>1.2.2</shiro.version> 
<org.hibernate.version>4.1.7.Final</org.hibernate.version> 

<dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-core</artifactId> 
      <version>3.2.3.RELEASE</version> 
      <exclusions> 
       <exclusion> 
        <artifactId>commons-logging</artifactId> 
        <groupId>commons-logging</groupId> 
       </exclusion> 
      </exclusions> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-context</artifactId> 
      <version>3.2.3.RELEASE</version> 
      <exclusions> 
       <!-- Exclude Commons Logging in favor of SLF4j --> 
       <exclusion> 
        <groupId>commons-logging</groupId> 
        <artifactId>commons-logging</artifactId> 
       </exclusion> 
      </exclusions> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-web</artifactId> 
      <version>3.2.3.RELEASE</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-webmvc</artifactId> 
      <version>$3.2.3.RELEASE</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-orm</artifactId> 
      <version>3.2.3.RELEASE</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-tx</artifactId> 
      <version>3.2.3.RELEASE</version> 
     </dependency> 
      <dependency> 
      <groupId>cglib</groupId> 
      <artifactId>cglib</artifactId> 
      <version>2.2</version> 
     </dependency> 
<dependency> 
      <groupId>org.apache.shiro</groupId> 
      <artifactId>shiro-core</artifactId> 
      <version>${shiro.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.apache.shiro</groupId> 
      <artifactId>shiro-web</artifactId> 
      <version>${shiro.version}</version> 
     </dependency> 
     <!--<dependency>--> 
      <!--<groupId>org.apache.shiro</groupId>--> 
      <!--<artifactId>shiro-aspectj</artifactId>--> 
      <!--<version>${shiro.version}</version>--> 
     <!--</dependency>--> 
     <dependency> 
      <groupId>org.aspectj</groupId> 
      <artifactId>aspectjrt</artifactId> 
      <version>1.6.11</version> 
     </dependency> 
     <dependency> 
      <groupId>org.aspectj</groupId> 
      <artifactId>aspectjweaver</artifactId> 
      <version>1.6.12</version> 
     </dependency> 

     <dependency> 
      <groupId>org.apache.shiro</groupId> 
      <artifactId>shiro-ehcache</artifactId> 
      <version>${shiro.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.apache.shiro</groupId> 
      <artifactId>shiro-spring</artifactId> 
      <version>${shiro.version}</version> 
      </dependency> 
<dependency> 
      <groupId>org.springframework.data</groupId> 
      <artifactId>spring-data-jpa</artifactId> 
      <version>1.0.3.RELEASE</version> 
     </dependency> 
<dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-core</artifactId> 
      <version>${org.hibernate.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-entitymanager</artifactId> 
      <version>${org.hibernate.version}</version> 
     </dependency> 
     <!-- Hibernate metamodel annotation processor --> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-jpamodelgen</artifactId> 
      <version>1.1.1.Final</version> 
     </dependency> 
... 
</> 

Я использую этот веб-конфигурации:

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 { 

     // Create the 'root' Spring application context 
     AnnotationConfigWebApplicationContext rootContext = new 
AnnotationConfigWebApplicationContext(); 

     //I have two @Configuration classes: 
     rootContext.register(EdmConfiguration.class, SecurityConfig.class); 

     // Manage the lifecycle of the root application context 
     servletContext.addListener(new ContextLoaderListener(rootContext)); 


     // Create the dispatcher servlet's Spring application context 
     AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext(); 
     dispatcherContext.setServletContext(servletContext); 
     dispatcherContext.setParent(rootContext); 

     // it seems I have to register the Configuration classes again or I can't @Autowire 
     dispatcherContext.register(EdmConfiguration.class, SecurityConfig.class); 



     // Register and map the dispatcher servlet 
     ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(dispatcherContext)); 
     dispatcher.setLoadOnStartup(1); 
     dispatcher.addMapping("/"); 


     servletContext.addFilter("shiroFilter", new DelegatingFilterProxy("shiroFilter", dispatcherContext)) 
       .addMappingForUrlPatterns(null, false, "/*"); 
    } 
} 

Вот мой основной класс конфигурации:

@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages = { "com.company.product.service", "com.company.product.utility", 
     "com.company.product.controller", "com.company.product.utility.startup", 
     "com.company.product.security", "com.company.product.repository.people" }) 
@EnableTransactionManagement(proxyTargetClass=false) 
@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(); 

     dataSource.setDriverClass(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER)); 
     dataSource.setJdbcUrl(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_URL)); 
     dataSource.setUsername(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME)); 
     dataSource.setPassword(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD)); 

     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 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); 
     shiroFilter.setLoginUrl("/login"); 
     shiroFilter.setUnauthorizedUrl("/"); 
     return shiroFilter; 
    } 



    @Bean 
    @DependsOn(value = "lifecycleBeanPostProcessor") 
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { 
     DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator(); 
     creator.setProxyTargetClass(true); 
     return creator; 
    } 
} 

А вот другой класс конфигурации. Это добавление, которое вызывает проблемы с прокси-сервером.

@Configuration 
public class SecurityConfig { 

    @Bean 
    public SaltAwareJdbcRealm saltAwareJdbcRealm() { 
     return new SaltAwareJdbcRealm(); 
    } 

    @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 AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() { 
     AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); 
     authori 

zationAttributeSourceAdvisor.setSecurityManager(securityManager()); 
      return authorizationAttributeSourceAdvisor; 
     }  
    } 

класс нарушившая это просто весна jparepository:

public interface MenuRepository extends CrudRepository<Menu, Long>, JpaSpecificationExecutor<Menu> { 

...} 

Я добавил @EnableTransactionManagement (proxyTargetClass = ложь) который я думал бы решить проблему прокси, но, видимо, ISN» т.

Благодарим вас за то, что вы прочитали все это.

+0

Просьба уточнить, поскольку в настоящее время неясно, в чем проблема. Вы в основном заявляете, что он не работает, сбрасывает много кода и ожидает, что люди здесь исправят его. –

+0

Извините, я постараюсь уточнить свой первоначальный пост. – sonoerin

+0

По какой-то причине что-то запускает создание прокси-сервера для прокси-сервера. Судя по вашему коду, вы смешиваете разные прокси-стратегии, зачем вам нужен дополнительный 'DefaultAdvisorAutoProxyCreator'? –

ответ

4
Caused by: java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy69 

Это исключение указывает на то, что из-за какой-то неправильной или несколькими способами применения АОП, доверенное лицо прокси генерируется. Теперь с JDK Dynamic Proxies это не проблема, но с прокси-серверами на основе классов. Потому что cglib делает классы окончательными (как указано в stacktrace).

Ваша конфигурация имеет несколько способов генерации прокси, @EnableTransactionManagement запускает регистрацию AutoProxyCreator. Затем вы добавляете еще один.

Решение в этом случае должно удалить DefaultAdvisorAutoProxyCreator, так как для вас уже зарегистрирован экземпляр. Это отключит прокси-сервер.