History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: CAMEL-494
Type: Bug Bug
Status: Resolved Resolved
Resolution: Cannot Reproduce
Priority: Major Major
Assignee: Claus Ibsen
Reporter: Dean Thompson
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Apache Camel

CamelBeanPostProcessor.camelContext cannot be injected if SpringCamelContext is proxied (e.g. AOP)

Created: 05/May/08 07:07 AM   Updated: 23/Aug/08 12:40 AM
Component/s: camel-spring
Affects Version/s: 1.3.0, 1.4.0
Fix Version/s: 1.4.0

Time Tracking:
Not Specified

File Attachments:
  Size
Java Archive File Licensed for inclusion in ASF works camel-example-spring-jms-1.4-SNAPSHOT.jar 2008-06-10 08:11 AM Claus Ibsen 14 kb
XML File iris-framework.xml 2008-06-09 01:54 PM Dean Thompson 38 kb
XML File spring-magic.xml 2008-06-10 07:24 AM Dean Thompson 1 kb


 Description  « Hide
Because CamelBeanPostProcessor.setCamelContext(SpringCamelContext) takes the class SpringCamelContext as its parameter, bean initialization fails if SpringCamelContext is proxied. The error is as follows:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'camelContext:beanPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [$Proxy61] to required type [org.apache.camel.spring.SpringCamelContext] for property 'camelContext'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy61] to required type [org.apache.camel.spring.SpringCamelContext] for property 'camelContext': no matching editors or conversion strategy found

In my project's Spring conf, we declare <aop:aspectj-autoproxy/>, which causes all Spring beans to be proxied. This triggers the problem shown above. The problem should be reproducible by adding <aop:aspectj-autoproxy/> to any Spring config that uses <camel:camelContext>.

The fix will be to separate the interface and class for SpringCamelContext, and use the interface where appropriate.



 All   Comments   Work Log   Change History   Subversion Commits   FishEye   Crucible      Sort Order: Ascending order - Click to sort in descending order
Claus Ibsen - 06/May/08 09:24 PM
Added code blocks.

Dean, Can you whirl together a small sample / preferred unit test that demonstrates this bug? Would aid much during the fixing of the bug.


Claus Ibsen - 08/Jun/08 05:52 AM
Dan what version of Spring are you using?

Claus Ibsen - 08/Jun/08 07:45 AM
Dan I have refined a sample in camel trunk that uses the aop autoproxy stuff and I can not reproduce the bug you have reported.

The sample is the camel-example-jms-spring.

Can you give any hints how to reproduce the bug? Have you tried with a Camel 1.4 version?
There is a RC here:

Please find a first release candidate of apache-camel-1.4.0 here:
http://people.apache.org/~hadrian/apache-camel-1.4.0-RC1/maven2/


Claus Ibsen - 08/Jun/08 07:45 AM
Or if using maven try the 1.4-SNAPSHOT version instead.

Dean Thompson - 09/Jun/08 05:21 AM
Thanks very much, Claus, for looking at this. I'm sorry I didn't find time to submit an example. I was using Camel 1.3.0. I'll try with 1.4. I haven't been able to find camel-example-jms-spring; could you point me to it?

Claus Ibsen - 09/Jun/08 05:54 AM
Its in svn trunk.

However I can attach it to this jira as a .zip file later if you rather would like this, instead of having to checkout the code from svn.


Dean Thompson - 09/Jun/08 01:09 PM
I did check out https://svn.apache.org/repos/asf/activemq/camel/trunk. Unfortunately, I am stuck trying to get it to compile in maven:

[INFO] ------------------------------------------------------------------------
[INFO] Building Camel :: CXF
[INFO] task-segment: [install]
[INFO] ------------------------------------------------------------------------
Downloading: http://repo1.maven.org/maven2//com/sun/xml/fastinfoset/FastInfoset/1.2.2/FastInfoset-1.2.2.pom
Downloading: http://people.apache.org/repo/m2-incubating-repository/com/sun/xml/fastinfoset/FastInfoset/1.2.2/FastInfoset-1.2.2.pom
Downloading: http://repo.open.iona.com/maven2/com/sun/xml/fastinfoset/FastInfoset/1.2.2/FastInfoset-1.2.2.pom
Downloading: http://uface.googlecode.com/svn/maven//com/sun/xml/fastinfoset/FastInfoset/1.2.2/FastInfoset-1.2.2.pom
Downloading: http://repo1.maven.org/maven2/com/sun/xml/fastinfoset/FastInfoset/1.2.2/FastInfoset-1.2.2.pom
[INFO] [cxf-codegen:wsdl2java {execution: generate-test-sources}]
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Compiling 23 source files to C:\java\apache-camel-svn\camel\components\camel-cxf\target\classes
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Compilation failure
C:\java\apache-camel-svn\camel\components\camel-cxf\target\generated\org\apache\camel\wsdl_first\PersonService.java:[67,20] cannot find symbol
symbol : method getPort(javax.xml.namespace.QName,java.lang.Class<org.apache.camel.wsdl_first.Person>,javax.xml.ws.WebServiceFeature[])
location: class javax.xml.ws.Service

I got as far as downloading the JAXWS package manually and trying to follow its installation process, but so far I'm stuck there. I am assuming maven doesn't install that package automatically because it thinks of it as built into the JDK, but Sun doesn't install it automatically because it is javax (and hence an add-on)?

I did review the Camel 1.4.0 source code to see if the problem appears to have been fixed, and it does not appear to have been.
The fundamental problem, if I am following the code correctly, is that org.apache.camel.spring.CamelBeanPostProcessor.java is being placed into the spring configuration as a bean.
It has a method setCamelContext(SpringCamelContext), which is being driven from the Spring configuration also. However, SpringCamelContext is a class, not an interface. This means
that if the SpringCamelContext is proxied by <aop:aspectj-autoproxy/>, the resulting proxy is not a SpringCamelContext. So the attempt to invoke CamelBeanPostProcessor.setCamelContext(the proxy) fails.

I assume the test you added was examples/camel-example-spring-jms/src/main/resources/META-INF/spring/camel-server-aop.xml. I find myself wondering whether the <aop:aspectj-autoproxy/> declaration in that file applies to the
beans in the previously included <import resource="camel-server.xml"/>. Perhaps you have to either move the <aop:aspectj-autoproxy/> up above the <import resource="camel-server.xml"/>, or else do the <aop:aspectj-autoproxy/>
in the same file as the

<camel:camelContext id="camel">
<camel:package>org.apache.camel.example.server</camel:package>
</camel:camelContext>

?


Claus Ibsen - 09/Jun/08 01:43 PM
I am sure I had them in one file to start with. But then I changed to two files to cater for two kind of servers (with and without AOP) in the example.

Do you do anything special to proxy the camel bean?

I am sure we can extract and interface and let Camel use this but I would like to have a unit test that demonstrates the bug before starting the refactoring.
Okay I gotta jump into the bed.


Dean Thompson - 09/Jun/08 01:54 PM
Here is the Spring configuration file in which the problem occurs. Note that the portion of the XML that actually declares the <camel:camelContext> (and thus triggers the problem) is commented out with a reference to this issue.

Claus Ibsen - 09/Jun/08 09:04 PM
Hi Dean

Thanks for your spring file. I can see that the aspectj autoproxy declaration is in line 660 in your file.

I dont suppose you do some fancy magic in this file that is relevant for this bug?
<import resource="spring-magic.xml"/>

And in your file the Camel XSD reference is Camel 1.2. What version are you exactly using of Camel?


Claus Ibsen - 09/Jun/08 09:20 PM
Dean I have tried a single file and can not reproduce the bug.

However I noticed this answer that has been there all the time

ClassPathXmlApplicationContext INFO  Bean 'camel' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

That means that the CamelBeanPostProcessor that is being created during post processing is not auto proxied.
Dean do you see this INFO logging from Spring?

This is from the spring 2.5.3 source, in its AbstractApplicationContext

public Object postProcessAfterInitialization(Object bean, String beanName) {
			if (!(bean instanceof BeanPostProcessor) &&
					this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
				if (logger.isInfoEnabled()) {
					logger.info("Bean '" + beanName + "' is not eligible for getting processed by all " +
							"BeanPostProcessors (for example: not eligible for auto-proxying)");
				}
			}
			return bean;
		}

But I am running the example with Spring 2.5.4. What version of Spring are you using?


Claus Ibsen - 09/Jun/08 09:39 PM
I tried the example-spring-jms with Camel 1.3.0 and it also works out-of-the-box
D:\project\camel\examples\camel-example-spring-jms>mvn clean compile exec:java -PCamelServer494
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'exec'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Camel :: Example :: Spring :: JMS
[INFO]    task-segment: [clean, compile, exec:java]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] Deleting directory D:\project\camel\examples\camel-example-spring-jms\target
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Compiling 6 source files to D:\project\camel\examples\camel-example-spring-jms\target\classes
[INFO] Preparing exec:java
[INFO] No goals needed for project - skipping
[INFO] [exec:java]
[pache.camel.spring.Main.main()] Main                           INFO  Apache Camel 1.3.0 starting
[pache.camel.spring.Main.main()] ClassPathXmlApplicationContext INFO  Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@19fe451: display name [org.springframework.context.support.ClassPathXmlApplicationContext@19fe451]; startup date [Tue Jun 10 06:38:16 CEST 2008]; root o
f context hierarchy
[pache.camel.spring.Main.main()] XmlBeanDefinitionReader        INFO  Loading XML bean definitions from class path resource [META-INF/spring/camel-494.xml]
[pache.camel.spring.Main.main()] ClassPathXmlApplicationContext INFO  Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@19fe451]: org.springframework.beans.factory.support.DefaultListableBeanFactory@1757337
[pache.camel.spring.Main.main()] ClassPathXmlApplicationContext INFO  Bean 'org.apache.camel.example.server.ServerRoutes' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[pache.camel.spring.Main.main()] ClassPathXmlApplicationContext INFO  Bean 'Claus' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[pache.camel.spring.Main.main()] ClassPathXmlApplicationContext INFO  Bean 'Claus' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[pache.camel.spring.Main.main()] DefaultListableBeanFactory     INFO  Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1757337: defining beans [multiplier,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframewor
k.context.annotation.internalAutowiredAnnotationProcessor,Claus:beanPostProcessor,Claus,AuditTracker,AuditStore,jms,org.apache.activemq.xbean.XBeanBrokerService#0,org.springframework.aop.config.internalAutoProxyCreator]; root of factory hierarchy
[pache.camel.spring.Main.main()] BrokerService                  INFO  Using Persistence Adapter: MemoryPersistenceAdapter
[pache.camel.spring.Main.main()] BrokerService                  INFO  ActiveMQ 5.1.0 JMS Message Broker (localhost) is starting
[pache.camel.spring.Main.main()] BrokerService                  INFO  For help or more information please see: http://activemq.apache.org/
[pache.camel.spring.Main.main()] TransportServerThreadSupport   INFO  Listening for connections at: tcp://claus-acer:61616
[pache.camel.spring.Main.main()] TransportConnector             INFO  Connector tcp Started
[pache.camel.spring.Main.main()] BrokerService                  INFO  ActiveMQ JMS Message Broker (localhost, ID:claus-acer-2460-1213072701953-0:0) started
[pache.camel.spring.Main.main()] TransportConnector             INFO  Connector vm://localhost Started

Dean Thompson - 10/Jun/08 07:24 AM
Thanks for all of your hard work on this, Claus! I am enclosing the "spring-magic.xml" file that you asked about.

Dean Thompson - 10/Jun/08 07:28 AM
Claus, I think I should take the next step on this end. If you are able to help me get unstuck and take it,
that would be great. But in any case, I need to reproduce my problem on a small test case.

Since I was unable to compile the project in maven (as I reported above), I decided to try to use maven to generate an IntelliJ IDEA project. That failed too:

Downloading: http://people.apache.org/repo/m2-incubating-repository/org/apache/camel/maven-html-to-pdf/1.4-SNAPSHOT/maven-html-to-pdf-1.4-SNAPSHOT.jar
Downloading: http://people.apache.org/repo/m2-snapshot-repository/org/apache/camel/maven-html-to-pdf/1.4-SNAPSHOT/maven-html-to-pdf-1.4-SNAPSHOT.jar
Downloading: http://download.java.net/maven/2/org/apache/camel/maven-html-to-pdf/1.4-SNAPSHOT/maven-html-to-pdf-1.4-SNAPSHOT.jar
Downloading: http://repository.codehaus.org//org/apache/camel/maven-html-to-pdf/1.4-SNAPSHOT/maven-html-to-pdf-1.4-SNAPSHOT.jar
Downloading: http://repo.open.iona.com/maven2/org/apache/camel/maven-html-to-pdf/1.4-SNAPSHOT/maven-html-to-pdf-1.4-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] A required plugin was not found: Plugin could not be found - check that the goal name is correct: Unable to download the artifact from any repository

Try downloading the file manually from the project website.

Then, install it using the command:
mvn install:install-file -DgroupId=org.apache.camel -DartifactId=maven-html-to-pdf -Dversion=1.4-SNAPSHOT -Dpackaging=maven-plugin -Dfile=/path/to/file

Alternatively, if you host your own repository you can deploy the file there:
mvn deploy:deploy-file -DgroupId=org.apache.camel -DartifactId=maven-html-to-pdf -Dversion=1.4-SNAPSHOT -Dpackaging=maven-plugin -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]

org.apache.camel:maven-html-to-pdf:maven-plugin:1.4-SNAPSHOT

from the specified remote repositories:
apache.snapshots (http://people.apache.org/repo/m2-snapshot-repository),
codehaus.repo (http://repository.codehaus.org/),
open.iona.m2 (http://repo.open.iona.com/maven2),
apache.incubating.releases (http://people.apache.org/repo/m2-incubating-repository),
maven2-repository.dev.java.net (http://download.java.net/maven/2),
central (http://repo1.maven.org/maven2)

org.apache.camel:maven-html-to-pdf:maven-plugin:1.4-SNAPSHOT

from the specified remote repositories:
apache.snapshots (http://people.apache.org/repo/m2-snapshot-repository),
codehaus.repo (http://repository.codehaus.org/),
open.iona.m2 (http://repo.open.iona.com/maven2),
apache.incubating.releases (http://people.apache.org/repo/m2-incubating-repository),
maven2-repository.dev.java.net (http://download.java.net/maven/2),
central (http://repo1.maven.org/maven2)

If you are able to help with either a native Maven compile or a Maven -> Idea conversion, that would be great. Otherwise, I'll try porting your test case to ant to see it it works or breaks for me.


Claus Ibsen - 10/Jun/08 08:00 AM
Dean.

If you follow the instructions from: http://activemq.apache.org/camel/building.html you should be able to build the source from SVN checkout.

If you are still having problems then you could build only what you need:

cd camel-core
mvn clean install -Dtest=false

cd ..
cd components
mvn clean install -Dtest=false

cd ..
cd examples
mvn clean install -Dtest=false


Claus Ibsen - 10/Jun/08 08:02 AM
And you should be able to generate the idea project files for the example

cd examples
cd camel-examples-spring-jms
mvn idea:idea


Claus Ibsen - 10/Jun/08 08:04 AM
Dean you can also try the camel 1.4.0 release candidate

Please find a first release candidate of apache-camel-1.4.0 here:
http://people.apache.org/~hadrian/apache-camel-1.4.0-RC1/maven2/

It doesn't include all the latest AOP changes to the example but you could try with Camel 1.4.0 on your existing project.


Claus Ibsen - 10/Jun/08 08:11 AM
mvn package of the camel-example-spring-jms example.

Need to find all the jars needed on the CP yourself.


Claus Ibsen - 17/Jun/08 12:11 PM
Dean any update on this? We are homing into a Camel 1.4 release and want to either fix it asap or reschedule it for 1.5 or later.

Dean Thompson - 17/Jun/08 12:32 PM
Yikes – thanks for the heads up! I like the ASAP option . Do I still have a couple of days to jump on this? I don't know whether I can work on it tomorrow, but I'm fairly sure I can on Thursday.

Claus Ibsen - 24/Jun/08 09:19 PM
Hi Dean

Any updates? I am sorry but I can not reproduce the problem with Camel 1.4 and Spring 2.5.4.


Dean Thompson - 25/Jun/08 06:09 AM
No updates yet. I'm trying very hard to get back to this, but we have done a new beta release of our own software that has required "all hands".
If Camel 1.4 has to ship with no further work in this area, I understand. At the same time, I'm holding out hope that I can return to this issue
this week. Thank you, Claus, for your diligent and well-chosen work to help isolate this issue.

Dean Thompson - 25/Jun/08 06:17 AM
One other thought on this: Any class that is intended as a Spring bean really should make its functionality available through an interface.
Proxying class interfaces in Spring is possible in many cases, but is certainly not the norm or the recommended approach. Although
I agree, Claus, that the best first approach was to create a unit test that would fail, would you consider creating an interface for SpringCamelContext
just as a matter of good general Spring practice, and just verifying that the existing unit tests still work?

Dean Thompson - 25/Jun/08 06:20 AM
Sorry, my choice of language was confusing. I should say "proxying class APIs in Spring is possible...but not the norm".