Announcement Announcement Module
No announcement yet.
[PATCH] let spring-dm 1.x server support bundle start levels inside a PAR Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • [PATCH] let spring-dm 1.x server support bundle start levels inside a PAR


    Here is my patch against the spring-dm-server-1.0.2 source code that supports the startup level of PARed bundles.

    diff -u -r 1.0.1/com.springsource.server.deployer/com.springsource.server.deployer.core/src/main/java/com/springsource/server/deployer/app/ 1.0.1.patched/com.springsource.server.deployer/com.springsource.server.deployer.core/src/main/java/com/springsource/server/deployer/app/
    --- 1.0.1/com.springsource.server.deployer/com.springsource.server.deployer.core/src/main/java/com/springsource/server/deployer/app/	2008-11-27 12:08:28.000000000 +0800
    +++ 1.0.1.patched/com.springsource.server.deployer/com.springsource.server.deployer.core/src/main/java/com/springsource/server/deployer/app/	2009-05-16 23:03:22.000000000 +0800
    @@ -23,6 +23,7 @@
     import java.util.ArrayList;
    +import java.util.Comparator;
     import java.util.HashSet;
     import java.util.List;
     import java.util.Set;
    @@ -60,6 +61,7 @@
     import com.springsource.server.serviceability.tracing.TracerFactory;
     import com.springsource.server.serviceability.tracing.TracingService;
      * This class represents a deployable OSGi application.
      * <p />
    @@ -140,7 +142,7 @@
             this.moduleDeployerSet = moduleDeployerSet;
             this.modules = getModules(this.osgi, this.moduleFactory, this.applicationDeploymentArtefact);
             for (Module module : this.modules) {
    @@ -182,6 +184,30 @@
             if (!hasContent) {
                 modules.add(moduleFactory.create(this, applicationDeploymentArtefact.getURI()));
    +        //Shawn - Sort modules according to the bundle startLevel
    +        java.util.Collections.sort(modules,new Comparator<Module>(){
    +			public int compare(Module o1, Module o2) {
    +				int i1 = 0,i2=0;
    +				try{
    +					i1 = Integer.parseInt((String)o1.getBundle().getHeaders().get("Bundle-StartLevel"));
    +				}catch(Exception e){
    +					// ignore;
    +				}
    +				try{
    +					i2 = Integer.parseInt((String)o1.getBundle().getHeaders().get("Bundle-StartLevel"));
    +				}catch(Exception e){
    +					// ignore;
    +				}
    +				if(i1 < i2){
    +					return -1;
    +				}else if(i1 > i2){
    +					return 1;
    +				}else{
    +					return 0;
    +				}
    +			}
    +        });
             return modules;
    @@ -197,8 +223,20 @@
                 for (Module module : this.modules) {
    -            scope();
    +            // Don't scoping if par is shared.
    +            String appScope = getApplicationManifest().getMainAttributes().getValue("Application-Scope");
    +            if(TRACER.isInfoEnabled()){
    +                TRACER.traceInfo("Application-Scope '%s', %s.", appScope,this.getApplicationName());	
    +            }
    +            if("shared".equalsIgnoreCase(appScope)){
    +                if(TRACER.isInfoEnabled()){
    +                    TRACER.traceInfo("Service scoping is skipped for Shared Application '%s'", this.getApplicationName());	
    +                }
    +            }else{
    +                scope();
    +            }
                 for (Module module : this.modules) {
    diff -u -r 1.0.1/com.springsource.server.deployer/com.springsource.server.deployer.core/src/main/java/com/springsource/server/deployer/core/internal/ 1.0.1.patched/com.springsource.server.deployer/com.springsource.server.deployer.core/src/main/java/com/springsource/server/deployer/core/internal/
    --- 1.0.1/com.springsource.server.deployer/com.springsource.server.deployer.core/src/main/java/com/springsource/server/deployer/core/internal/	2008-11-27 12:08:30.000000000 +0800
    +++ 1.0.1.patched/com.springsource.server.deployer/com.springsource.server.deployer.core/src/main/java/com/springsource/server/deployer/core/internal/	2009-05-16 21:53:47.000000000 +0800
    @@ -72,6 +72,10 @@
         public void setApplicationManifest(DeployerBundleManifest manifest) {
             this.applicationManifest = manifest;
    +    protected DeployerBundleManifest getApplicationManifest(){
    +    	return this.applicationManifest;
    +    }
          * {@inheritDoc}
    Hope that helps.
    And I'll appreciate if this patch(or that kind of idea) could be accepted by your guys, so that I don't need to patch the source once again when new version of dm server is released.

  • #2
    Hi Shawn

    I believe dm Server 2.0 will solve both of the requirements that your patch is aimed at.

    The start order of bundles in a PAR in 1.x is essentially undefined, so in 2.0 we have introduced the concept of a "plan" which is a file listing contents, such as bundles, to be (installed and) started in the order specified in the plan. In fact, scoped, atomic plans (the plan functional equivalent to a PAR, except for the difference in packaging) are already supported in the latest milestone and nightly builds of 2.0.

    The other feature of your patch is to enable PARs to be optionally unscoped. Again, plans will satisfy this requirement in 2.0. An unscoped plan will do what you want. (Then you can choose separately whether to give the plan atomic or non-atomic lifecycle, if you care.) Unscoped plans will be coming into the 2.0 line before very long, but are dependent on the deployer pipeline rearchitecture that I'm currently up to my neck in. ;-)

    That said, I really appreciate you sending in the patch, but since PARs are working as designed in 1.x, I can't really justify integrating it. However, you have provided further validation that the plan function will be useful, so thanks for that.

    Meanwhile, have you considered reworking the bundles in your PAR to use Spring DM function to manage their service publications and consumption? Then the start order wouldn't matter. Or do you have some other reason for the bundles starting in a particular order? If I can understand your situation a bit better, I may be able to help you find a workaround that will avoid you having to patch the 1.x line of dm Server.

    What do you think?


    • #3
      Hi Glyn,

      Currently we're working on a framework-like project based on OSGi and DM-server. This private project has several components that using DM powered features(such as Import-Bundle, ApplicationContext support...etc).

      This is a PoC to us to verify whether we can develop apps or even frameworks in dynamic-module way, based on DMServer and OSGi technology.

      That's why we're facing the startup precedence and the shared-service(scoping) problems on DM server.

      It's a little bit awkward to us now because our framework indeed is nothing but a standard par to DM-Server, but it requirs more "special" privileges than other apps.

      We now managed to cover most of those problems(start precedence,shared service, hooking something) by pathcing and providing a special extension.

      Now we're looking forward to the release of 2.0.




      • #4
        I see. Good to know 2.0 will help you.

        Meanwhile I hope you'll find the 1.0.x stream fairly stable so you can continue to apply your patch without much effort.