FELIX-2027: Custom deployers leveraging url handlers must not be registered before the url handler is actually registered in the osgi framework

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@905551 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/karaf/deployer/blueprint/pom.xml b/karaf/deployer/blueprint/pom.xml
index d5251ad..7f7a69c 100644
--- a/karaf/deployer/blueprint/pom.xml
+++ b/karaf/deployer/blueprint/pom.xml
@@ -69,7 +69,9 @@
                 <artifactId>maven-bundle-plugin</artifactId>
                 <configuration>
                     <instructions>
-                        <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+                        <!-- Set the blueprint.graceperiod flag to false to allow the bundle to start
+                             See the blueprint config file -->
+                        <Bundle-SymbolicName>${pom.artifactId};blueprint.graceperiod:=false</Bundle-SymbolicName>
                         <Export-Package>${pom.artifactId}*;version=${project.version}</Export-Package>
                         <Import-Package>!${pom.artifactId}*,*</Import-Package>
                         <Private-Package>org.apache.felix.karaf.deployer.blueprint</Private-Package>
diff --git a/karaf/deployer/blueprint/src/main/resources/OSGI-INF/blueprint/blueprint-deployer.xml b/karaf/deployer/blueprint/src/main/resources/OSGI-INF/blueprint/blueprint-deployer.xml
index 4726e44..bc55e2e 100644
--- a/karaf/deployer/blueprint/src/main/resources/OSGI-INF/blueprint/blueprint-deployer.xml
+++ b/karaf/deployer/blueprint/src/main/resources/OSGI-INF/blueprint/blueprint-deployer.xml
@@ -19,15 +19,22 @@
 -->
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
 
-    <service auto-export="interfaces" depends-on="blueprintUrlHandler">
-        <bean class="org.apache.felix.karaf.deployer.blueprint.BlueprintDeploymentListener" />
-    </service>
-
     <service id="blueprintUrlHandler" interface="org.osgi.service.url.URLStreamHandlerService">
-    	<service-properties>
+        <service-properties>
             <entry key="url.handler.protocol" value="blueprint"/>
         </service-properties>
         <bean class="org.apache.felix.karaf.deployer.blueprint.BlueprintURLHandler"/>
     </service>
 
+    <bean id="blueprintDeploymentListener" class="org.apache.felix.karaf.deployer.blueprint.BlueprintDeploymentListener"/>
+
+    <!-- Force a reference to the url handler above from the osgi registry to (try to) make sure
+         the url handler is registered inside the framework.  Else we can run into timing issues
+         where fileinstall will use the featureDeploymentListener before the url can be actually
+         used.  In order to not block the bundle, the blueprint.graceperiod=false flag must be
+         set on the SymbolicName osgi header -->
+    <reference id="blueprintUrlHandlerRef" interface="org.osgi.service.url.URLStreamHandlerService" filter="url.handler.protocol=blueprint" />
+
+    <service ref="blueprintDeploymentListener" auto-export="interfaces" depends-on="blueprintDeploymentListener" />
+
 </blueprint>
diff --git a/karaf/deployer/features/pom.xml b/karaf/deployer/features/pom.xml
index 575749f..86abcfb 100644
--- a/karaf/deployer/features/pom.xml
+++ b/karaf/deployer/features/pom.xml
@@ -73,7 +73,9 @@
                 <artifactId>maven-bundle-plugin</artifactId>
                 <configuration>
                     <instructions>
-                        <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+                        <!-- Set the blueprint.graceperiod flag to false to allow the bundle to start
+                             See the blueprint config file -->
+                        <Bundle-SymbolicName>${pom.artifactId};blueprint.graceperiod:=false</Bundle-SymbolicName>
                         <Export-Package>${pom.artifactId}*;version=${project.version}</Export-Package>
                         <Import-Package>!${pom.artifactId}*,*</Import-Package>
                         <Private-Package>org.apache.felix.karaf.deployer.features</Private-Package>
diff --git a/karaf/deployer/features/src/main/java/org/apache/felix/karaf/deployer/features/FeatureDeploymentListener.java b/karaf/deployer/features/src/main/java/org/apache/felix/karaf/deployer/features/FeatureDeploymentListener.java
index 6a7f256..c1e9b57 100644
--- a/karaf/deployer/features/src/main/java/org/apache/felix/karaf/deployer/features/FeatureDeploymentListener.java
+++ b/karaf/deployer/features/src/main/java/org/apache/felix/karaf/deployer/features/FeatureDeploymentListener.java
@@ -39,7 +39,7 @@
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
-import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.framework.BundleListener;
 import org.xml.sax.ErrorHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
@@ -47,7 +47,7 @@
 /**
  * A deployment listener able to hot deploy a feature descriptor
  */
-public class FeatureDeploymentListener implements ArtifactUrlTransformer, SynchronousBundleListener {
+public class FeatureDeploymentListener implements ArtifactUrlTransformer, BundleListener {
 
     public static final String FEATURE_PATH = "org.apache.felix.karaf.shell.features";
 
@@ -76,7 +76,9 @@
     public void init() throws Exception {
         bundleContext.addBundleListener(this);
         for (Bundle bundle : bundleContext.getBundles()) {
-            bundleChanged(new BundleEvent(BundleEvent.INSTALLED, bundle));
+            if (bundle.getState() == Bundle.RESOLVED || bundle.getState() == Bundle.STARTING
+                    || bundle.getState() == Bundle.ACTIVE)
+            bundleChanged(new BundleEvent(BundleEvent.RESOLVED, bundle));
         }
     }
 
diff --git a/karaf/deployer/features/src/main/resources/OSGI-INF/blueprint/features-deployer.xml b/karaf/deployer/features/src/main/resources/OSGI-INF/blueprint/features-deployer.xml
index faad6b0..001f18e 100644
--- a/karaf/deployer/features/src/main/resources/OSGI-INF/blueprint/features-deployer.xml
+++ b/karaf/deployer/features/src/main/resources/OSGI-INF/blueprint/features-deployer.xml
@@ -20,7 +20,12 @@
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
            default-activation="lazy">
 
-    <service ref="featureDeploymentListener" auto-export="interfaces" depends-on="featureUrlHandler"/>
+    <service id="featureUrlHandler" interface="org.osgi.service.url.URLStreamHandlerService">
+    	<service-properties>
+            <entry key="url.handler.protocol" value="feature"/>
+        </service-properties>
+        <bean class="org.apache.felix.karaf.deployer.features.FeatureURLHandler"/>
+    </service>
 
     <bean id="featureDeploymentListener" class="org.apache.felix.karaf.deployer.features.FeatureDeploymentListener"
           init-method="init" destroy-method="destroy" activation="lazy">
@@ -30,11 +35,13 @@
         </property>
     </bean>
 
-    <service id="featureUrlHandler" interface="org.osgi.service.url.URLStreamHandlerService">
-    	<service-properties>
-            <entry key="url.handler.protocol" value="feature"/>
-        </service-properties>
-        <bean class="org.apache.felix.karaf.deployer.features.FeatureURLHandler"/>
-    </service>
+    <!-- Force a reference to the url handler above from the osgi registry to (try to) make sure
+         the url handler is registered inside the framework.  Else we can run into timing issues
+         where fileinstall will use the featureDeploymentListener before the url can be actually
+         used.  In order to not block the bundle, the blueprint.graceperiod=false flag must be
+         set on the SymbolicName osgi header -->
+    <reference id="featureUrlHandlerRef" interface="org.osgi.service.url.URLStreamHandlerService" filter="url.handler.protocol=feature" />
+
+    <service ref="featureDeploymentListener" auto-export="interfaces" depends-on="featureUrlHandlerRef"/>
 
 </blueprint>
diff --git a/karaf/deployer/spring/pom.xml b/karaf/deployer/spring/pom.xml
index 44adc3f..89dc0ce 100644
--- a/karaf/deployer/spring/pom.xml
+++ b/karaf/deployer/spring/pom.xml
@@ -69,7 +69,9 @@
                 <artifactId>maven-bundle-plugin</artifactId>
                 <configuration>
                     <instructions>
-                        <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+                        <!-- Set the blueprint.graceperiod flag to false to allow the bundle to start
+                             See the blueprint config file -->
+                        <Bundle-SymbolicName>${pom.artifactId};blueprint.graceperiod:=false</Bundle-SymbolicName>
                         <Export-Package>${pom.artifactId}*;version=${project.version}</Export-Package>
                         <Import-Package>!${pom.artifactId}*,*</Import-Package>
                         <Private-Package>org.apache.felix.karaf.deployer.spring</Private-Package>
diff --git a/karaf/deployer/spring/src/main/resources/OSGI-INF/blueprint/spring-deployer.xml b/karaf/deployer/spring/src/main/resources/OSGI-INF/blueprint/spring-deployer.xml
index 558e003..278584f 100644
--- a/karaf/deployer/spring/src/main/resources/OSGI-INF/blueprint/spring-deployer.xml
+++ b/karaf/deployer/spring/src/main/resources/OSGI-INF/blueprint/spring-deployer.xml
@@ -19,10 +19,6 @@
 -->
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
 
-    <service auto-export="interfaces" depends-on="springUrlHandler">
-        <bean class="org.apache.felix.karaf.deployer.spring.SpringDeploymentListener"/>
-    </service>
-
     <service id="springUrlHandler" interface="org.osgi.service.url.URLStreamHandlerService">
     	<service-properties>
             <entry key="url.handler.protocol" value="spring"/>
@@ -30,4 +26,15 @@
         <bean class="org.apache.felix.karaf.deployer.spring.SpringURLHandler"/>
     </service>
 
+    <bean id="springDeploymentListener" class="org.apache.felix.karaf.deployer.spring.SpringDeploymentListener"/>
+
+    <!-- Force a reference to the url handler above from the osgi registry to (try to) make sure
+         the url handler is registered inside the framework.  Else we can run into timing issues
+         where fileinstall will use the featureDeploymentListener before the url can be actually
+         used.  In order to not block the bundle, the blueprint.graceperiod=false flag must be
+         set on the SymbolicName osgi header -->
+    <reference id="springUrlHandlerRef" interface="org.osgi.service.url.URLStreamHandlerService" filter="url.handler.protocol=spring" />
+
+    <service ref="springDeploymentListener" auto-export="interfaces" depends-on="springDeploymentListener" />
+
 </blueprint>