9 Replies Latest reply on Nov 1, 2012 9:28 PM by Freeman(Yue) Fang

    Spring annotations, component-scanning, autowiring - and Blueprint?

    Constantine Vasilyev Newbie

      A newbie question... I am exploring a possibility of repackaging an existing Spring project as OSGi bundles. My modules have Spring-annotated classes (e.g. @Component-annotated) with @autowired- and @Value-annotated properties, etc. If I understand correctly, to export some of my shared beans as OSGi services (defined in one bundle) I would need to create service definitions in the bundle's Blueprint configuration XML(s), not in Spring. (Assuming I am using Aries.) I do realize that the Blueprint spec came out of of Spring DM and is itself a dependency-injection container for OSGi.  Does this mean that I should be using Blueprint/Aries instead of Spring, not with it?  Does this mean I would have to redefine all the client beans (that live in other bundles and need to be injected with the references to those shared "services") as Blueprint beans? Does this mean I can no longer rely on Spring auto-wiring, component scanning, etc? Or will I be able to use "regular" Spring contexts together with Blueprint?


      I wouldn't want to a) have to change my implementation just because I am packaging the artifacts differently now, b) give up on familiar and convenient Spring features - for whatever reasons.  An old tutorial I found on the Internet (from 2009) demonstrates the usage of Spring DM with separate configuration files for regular Spring and OSGi service definitions per bundle. That makes a lot of sense, it allows reusing regular Spring definitions for testing and any non-OSGi stuff. I have tried something similar with Blueprint/Aries, but, evidently, the Blueprint-context objects are not seen by my Spring beans.  Am I missing something? I'm exploring a new territory here, and any up-to-date tutorials seem to be sparse. So, I'd appreciate any clarifications or advice.


      Many thanks for your help!


      Edited by: constv7 on Oct 30, 2012 8:50 PM

        • 1. Re: Spring annotations, component-scanning, autowiring - and Blueprint?
          Freeman(Yue) Fang Master



          You can consider to use spring-dm but not blueprint if your bean already use a lot of spring annotation, though we suggest to use blueprint instead.


          And if you use blueprint to expose OSGi service from one bundle, you still can use another bundle which use spring-dm to hold the OSGi service reference. You just can't use both blueprint and spring-dm in same bundle, but no such limitation across bundle boundary.



          • 2. Re: Spring annotations, component-scanning, autowiring - and Blueprint?
            Constantine Vasilyev Newbie

            Thank you, Freeman. This is a very helpful clarification.

            • 3. Re: Spring annotations, component-scanning, autowiring - and Blueprint?
              Constantine Vasilyev Newbie

              A quick follow-up question. When you say "Spring DM", do you mean the older/original/obsolescent Spring project (pre-Gemini) or the latest reincarnation of it in the form of Gemini Blueprint? I assume it is the former, correct?


              Edited by: constv7 on Oct 31, 2012 1:36 PM

              • 4. Re: Spring annotations, component-scanning, autowiring - and Blueprint?
                Claus Ibsen Master

                No, its the spring-dm 1.2.1 which is currently supported.


                For blueprint currently Aries Blueprint is only supported. In the future we will also support other implementations of Blueprint.

                • 5. Re: Spring annotations, component-scanning, autowiring - and Blueprint?
                  Constantine Vasilyev Newbie

                  So, this means that if I use Spring 3.x, using the old Spring DM v1.x is out of the question - it just won't work.  


                  I am a bit lost now... What if I have a Spring3-managed bean "serviceConsumerA" in BundleA that needs to be injected with a bean implementation from BundleB - "serviceB"?

                  I already have the application context configuration in BundleA that resolves properties and properly autowires serviceConsumerA with everything else. (Specifically, we have a CamelContext Spring XML definition that refers to a bean with a property whose implementation is - must be - defined in another shared bundle.)  How do I make that work then?


                  I understand that I can define serviceB via blueprint in BundleB and export it.  If BundleA imports the appropriate packages from BundleB, how can I properly inject serviceB into serviceConsumerA? By defining serviceConsumerA via Blueprint instead of Spring? But that would mean that I should forgo my Spring3 definitions of that bean and all its dependencies and reconfigure all of those via Blueprint, correct?  If so, this means I cannot use any Spring annotations on the involved classes... And is it even possible to move the  definition into a Blueprint XML file?


                  Edited by: constv7 on Oct 31, 2012 7:28 PM

                  • 6. Re: Spring annotations, component-scanning, autowiring - and Blueprint?
                    Constantine Vasilyev Newbie

                    Currently, my camel context configuration looks like this (sorry, I couldn't find a way to use the tags, so everything is spilled as plain text...):




                    NOTE: Originally I was hoping to simply auto-scan the "myFileFilter" implementation. The "myTransform" instance relies on a property whose implementation must live in a different (shared) bundle. How do I make it all work using plain Aries Blueprint? Specifically, what would the CamelContext configuration XML look like in Blueprint? All examples use Spring...  Or should I use Java DSL instead?




                    Many thanks for your help and suggestions!


                    Edited by: constv7 on Oct 31, 2012 7:16 PM

                    • 7. Re: Spring annotations, component-scanning, autowiring - and Blueprint?
                      Freeman(Yue) Fang Master



                      No, in your bundle A you can still use spring and use spring-dm way to inject the OSGi service reference.

                      For your case, something like




                      Ensure your spring-dm file is under path src/main/resources/META-INF/spring/



                      • 8. Re: Spring annotations, component-scanning, autowiring - and Blueprint?
                        Constantine Vasilyev Newbie

                        Thanks for your help. Would this work with Spring 3.x though? I am getting the following exception when deploying the "consuming" bundle:


                        Caused by: org.xml.sax.SAXParseException: cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'osgi-springdm:reference'.

                             at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)[:]

                             at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source)[:]

                             at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)[:]

                             at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)[:]

                             at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)[:]

                             at org.apache.xerces.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)[:]

                             at org.apache.xerces.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)[:]

                             at org.apache.xerces.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)[:]

                             at org.apache.xerces.impl.xs.XMLSchemaValidator.emptyElement(Unknown Source)[:]

                             at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)[:]

                             at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)[:]

                             at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)[:]

                             at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)[:]

                             at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)[:]

                             at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)[:]

                             at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)[:]

                             at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)[:]

                             at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75)[66:org.springframework.beans:3.0.6.RELEASE]

                        *     at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:388)[66:org.springframework.beans:3.0.6.RELEASE]*

                             ... 18 more




                        I've tried to specify various schema locatinos in the XML header, but nothing works. The farthest I was able to get was the following exception:


                        org.springframework.beans.NotWritablePropertyException: Invalid property 'osgiSpringdm' of bean class : Bean property 'osgiSpringdm' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

                             at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1052)[66:org.springframework.beans:3.0.6.RELEASE]

                             at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:921)[66:org.springframework.beans:3.0.6.RELEASE]

                             at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)[66:org.springframework.beans:3.0.6.RELEASE]

                             at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:58)[66:org.springframework.beans:3.0.6.RELEASE]

                             at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1358)[66:org.springframework.beans:3.0.6.RELEASE]