Exceptions if <geda:annotation-driven> is added to Spring context

96 views
Skip to first unread message

Alex

unread,
Sep 11, 2013, 10:24:08 AM9/11/13
to geda-generic-dto-asse...@googlegroups.com
Hi there,
first of all - nice framework guys, keep going forward!

I've got a question though - the core functionality works for me but Spring integration unfortunately not.

The exceptions start to appear in the log once I add <geda:annotation-driven dto-factory="dtoFactory" use-bean-preprocessor="true"/> declaration.

This is my current setup - a Spring MVC Web application with 2 Spring context files - one for MVC, second one for the beans. In the second one once I declare this line I start getting exceptions like this on Spring startup:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.fasterxml.jackson.databind.ObjectMapper com.My.objectMapper; nested exception is java.lang.IllegalArgumentException: Can not set com.fasterxml.jackson.databind.ObjectMapper field com.MyController.objectMapper to $Proxy45
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) ~[spring-context-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) ~[spring-context-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389) ~[spring-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294) ~[spring-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112) [spring-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4887) [catalina.jar:7.0.40]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5381) [catalina.jar:7.0.40]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.40]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) [catalina.jar:7.0.40]
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) [catalina.jar:7.0.40]
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633) [catalina.jar:7.0.40]
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:657) [catalina.jar:7.0.40]
at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1636) [catalina.jar:7.0.40]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439) [na:1.6.0_37]
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) [na:1.6.0_37]
at java.util.concurrent.FutureTask.run(FutureTask.java:138) [na:1.6.0_37]
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [na:1.6.0_37]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [na:1.6.0_37]
at java.lang.Thread.run(Thread.java:662) [na:1.6.0_37]
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.fasterxml.jackson.databind.ObjectMapper com.MyController.objectMapper; nested exception is java.lang.IllegalArgumentException: Can not set com.fasterxml.jackson.databind.ObjectMapper field com.MyController.objectMapper to $Proxy45
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
... 27 common frames omitted
Caused by: java.lang.IllegalArgumentException: Can not set com.fasterxml.jackson.databind.ObjectMapper field com.MyController.objectMapper to $Proxy45
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146) ~[na:1.6.0_37]
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150) ~[na:1.6.0_37]
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63) ~[na:1.6.0_37]
at java.lang.reflect.Field.set(Field.java:657) ~[na:1.6.0_37]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:510) ~[spring-beans-3.2.3.RELEASE.jar:3.2.3.RELEASE]
... 29 common frames omitted

MyController is a class with @Controller annotation and it injects a few beans with using @Autowired - no matter which bean, if I comment one of them it starts complaining about another one. Any ideas?
For now on I have to continue with using DTOSupport helper as a workaround.

 A question on another matter - why don't you make a default implementation of DTOSupport bean available in the context automatically? Otherwise I have to declare it by myself:
<bean id="dtoSupport" class="com.inspiresoftware.lib.dto.geda.impl.DTOSupportImpl"/>

Denis Pavlov

unread,
Sep 11, 2013, 11:07:04 AM9/11/13
to geda-generic-dto-asse...@googlegroups.com
Hi Alex,

I'll start from the end of your e-mail.
Regaring auto creation of DTOSupportImpl - that is exactly what the <geda:annotation-driven dto-factory="dtoFactory" use-bean-preprocessor="true"/> is doing. Here is a full overview how to use the GeDA Spring API: http://inspire-software.com/confluence/display/GeDA/Spring+API  

By default id "dtoSupport" is reserved by the GeDA bean processor and it will use it for auto created com.inspiresoftware.lib.dto.geda.impl.DTOSupportImpl, so you should not have to declare your own bean. In fact for annotation driven you should not have any references to that bean in you application as all in encapsulated via AOP. If you want to use DTOSupport in your beans I think you need to look into xml-driven which provides better access to it (instructions in the link above)

Looking at your stacktrace it seems like autowired dependencies are not satisfied. Hard to say but maybe there is conflict with your bean declaration and what preprocessor is doing or maybe pre processor has not yet executed.

Do you have full stacktrace? as it is difficult to pinpoint the problem as there is no reference to GeDA classes.
BTW you can download source code and place a debug breakpoint into preprocessor to see if actually gets invoked before you get this exception - just to make sure that dtoSupport bean does get created.

Let me know if any of this helps, otherwise I will need more detailed logs and configuration files to investigate further.

Regards,
Denis

P.S. There is examples module that you can download that has fully functional integration with Spring API and also integration tests constain working examples as well if you download full sources.

Alex

unread,
Sep 11, 2013, 11:40:08 AM9/11/13
to geda-generic-dto-asse...@googlegroups.com
Hi Denis,
ok, I got it. My Spring context works fine, but if I just add <geda:annotation-driven> declaration everything stops working. This is the full stack I provided, no additional error information. BTW If use-bean-preprocessor attribute is removed the same error is still reproduced.

Actually I downloaded the examples as well as the source code - but I miss "real" project examples over there, the units tests are not really good examples. I'm gonna make a small maven project to demonstrate the issue and once reproduced post it to JIRA issue.

A question on another matter - why don't you implement auto-scan of annotated DTOs to avoid declaration of dtoDactory, I mean something similar like this: 
<geda:annotation-driven />
<geda:dto-scan base-package="com.example.package"/>


Regards,
Alex

Denis Pavlov

unread,
Sep 11, 2013, 11:59:50 AM9/11/13
to geda-generic-dto-asse...@googlegroups.com
Hi Alex,

Thanks for your reply. You are right example are only in junits of Spring API - sorry for misleading you. But to be honest there is not must to the integration itself. All you need is geda declaration, dtoFactory bean and your service bean with @Transferable:

<geda:annotation-driven dto-factory="dtoFactory" use-bean-preprocessor="false"/>

    <bean id="dtoFactory" class="com.inspiresoftware.lib.dto.geda.impl.DTOFactoryImpl">
        <constructor-arg>
            <map>
...
            </map>
        </constructor-arg>
    </bean>

    <bean id="annSimpleTransferableService"
          class="com.inspiresoftware.lib.dto.geda.test.impl.AnnotatedTestServiceImpl"/>

BTW your comment about the same error - I strongly believe that it is a setup issue, whereby the dtoSupport bean is not available for some reason to your controllers. Can you try creating ApplicationContextAware bean and write some code in setter to verify that dtoSupport actually exists or not? if it does not exists there are two options: it is never created due to invalid context setup, or GeDA crashes somewhere - but I really would expect some stacktrace for that? Can you double check your logs?

P.S. Thanks for the tip about that project - have not seen it before )). If you think this feature really deserves to be part of GeDA - could add this a new feature request in jira? 

Denis Pavlov

unread,
Sep 17, 2013, 3:49:44 AM9/17/13
to geda-generic-dto-asse...@googlegroups.com
Hey Alex, so have you progressed with your problem? Let me know - I am keen to know!

Alex

unread,
Sep 17, 2013, 5:26:17 PM9/17/13
to geda-generic-dto-asse...@googlegroups.com
Not really progressed yet, a small sample Spring application without Spring MVC works fine, but still there's something in my current setup that causes errors. Still trying to find out what is wrong over there.

Denis Pavlov

unread,
Sep 17, 2013, 6:58:44 PM9/17/13
to geda-generic-dto-asse...@googlegroups.com
Have you tried to use xml-driven ?
Reply all
Reply to author
Forward
0 new messages