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
Context File Load Order Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Context File Load Order

    I have an interesting problem dealing with context startup order.

    In my spring powered bundle I have multiple context files and one of them needs to startup before any of the others (a kind of bootstrap context). The context defines a factory bean (which provides properties to other beans), this singleton may or may not be accessed statically (not spring managed) by beans in other context files. The context loader for a bundle reads contexts in alphabetical order by default and a new context could be added in the future that accidentally starts before just because of its name - thus causing the application to crash with a null pointer.

    - I tried to create a separate thread, but the calls to the singleton are sometimes made in a class' field.
    - I can't have the singleton spring managed because it would be too much work to refactor.
    - I haven't tried "import", but it seems erroneous to require that every context import a startup context.
    - Creating a service doesn't work because the singleton is statically accessed.
    - I haven't tried overriding the ApplicationContextCreator because I don't want to have to maintain this hook.

    The only easy solution I've found is doing this below, which will load the bootstrap context and then any other context file. The only bad things are: we have to remember to add it and the manifest must become Spring aware.


    Is there a better solution?

    Should Spring-DM provide a special location to load any bootstrap context files? Like, if Spring finds a context in "META-INF/spring/bootstrap/" then it loads those first.

  • #2
    I'm not sure if I got your problem correctly, but I understood that one your Spring-powered bundle has some Spring beans that depend on some kind of root bean which does some initialization.

    Let's assume I got it right. Spring DM can create a Spring application context from different files, but these files does not define an application context of their own. Spring reads all the files, computes all the dependency between the beans and creates them according to these dependencies. If they are no dependency between beans, the order of creation is undefined (or Spring does not define any strict contract about it).

    So your problem is more about the Spring container than about Spring DM. You can tweak the creation order by creating dependencies between beans, thanks to the "depends-on" attribute of the "tag" bean. This allows you to define dependencies "artificially" (as opposed to dependency injection) and tells the Spring container to create beans in a clearly defined manner.

    If I got your problem wrong, perhaps you have a dependency problem that spreads accross Spring-powered bundles and that's another story.


    • #3
      I Still think Spring DM should handle this case

      Thank you for your response arno. You understood the question right, but still not a good/usable solution in my opinion.

      I was thinking, it still may be the case, the problem is with Spring DM. Because the initializing bean might not be available at startup due to OSGi's dynamic nature... I had hoped that Spring DM would help more than providing a "depends-on".

      The "depends-on" solution works but fails in my opinion because the amount of work involved does not scale and developers have to remember that dependency each time (we have a very large product). In other words, I don't want to have to write "depends-on" for n number of beans; I would rather tell Spring just once which bean (or context file) must be loaded before all others.

      "perhaps you have a dependency problem that spreads accross Spring-powered bundles"
      This problem could exist with just two bundles and a single dependency on the initializing bean's bundle.
      Last edited by; Aug 25th, 2009, 06:33 PM. Reason: spelling


      • #4
        You're not facing a Spring DM's issue, but a Spring's issue. As I said, the only reliable way to control the order of bean creation is to create dependencies between them, either explicitly (with dependency injection) or artificially (by using the depends-on attribute). There's not much Spring DM can do for you.

        There's perhaps a workaround, but it's nasty and fragile. You can specify the context files in the right order, thanks to the Spring-Context header (no guarantee it'll work and caveat emptor!).

        I think you should definitely find a reliable way to solve your problem, by either changing your design or declaring the dependencies for Spring to create the bean in the right order. Perhaps you could use the bean definition inheritance, where a parent bean definition would contain the depends-on attribute and other beans would use it as a template.

        For the dependency that would spread accross Spring-powered bundles, as long you rely on OSGi services and Spring DM to publish/consume them, you should not have any problem.


        • #5
          Brian, Spring as the container uses two rules for creating beans:
          1. dependency order
          2. declaration order
          That is, first it creates the beans based on the dependency between them and then, if it has a choice, based on the way it encountered the beans during parsing.

          As was discussed, you can either declare the first beans that you depend first, or you can use 'depends-on' to guarantee an ordering initialization.
          There is no concept of bootstrapping files - for your case this would exhibit the same problems if more then one file would be placed under META-INF/spring/bootstrap/.

          Note that you could use a Spring infrastructure class, such as BeanFactoryPostProcessor & co to interfere with the bean factory configuration and force eager initialization of certain beans.