Announcement Announcement Module

Spring Dynamic Modules forum decommissioned in favor of Eclipse Gemini Blueprint

With the official first release of Eclipse Gemini Blueprint shipped, the migration of the Spring Dynamic Modules code base to the Eclipse Foundation, as part of the Gemini project, has been completed.

As such, this forum has been decommissioned in favour of the Eclipse Gemini forums.
See more
See less
Using beans from other bundles Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using beans from other bundles


    should dependency injection work for beans with scope = prototype that are defined in other bundles?

      <bean class="exporter1.Consumer1" scope="prototype">
        <property name="text" value="text1"></property>
    I have a constellation in which I have to instantiate the class programmatically using new and not via beans.xml. Sometimes this works and the field of the created class is injected, sometimes it does not work.

    If more details are required to answer this question you can take a look at thread 59126 (threading issues with scope="prototype", sorry I cannot post URLs yet...)

    Any ideas?

    Best regards, Jens

  • #2
    Jens, at what thread are you referring? You cannot post links but you can remove the http heading (or add some spaces). The link won't be clickable but readable.
    Also, is this an OSGi or generic container question?


    • #3
      Hi Costin,

      okay, then I will try some camouflage for my URL (that was really easy)

      I am not quite sure which subforum is adequate since it involves both core functionality (dependency injection) and OSGi stuff. Not having received an answer in the core container forum I tried it here. But I do not mind continuing the discussion somewhere else...

      -- Jens


      • #4
        Hi Jens,

        I've read the thread mentioned but I don't understand what the issue it - your code creates two objects locally but the posted logs refer to an introspection class from Spring.
        Also, I don't understand why after you are creating the object, you try to see if the object is set? Set by who? you just created the objects yourself.


        • #5
          Hi Costin,

          thanks for answering and adding a _real_ link ;-)

          I expected to see the text injected into both of these objects I create locally. This does (usually) happen for one of these two, which then causes the log entries from Spring. I can even set breakpoints in eclipse and walk thugh all this proxy stuff that leads to the log entries.

          Did I get you right that my code is completely abusing some concepts?

          What is interesting is that the property is always injected whenever I just create objects from one other bundle. Is this just some random behaviour?

          -- Jens


          • #6
            I think you ran into a bug here. When you export services as prototype, you won't get one new instance on each call. This happens since the OSGi platform always caches the service instance. You can however have a new instance attached in the backend by using aop:scoped-proxy tag - a scoped proxy which keeps the same reference but always delegates the call to a backing instance.
            This is a known behaviour for which special workarounds needs to be added (there is also a jira issue on this).
            You can double check this by changing the scope of the proxy - see whether that makes any difference.

            However, in your case you are creating the beans not importing them so it might be that the weaving configuration doesn't work properly for some reason. What type of LTW are you using?


            • #7
              We use AspectJ for LTW. The implementation bundle is org.springframework.aspects in version 2.5.5.

              Please note that I am not exporting services but only defining prototype beans for some classes. Then I create instances of those classes locally in a different bundle. Is your recommendation to use aop:scoped-proxy also valid in this case?

              Can the problems concering caching you described explain why dependency injection does not work for instances of classes from two separate bundles? IMHO this would rather explain the same phenomena for instances of the same class.


              • #8
                aop:scoped-proxy regards instances injected by the context. In your case the LTW works on the class definition itself so it shouldn't matter how you create the objects. You are right about the caching - it affects only OSGi services which again doesn't seem to be your case.
                Regarding the LTW, are you using an agent or a context defined LTW? I ask since non-agents LTW use the classloader of the declaring context which can be problematic in OSGi.
                By the way, try using S2AP - LTW are properly addressed in there (especially with regards to refresh and unweaving classes). It can be a nice test to see whether it works or not in S2AP.



                • #9
                  Hi Costin and others...

                  we reinvestigated the problem described above and are not quite sure wether we found a bug. To make it easier to discuss the issue I will sum up the whole constellation. So nobody will have to look into other threads.

                  Let's say, for some reasons we have a framework that knows nothing of Spring. It has to instantiate classes using the constructor (directly or via reflection).
                  To initialize and to configure the classes that are instantiated by our framework, we would like to use spring. So we had the idea to use AspectJ (compile time weaving - not LTW, sorry Costin for reporting this fact wrong before)
                  and Spring (version 2.5.5.A) to do spring-configured initialization.

                  Here is a small example and setup to illustrate our problem:

                  We have 2 supporting bundles: B1 and B2. Each bundle is exporting a package with one class C1 and C2 respectively.

                  _at_Configurable (preConstruction = false)
                  public class C1 {       // with constructor
                    private String text;  // with getters and setters
                  C2 accordingly.

                  The Spring configuration for B1 looks like
                  <?xml version="1.0" encoding="UTF-8"?>
                  <beans xmlns="http_protocolprefix/"
                    xsi:schemaLocation="http_protocolprefix/ http_protocolprefix/
                      http_protocolprefix/ http_protocolprefix/
                      http_protocolprefix/ http_protocolprefix/
                      http_protocolprefix/ http_protocolprefix/">
                    <bean class="external1.C1" scope="prototype">
                      <property name="text" value="text1"></property>
                  B2 accordingly.

                  Our framework (a third bundle F) simply does
                  new C1();
                  new C2();
                  after it has made sure that the application contexts for B1 and B2 have been initialized.

                  What we experience is, that only one class is initialized by Spring, never both. Which one of them is initialized is not deterministic.

                  A short debugging session revealed, that both classes, C1 and C2, have been associated with a class 'AnnotationBeanConfigurerAspect'. As expected ;-)
                  What we do not understand is, that both classes are associated by the SAME INSTANCE of AnnotationBeanConfigurerAspect. AnnotationBeanConfigurerAspect has a method
                  'setBeanFactory' which is called twice, once for the application context for bundle B1 and once for the application context for B2. The order does not seem to be deterministic.
                  And, as expected, the second call wins. Whatever the second call sets, the coresponding class C1 or C2 will be initialized, the one other not.

                  Are we doing something wrong? Are we missing some basic concept? Or is this behavior just a bug?

                  Thank you a lot for your help,


                  • #10
                    In the meantime we have figured out what was/is wrong in our case.

                    In our setup we have the spring-aspects-jar as a bundle in our target platform and not embedded in every domain bundle doing spring configuration. Therefore the AnnotationBeanConfigurerAspect is created exactly once (singleton) in the context of the spring-aspects-bundle and then used for the whole application, which leads to the behaviour we described in our posts.

                    We experimented with copying the jar into each bundle using <context:spring-configured>, which did work. But we discarded this approach for two reasons:
                    1) Update risk: In case of an update of the aspects bundle we would have to remember every single occurence, which does not work very well as soon as you have several teams working having to do this...
                    2) Import risk: As soon as somebody would by accident or ignorance import the package containing the aspects from the aspects-bundle in the target platform the whole mechanism would bypassed. As a consequence of the OSGi resolving algorithm always the aspect from the target bundle would be used and we would be back at the singleton problem :-(

                    So we decided to do without automatic dependency injection for prototypes.

                    -- Jens


                    • #11
                      Interesting find. Have you considered running your app inside dm Server. I'd recommend raising this issue on their forum as well since it's likely situations like these are/will be properly addressed in dm server.


                      • #12
                        Hi Costin!

                        Can you give me more details on how the spring dm server solves this issue? Or can you point me to the right place to ask those questions? ;-)



                        • #13
                          Hi Martin.
                          Try the dm Server forum here: dm Server General probably is a good starting point: