Announcement Announcement Module
Collapse

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
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • jborrmann
    started a topic Using beans from other bundles

    Using beans from other bundles

    Hi,

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

    Code:
      <context:spring-configured/>
      <bean class="exporter1.Consumer1" scope="prototype">
        <property name="text" value="text1"></property>
      </bean>
    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

  • Costin Leau
    replied
    Hi Martin.
    Try the dm Server forum here: http://forum.springframework.org/forumdisplay.php?f=53. dm Server General probably is a good starting point: http://forum.springframework.org/forumdisplay.php?f=57

    Leave a comment:


  • Martin Lippert
    replied
    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? ;-)

    Thanks!!!
    -Martin

    Leave a comment:


  • Costin Leau
    replied
    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.

    Leave a comment:


  • jborrmann
    replied
    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

    Leave a comment:


  • jborrmann
    replied
    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.

    Code:
    _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
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http_protocolprefix/www.springframework.org/schema/beans"
      xmlns:xsi="http_protocolprefix/www.w3.org/2001/XMLSchema-instance"
      xmlns:aop="http_protocolprefix/www.springframework.org/schema/aop"
      xmlns:context="http_protocolprefix/www.springframework.org/schema/context"
      xmlns:osgi="http_protocolprefix/www.springframework.org/schema/osgi"
      xsi:schemaLocation="http_protocolprefix/www.springframework.org/schema/beans http_protocolprefix/www.springframework.org/schema/beans/spring-beans.xsd
        http_protocolprefix/www.springframework.org/schema/aop http_protocolprefix/www.springframework.org/schema/aop/spring-aop.xsd
        http_protocolprefix/www.springframework.org/schema/context http_protocolprefix/www.springframework.org/schema/context/spring-context.xsd
        http_protocolprefix/www.springframework.org/schema/osgi http_protocolprefix/www.springframework.org/schema/osgi/spring-osgi.xsd">
    
      <context:spring-configured/>
      
      <bean class="external1.C1" scope="prototype">
        <property name="text" value="text1"></property>
      </bean>
    </beans>
    B2 accordingly.

    Our framework (a third bundle F) simply does
    Code:
    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,
    --Jens

    Leave a comment:


  • Costin Leau
    replied
    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.

    Cheers,

    Leave a comment:


  • jborrmann
    replied
    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.

    Leave a comment:


  • Costin Leau
    replied
    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?

    Leave a comment:


  • jborrmann
    replied
    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

    Leave a comment:


  • Costin Leau
    replied
    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.

    Leave a comment:


  • jborrmann
    replied
    Hi Costin,

    okay, then I will try some camouflage for my URL forum.springframework.org/showthread.php?t=59126. (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

    Leave a comment:


  • Costin Leau
    replied
    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?

    Leave a comment:

Working...
X