Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Virgo » Spring annotation config
Spring annotation config [message #1062579] Sun, 09 June 2013 11:36 Go to next message
Maarten Winkels is currently offline Maarten Winkels
Messages: 11
Registered: May 2013
Junior Member
Hi All,

I have a very simple bundle that has a small spring configuration. I build the bundle using maven and the maven-bundle-plugin. When using XML for spring configuration this works fine: I have a minimal set of import packages and virgo can resolve them easily and start up the bundle.

Now I want to move to annotation configuration. I use a
<component-scan/>
tag in the XML file and have a
@Configuration
and a
@Component
. This works great when I load the configuration in a unit test. When I start the bundle in Virgo, however, I get an exception:

Quote:
Start failed for bundle 'xxx'. java.lang.IllegalStateException: Cannot load configuration class: x.x.xConfiguration
at org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:366)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:242)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.invokeBeanFactoryPostProcessors(AbstractDelegatedExecutionApplicationContext.java:444)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.invokeBeanFactoryPostProcessors(AbstractDelegatedExecutionApplicationContext.java:431)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.invokeBeanFactoryPostProcessors(AbstractDelegatedExecutionApplicationContext.java:362)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$3.run(AbstractDelegatedExecutionApplicationContext.java:254)
at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.startRefresh(AbstractDelegatedExecutionApplicationContext.java:220)
at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.stageOne(DependencyWaiterApplicationContextExecutor.java:224)
at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.refresh(DependencyWaiterApplicationContextExecutor.java:177)
at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.refresh(AbstractDelegatedExecutionApplicationContext.java:157)
at org.eclipse.gemini.blueprint.extender.internal.activator.LifecycleManager$1.run(LifecycleManager.java:211)
at org.eclipse.virgo.kernel.agent.dm.ContextPropagatingTaskExecutor$2.run(ContextPropagatingTaskExecutor.java:95)
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: java.lang.NoClassDefFoundError: org/springframework/cglib/core/ReflectUtils
at x.x.xConfiguration$$EnhancerByCGLIB$$124808e1_2.CGLIB$STATICHOOK2(<generated>)
at x.x.xConfiguration$$EnhancerByCGLIB$$124808e1_2.<clinit>(<generated>)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:249)
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:386)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
at org.springframework.context.annotation.ConfigurationClassEnhancer.createClass(ConfigurationClassEnhancer.java:118)
at org.springframework.context.annotation.ConfigurationClassEnhancer.enhance(ConfigurationClassEnhancer.java:92)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:356)
... 15 common frames omitted
Caused by: org.eclipse.virgo.kernel.osgi.framework.ExtendedClassNotFoundException: org.springframework.cglib.core.ReflectUtils in KernelBundleClassLoader: [bundle=xxx]
at org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader.loadClass(KernelBundleClassLoader.java:139)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 26 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.cglib.core.ReflectUtils
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader.loadClass(KernelBundleClassLoader.java:135)


Now, as I understand this exception, it means that to load the Configuration class spring needs some CGLib classes and it cannot load these classes from the bundle class loader. This is because there are no package, bundle or library import statements for those classes. I think I can resolve this by adding a library import for the spring library or maybe a package import for the spring-core bundle, but this seems like functionality that Virgo might support out of the box: If it can load the XML variant, why not the annotation variant?

Any better options for how to resolve this? Will there be better support for spring annotation config in the near future?

Thanks!

-Maarten Winkels
Re: Spring annotation config [message #1062580 is a reply to message #1062579] Sun, 09 June 2013 12:05 Go to previous messageGo to next message
Rigas Grigoropoulos is currently offline Rigas Grigoropoulos
Messages: 9
Registered: November 2012
Junior Member
When using xml configuration cglib (and thus the cglib imports in your manifest) is not required by what is contained in the spring configuration. But when using @Configuration, cglib is required to create the configuration class:
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
at org.springframework.context.annotation.ConfigurationClassEnhancer.createClass(ConfigurationClassEnhancer.java:118)

Since all this is runtime functionality (the @Configuration class is detected by <component-scan/> after the imports have been resolved), Virgo cannot know that your bundle will need cglib in the classpath.
Re: Spring annotation config [message #1062581 is a reply to message #1062580] Sun, 09 June 2013 12:15 Go to previous messageGo to next message
Rigas Grigoropoulos is currently offline Rigas Grigoropoulos
Messages: 9
Registered: November 2012
Junior Member
By the way it is not Virgo that decided which are the necessary classes in your bundle classpath in the xml variant. Virgo will load the packages defined as imports in your manifest. maven-bundle-plugin put the imports there by scanning your source and xml configuration. But since @Configuration does not have gclib imports and the spring-context lib that contains the annotation does not import gclib, the plugin cannot guess that this will be needed at runtime.
Re: Spring annotation config [message #1062595 is a reply to message #1062580] Sun, 09 June 2013 16:18 Go to previous messageGo to next message
Maarten Winkels is currently offline Maarten Winkels
Messages: 11
Registered: May 2013
Junior Member
Hi Rigas,

Thanks for your reply.

I have updated spring in virgo (user space) to version 3.2.2 which includes CGLib in spring-core (as I understand). Does that change your reasoning?

I can see that there is a difference there (needing CGLib classes on the class path when using annotation config) but wouldn't it be nice if Virgo would somehow support that?

Thanks!
-Maarten Winkels
Re: Spring annotation config [message #1062601 is a reply to message #1062595] Sun, 09 June 2013 20:04 Go to previous message
Rigas Grigoropoulos is currently offline Rigas Grigoropoulos
Messages: 9
Registered: November 2012
Junior Member
You may have cglib packages in Virgo (as part of spring or standalone) but unless your bundle imports them, they will not be available in your classpath.
The general procedure how to create a bundle is start with the minimal configuration for maven-bundle-plugin (which will create imports for what it can scan) and then deploy the bundle. For any ClassNotFoundException exception that comes after that, define extra imports in the <instructions> part of your maven-bundle-plugin configuration.

It would be nice if something could find out all the imports that would be needed at runtime for a bundle but unfortunately this does not exist, and the overhead of doing this manually is the price we have to pay for OSGi modularity. And this is not something Virgo should do as it is an OSGi container following a spec, so what you get when deploying your bundle in Virgo should be the same as when deploying it in another container.
Previous Topic:Help needed with basic resolution issue
Next Topic:Transaction management in Virgo
Goto Forum:
  


Current Time: Tue Sep 23 18:25:01 GMT 2014

Powered by FUDForum. Page generated in 0.02365 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software