java.lang.IllegalArgumentException: interface org.springframework.aop.IntroductionInfo is not visible from class loader

Spring JIRA | Don Brown | 8 years ago
  1. 0

    We've found that, interestingly, when cglib is not available or exposed to the Spring bundle, it is possible for Spring AOP to incorrectly start loading classes from a different classloader than the bundle. In our setup, we have a webapp that has an instance of Spring in WEB-INF/lib. In that webapp, we have an embedded Felix container running our plugin system. Because this plugin system has to run on very different web applications, we include the Spring bundle in the OSGi container so that we have a consistent Spring environment, regardless of application's DI library. The application, using the system bundle, registers its services into the OSGi service registry, so they are available to plugins. Now, when Spring DM starts up, CachingAopClassLoaderFactory (66) initializes its ChainedClassLoader with a set of classloaders that should be used to look up interfaces for AOP proxies (probably among other things). If it detects cglib, then it adds four classloaders into the chain, putting the one that loaded the cglib class 3rd (webapp classloader), after the classloader that loaded ProxyFactory, which will probably be the Spring bundle. However, if it doesn't detect cglib, it only adds three classloaders into the chain, none of which are the webapp classloader. Later, as it creates proxies for service references, if it finds a service interface that was loaded from the webapp classloader, it sees that the classloader isn't in the chain, then adds it 2nd, before the Spring bundle. This means that now Spring classes will be retrieved from the webapp classloader, which in our case, is a very different version of spring. This causes all sorts of errors later, including: [java] Caused by: java.lang.IllegalArgumentException: interface org.springframework.aop.IntroductionInfo is not visible from class loader [java] at java.lang.reflect.Proxy.getProxyClass(Proxy.java:353) [java] at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581) [java] at org.springframework.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:117) [java] at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110) [java] at org.springframework.osgi.service.util.internal.aop.ProxyUtils.createProxy(ProxyUtils.java:60) [java] at org.springframework.osgi.service.util.internal.aop.ProxyUtils.createProxy(ProxyUtils.java:37) [java] at org.springframework.osgi.service.importer.support.AbstractServiceProxyCreator.createServiceProxy(AbstractServiceProxyCreator.java:107) This is because the instance of IntroductionInfo is now loaded from the webapp classloader, conflicting with the one from the Spring bundle. As for a solution, the quick one is to have every application use cglib and expose the package to bundles, but obviously, that is kinda crap. A better solution would have the AbstractServiceImporterProxyFactoryBean not automatically add classloaders from those it finds to aopClassLoader. Alternatively, ChainedClassLoader should not add new classloaders second, but third or last.

    Spring JIRA | 8 years ago | Don Brown
    java.lang.IllegalArgumentException: interface org.springframework.aop.IntroductionInfo is not visible from class loader
  2. 0

    We've found that, interestingly, when cglib is not available or exposed to the Spring bundle, it is possible for Spring AOP to incorrectly start loading classes from a different classloader than the bundle. In our setup, we have a webapp that has an instance of Spring in WEB-INF/lib. In that webapp, we have an embedded Felix container running our plugin system. Because this plugin system has to run on very different web applications, we include the Spring bundle in the OSGi container so that we have a consistent Spring environment, regardless of application's DI library. The application, using the system bundle, registers its services into the OSGi service registry, so they are available to plugins. Now, when Spring DM starts up, CachingAopClassLoaderFactory (66) initializes its ChainedClassLoader with a set of classloaders that should be used to look up interfaces for AOP proxies (probably among other things). If it detects cglib, then it adds four classloaders into the chain, putting the one that loaded the cglib class 3rd (webapp classloader), after the classloader that loaded ProxyFactory, which will probably be the Spring bundle. However, if it doesn't detect cglib, it only adds three classloaders into the chain, none of which are the webapp classloader. Later, as it creates proxies for service references, if it finds a service interface that was loaded from the webapp classloader, it sees that the classloader isn't in the chain, then adds it 2nd, before the Spring bundle. This means that now Spring classes will be retrieved from the webapp classloader, which in our case, is a very different version of spring. This causes all sorts of errors later, including: [java] Caused by: java.lang.IllegalArgumentException: interface org.springframework.aop.IntroductionInfo is not visible from class loader [java] at java.lang.reflect.Proxy.getProxyClass(Proxy.java:353) [java] at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581) [java] at org.springframework.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:117) [java] at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110) [java] at org.springframework.osgi.service.util.internal.aop.ProxyUtils.createProxy(ProxyUtils.java:60) [java] at org.springframework.osgi.service.util.internal.aop.ProxyUtils.createProxy(ProxyUtils.java:37) [java] at org.springframework.osgi.service.importer.support.AbstractServiceProxyCreator.createServiceProxy(AbstractServiceProxyCreator.java:107) This is because the instance of IntroductionInfo is now loaded from the webapp classloader, conflicting with the one from the Spring bundle. As for a solution, the quick one is to have every application use cglib and expose the package to bundles, but obviously, that is kinda crap. A better solution would have the AbstractServiceImporterProxyFactoryBean not automatically add classloaders from those it finds to aopClassLoader. Alternatively, ChainedClassLoader should not add new classloaders second, but third or last.

    Spring JIRA | 8 years ago | Don Brown
    java.lang.IllegalArgumentException: interface org.springframework.aop.IntroductionInfo is not visible from class loader
  3. 0

    JPA with hibernate with spring DM

    Google Groups | 9 years ago | ouertani slim
    java.lang.IllegalArgumentException: interface org.springframework.beans.factory.xml.NamespaceHandlerResolver is not visible from class loader
  4. Speed up your debug routine!

    Automated exception search integrated into your IDE

    17 unregistered visitors
    Not finding the right solution?
    Take a tour to get the most out of Samebug.

    Tired of useless tips?

    Automated exception search integrated into your IDE

    Root Cause Analysis

    1. java.lang.IllegalArgumentException

      interface org.springframework.aop.IntroductionInfo is not visible from class loader

      at java.lang.reflect.Proxy.getProxyClass()
    2. Java RT
      Proxy.newProxyInstance
      1. java.lang.reflect.Proxy.getProxyClass(Proxy.java:353)
      2. java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581)
      2 frames
    3. Spring AOP
      ProxyFactory.getProxy
      1. org.springframework.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:117)
      2. org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110)
      2 frames
    4. Spring OSGi Core
      AbstractServiceProxyCreator.createServiceProxy
      1. org.springframework.osgi.service.util.internal.aop.ProxyUtils.createProxy(ProxyUtils.java:60)
      2. org.springframework.osgi.service.util.internal.aop.ProxyUtils.createProxy(ProxyUtils.java:37)
      3. org.springframework.osgi.service.importer.support.AbstractServiceProxyCreator.createServiceProxy(AbstractServiceProxyCreator.java:107)
      3 frames