This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-launcher.git


The following commit(s) were added to refs/heads/master by this push:
     new f7804da  SLING-12828 - Register the Feature service as soon as the 
org.apache.sling.feature bundle is active (#47)
f7804da is described below

commit f7804dafc22843b926a65e5504e12bf5b87825a9
Author: Robert Munteanu <[email protected]>
AuthorDate: Mon Jun 16 11:08:39 2025 +0200

    SLING-12828 - Register the Feature service as soon as the 
org.apache.sling.feature bundle is active (#47)
    
    Use a BundleListener to register the Feature service as soon as possible.
---
 .../launcher/impl/launchers/AbstractRunner.java    | 119 +++++++++++----------
 1 file changed, 65 insertions(+), 54 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
 
b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
index b80b906..c2aa2b8 100644
--- 
a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
+++ 
b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
@@ -46,7 +46,9 @@ import java.util.function.Supplier;
 
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
 import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
 import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.PrototypeServiceFactory;
@@ -251,6 +253,19 @@ public abstract class AbstractRunner implements 
Callable<Integer> {
             this.installerTracker.open();
         }
 
+        if (this.featureSupplier != null) {
+            framework.getBundleContext().addBundleListener(new 
BundleListener() {
+                @Override
+                public void bundleChanged(BundleEvent event) {
+                    Bundle bundle = event.getBundle();
+                    if 
(bundle.getSymbolicName().equals("org.apache.sling.feature")
+                            && event.getType() == BundleEvent.STARTED) {
+                        registerFeatureService(bundle);
+                    }
+                }
+            });
+        }
+
         this.install(framework, bundlesMap);
     }
 
@@ -372,63 +387,59 @@ public abstract class AbstractRunner implements 
Callable<Integer> {
         }
     }
 
-    protected void finishStartup(final Framework framework) {
-        Bundle featureBundle = null;
-        for (final Bundle bundle : framework.getBundleContext().getBundles()) {
-            if (featureSupplier != null && 
"org.apache.sling.feature".equals(bundle.getSymbolicName())) {
-                featureBundle = bundle;
-            }
-        }
-        if (featureBundle != null) {
-            final Bundle bundle = featureBundle;
-            // the feature is registered as a prototype to give each client a 
copy as feature models are mutable
-            final Dictionary<String, Object> properties = new Hashtable<>();
-            properties.put("name", "org.apache.sling.feature.launcher");
-            featureBundle
-                    .getBundleContext()
-                    .registerService(
-                            new String[] {"org.apache.sling.feature.Feature"},
-                            new PrototypeServiceFactory<Object>() {
-
-                                @Override
-                                public Object getService(
-                                        final Bundle client, final 
ServiceRegistration<Object> registration) {
-                                    final ClassLoader cl =
-                                            
bundle.adapt(BundleWiring.class).getClassLoader();
-                                    final ClassLoader oldTCCL =
-                                            
Thread.currentThread().getContextClassLoader();
-                                    
Thread.currentThread().setContextClassLoader(cl);
-                                    try {
-                                        final Class<?> readerClass =
-                                                
cl.loadClass("org.apache.sling.feature.io.json.FeatureJSONReader");
-                                        final Method readMethod = 
readerClass.getDeclaredMethod(
-                                                "read", java.io.Reader.class, 
String.class);
-                                        try (final StringReader reader = new 
StringReader(featureSupplier.get())) {
-                                            return readMethod.invoke(null, 
reader, null);
-                                        }
-                                    } catch (ClassNotFoundException
-                                            | NoSuchMethodException
-                                            | SecurityException
-                                            | IllegalArgumentException
-                                            | IllegalAccessException
-                                            | InvocationTargetException e) {
-                                        // ignore
-                                    } finally {
-                                        
Thread.currentThread().setContextClassLoader(oldTCCL);
+    protected void finishStartup(final Framework framework) {}
+
+    protected void registerFeatureService(Bundle featureBundle) {
+
+        logger.debug("Registering feature service");
+
+        // the feature is registered as a prototype to give each client a copy 
as feature models are mutable
+        final Dictionary<String, Object> properties = new Hashtable<>();
+        properties.put("name", "org.apache.sling.feature.launcher");
+        featureBundle
+                .getBundleContext()
+                .registerService(
+                        new String[] {"org.apache.sling.feature.Feature"},
+                        new PrototypeServiceFactory<Object>() {
+
+                            @Override
+                            public Object getService(
+                                    final Bundle client, final 
ServiceRegistration<Object> registration) {
+                                final ClassLoader cl =
+                                        
featureBundle.adapt(BundleWiring.class).getClassLoader();
+                                final ClassLoader oldTCCL =
+                                        
Thread.currentThread().getContextClassLoader();
+                                
Thread.currentThread().setContextClassLoader(cl);
+                                try {
+                                    final Class<?> readerClass =
+                                            
cl.loadClass("org.apache.sling.feature.io.json.FeatureJSONReader");
+                                    final Method readMethod =
+                                            
readerClass.getDeclaredMethod("read", java.io.Reader.class, String.class);
+                                    try (final StringReader reader = new 
StringReader(featureSupplier.get())) {
+                                        return readMethod.invoke(null, reader, 
null);
                                     }
-                                    return null;
+                                } catch (ClassNotFoundException
+                                        | NoSuchMethodException
+                                        | SecurityException
+                                        | IllegalArgumentException
+                                        | IllegalAccessException
+                                        | InvocationTargetException e) {
+                                    // ignore
+                                } finally {
+                                    
Thread.currentThread().setContextClassLoader(oldTCCL);
                                 }
+                                return null;
+                            }
 
-                                @Override
-                                public void ungetService(
-                                        final Bundle client,
-                                        final ServiceRegistration<Object> 
registration,
-                                        final Object service) {
-                                    // nothing to do
-                                }
-                            },
-                            properties);
-        }
+                            @Override
+                            public void ungetService(
+                                    final Bundle client,
+                                    final ServiceRegistration<Object> 
registration,
+                                    final Object service) {
+                                // nothing to do
+                            }
+                        },
+                        properties);
     }
 
     /**

Reply via email to