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

tjwatson pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git


The following commit(s) were added to refs/heads/master by this push:
     new 8ee5835206 Replace use of PackageAdmin with FrameworkWiring
     new 99d55010de Merge pull request #144 from tjwatson/scrRemovePackageAdmin
8ee5835206 is described below

commit 8ee58352065c94620af3e14dce555c78d8498c52
Author: Thomas Watson <[email protected]>
AuthorDate: Fri Apr 22 14:29:07 2022 -0500

    Replace use of PackageAdmin with FrameworkWiring
---
 scr/bnd.bnd                                        |   3 -
 .../java/org/apache/felix/scr/impl/Activator.java  |  14 +-
 .../scr/impl/config/ScrConfigurationImpl.java      |   8 +-
 .../felix/scr/impl/config/ScrManagedService.java   |   2 +-
 .../felix/scr/impl/inject/internal/ClassUtils.java | 166 ++++++++++++---------
 5 files changed, 104 insertions(+), 89 deletions(-)

diff --git a/scr/bnd.bnd b/scr/bnd.bnd
index 6b1f5e1388..72a5c1ed6c 100644
--- a/scr/bnd.bnd
+++ b/scr/bnd.bnd
@@ -24,14 +24,11 @@ Private-Package: org.apache.felix.scr.impl.*
 # Configuration Admin is optional and dynamic, but allow eager wiring by 
importing it
 # LogService is optional but if present the R7.0 version 1.4 is sufficient.
 # Metatype import is optional and dynamic, but allow eager wiring by importing 
it
-# PackageAdmin is used to find reference types if the component's bundle does 
not import it.
-#    R4.0 version 1.2 is sufficient.
 # optional import for Gogo annotations 
 Import-Package: \
  org.osgi.service.cm;version="[1.6,2)";resolution:=optional, \
  org.osgi.service.log;version="[1.4,2)";resolution:=optional, \
  org.osgi.service.metatype;version="[1.2,2)";resolution:=optional, \
- org.osgi.service.packageadmin;version="[1.2,2)";resolution:=optional,\
  org.apache.felix.service.command;resolution:=optional, \
  *
 
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/Activator.java 
b/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
index 05a5d8a718..0cfde4ea08 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
@@ -61,6 +61,7 @@ import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.framework.wiring.BundleWire;
 import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.framework.wiring.FrameworkWiring;
 import org.osgi.namespace.extender.ExtenderNamespace;
 import org.osgi.service.component.ComponentConstants;
 import org.osgi.service.component.runtime.ServiceComponentRuntime;
@@ -121,8 +122,7 @@ public class Activator extends AbstractExtender
         m_context = context;
         m_bundle = context.getBundle();
         m_trueCondition = findTrueCondition(context);
-        // set bundle context for PackageAdmin tracker
-        ClassUtils.setBundleContext( context );
+        
ClassUtils.setFrameworkWiring(context.getBundle(Constants.SYSTEM_BUNDLE_LOCATION).adapt(FrameworkWiring.class));
         // get the configuration
         m_configuration.start( m_context ); //this will call restart, which 
calls super.start.
     }
@@ -155,7 +155,7 @@ public class Activator extends AbstractExtender
         }
     }
 
-    public void restart(boolean globalExtender)
+    public void restart(boolean globalExtender, boolean initialStart)
     {
         m_componentMetadataStore = load(m_context, logger,
             m_configuration.cacheMetadata());
@@ -168,14 +168,14 @@ public class Activator extends AbstractExtender
         {
             m_globalContext = m_context;
         }
-        if ( ClassUtils.m_packageAdmin != null )
+        if (!initialStart)
         {
             logger.log(Level.INFO,
                 "Stopping to restart with new globalExtender setting: {0}", 
null,
                 globalExtender);
 
-            //this really is a restart, not the initial start
-            // the initial start where m_globalContext is null should skip 
this as m_packageAdmin should not yet be set.
+            // this really is a restart, not the initial start;
+            // first stop the extender
             try
             {
                 super.stop( context );
@@ -417,7 +417,7 @@ public class Activator extends AbstractExtender
             m_componentActor.terminate();
             m_componentActor = null;
         }
-        ClassUtils.close();
+        ClassUtils.setFrameworkWiring(null);
     }
 
     //---------- Component Management -----------------------------------------
diff --git 
a/scr/src/main/java/org/apache/felix/scr/impl/config/ScrConfigurationImpl.java 
b/scr/src/main/java/org/apache/felix/scr/impl/config/ScrConfigurationImpl.java
index 9a0417ab6a..2e7aadf377 100644
--- 
a/scr/src/main/java/org/apache/felix/scr/impl/config/ScrConfigurationImpl.java
+++ 
b/scr/src/main/java/org/apache/felix/scr/impl/config/ScrConfigurationImpl.java
@@ -123,7 +123,7 @@ public class ScrConfigurationImpl implements 
ScrConfiguration
         // overriden by configuration admin later.
         // Note that if the managed service is registered first then it is 
random which will win since
         // configuration may be delivered asynchronously
-        configure( null, false );
+        configure( null, true );
 
         managedServiceRef = 
bundleContext.registerService("org.osgi.service.cm.ManagedService", new 
ScrManagedServiceServiceFactory(this),
                 msProps);
@@ -161,7 +161,7 @@ public class ScrConfigurationImpl implements 
ScrConfiguration
     }
 
     // Called from the ScrManagedService.updated method to reconfigure
-    void configure( Dictionary<String, ?> config, boolean fromConfig )
+    void configure( Dictionary<String, ?> config, boolean initialStart )
     {
         Boolean newGlobalExtender;
         Boolean oldGlobalExtender;
@@ -169,7 +169,7 @@ public class ScrConfigurationImpl implements 
ScrConfiguration
         {
             if ( config == null )
             {
-                if (!fromConfig)
+                if (initialStart)
                 {
                     if (this.bundleContext == null)
                     {
@@ -231,7 +231,7 @@ public class ScrConfigurationImpl implements 
ScrConfiguration
         activator.setLogger();
         if ( newGlobalExtender != oldGlobalExtender )
         {
-            activator.restart( newGlobalExtender );
+            activator.restart( newGlobalExtender, initialStart );
         }
     }
 
diff --git 
a/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedService.java 
b/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedService.java
index 55ab0d3db2..dbaded4263 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedService.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ScrManagedService.java
@@ -48,6 +48,6 @@ public class ScrManagedService implements ManagedService
     @Override
     public void updated(final Dictionary<String, ?> properties) throws 
ConfigurationException
     {
-        this.scrConfiguration.configure(properties, true);
+        this.scrConfiguration.configure(properties, false);
     }
 }
diff --git 
a/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ClassUtils.java 
b/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ClassUtils.java
index 04b7a36109..870d4cc704 100755
--- 
a/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ClassUtils.java
+++ 
b/scr/src/main/java/org/apache/felix/scr/impl/inject/internal/ClassUtils.java
@@ -19,18 +19,28 @@
 package org.apache.felix.scr.impl.inject.internal;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
 import org.apache.felix.scr.impl.logger.ComponentLogger;
 import org.apache.felix.scr.impl.logger.InternalLogger.Level;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.framework.wiring.FrameworkWiring;
+import org.osgi.resource.Namespace;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.component.ComponentServiceObjects;
-import org.osgi.service.packageadmin.ExportedPackage;
-import org.osgi.service.packageadmin.PackageAdmin;
 import org.osgi.util.tracker.ServiceTracker;
 
 
@@ -40,10 +50,6 @@ import org.osgi.util.tracker.ServiceTracker;
 @SuppressWarnings("deprecation")
 public class ClassUtils
 {
-
-    // name of the PackageAdmin class (this is a string to not create a 
reference to the class)
-    private static final String PACKAGEADMIN_CLASS = 
"org.osgi.service.packageadmin.PackageAdmin";
-
     private static final Class<?> OBJECT_CLASS = Object.class;
 
     public static final Class<?> SERVICE_REFERENCE_CLASS = 
ServiceReference.class;
@@ -66,11 +72,7 @@ public class ClassUtils
     public static final String FORMATTER_LOGGER_CLASS = 
"org.osgi.service.log.FormatterLogger";
     public static final String LOGGER_FACTORY_CLASS = 
"org.osgi.service.log.LoggerFactory";
 
-
-    // this bundle's context
-    private static BundleContext m_context;
-    // the package admin service (see BindMethod.getParameterClass)
-    public static volatile ServiceTracker<?, ?> m_packageAdmin;
+    public static FrameworkWiring m_fwkWiring;
 
     /**
      * Returns the class object representing the class of the field reference
@@ -93,14 +95,14 @@ public class ClassUtils
         {
             logger.log(
                 Level.DEBUG,
-                "getReferenceClass: Looking for interface class {0} through 
loader of {1}", null,
+                "getClassFromComponentClassLoader: Looking for interface class 
{0} through loader of {1}", null,
                     className, componentClass.getName() );
         }
 
         try
         {
             // need the class loader of the target class, which may be the
-            // system classloader, which case getClassLoader may retur null
+            // system classloader, which case getClassLoader may return null
             ClassLoader loader = componentClass.getClassLoader();
             if ( loader == null )
             {
@@ -111,7 +113,7 @@ public class ClassUtils
             if (logger.isLogEnabled(Level.DEBUG))
             {
                 logger.log(Level.DEBUG,
-                    "getParameterClass: Found class {0}", null, 
referenceClass.getName() );
+                    "getClassFromComponentClassLoader: Found class {0}", null, 
referenceClass.getName() );
             }
             return referenceClass;
         }
@@ -124,54 +126,37 @@ public class ClassUtils
         if (logger.isLogEnabled(Level.DEBUG))
         {
             logger.log(Level.DEBUG,
-                "getParameterClass: Not found through component class, using 
PackageAdmin service", null );
+                "getClassFromComponentClassLoader: Not found through component 
class, using FrameworkWiring", null );
         }
 
-        // try to load the class with the help of the PackageAdmin service
-        PackageAdmin pa = ( PackageAdmin ) getPackageAdmin();
-        if ( pa != null )
+        // try to load the class with the help of the FrameworkWiring
+        Bundle exportingHost = getExporter(className, logger);
+        if ( exportingHost != null )
         {
-            final String referenceClassPackage = className.substring( 0, 
className
-                .lastIndexOf( '.' ) );
-            ExportedPackage[] pkg = pa.getExportedPackages( 
referenceClassPackage );
-            if ( pkg != null )
+            try
             {
-                for ( int i = 0; i < pkg.length; i++ )
+                if (logger.isLogEnabled(Level.DEBUG))
                 {
-                    try
-                    {
-                        if (logger.isLogEnabled(Level.DEBUG))
-                        {
-                            logger.log(
-                                Level.DEBUG,
-                                "getParameterClass: Checking Bundle {0}/{1}",
-                                null, 
pkg[i].getExportingBundle().getSymbolicName(), 
pkg[i].getExportingBundle().getBundleId() );
-                        }
+                    logger.log(Level.DEBUG, "getClassFromComponentClassLoader: 
Checking Bundle {0}/{1}", null,
+                            exportingHost.getSymbolicName(), 
exportingHost.getBundleId());
+                }
 
-                        Class<?> referenceClass = 
pkg[i].getExportingBundle().loadClass( className );
-                        if (logger.isLogEnabled(Level.DEBUG))
-                        {
-                            logger.log(Level.DEBUG,
-                                    "getParameterClass: Found class {0}", 
null,referenceClass.getName() );
-                        }
-                        return referenceClass;
-                    }
-                    catch ( ClassNotFoundException cnfe )
-                    {
-                        // exported package does not provide the interface !!!!
-                    }
+                Class<?> referenceClass = exportingHost.loadClass(className);
+                if (logger.isLogEnabled(Level.DEBUG))
+                {
+                    logger.log(Level.DEBUG, "getClassFromComponentClassLoader: 
Found class {0}", null,
+                            referenceClass.getName());
                 }
-            }
-            else if (logger.isLogEnabled(Level.DEBUG))
+                return referenceClass;
+            } catch (ClassNotFoundException cnfe)
             {
-                logger.log(Level.DEBUG,
-                    "getParameterClass: No bundles exporting package {0} 
found", null, referenceClassPackage );
+                // exported package does not provide the interface !!!!
             }
         }
         else if (logger.isLogEnabled(Level.DEBUG))
         {
             logger.log(Level.DEBUG,
-                "getParameterClass: PackageAdmin service not available, cannot 
find class", null );
+                    "getClassFromComponentClassLoader: No bundles exporting 
package {0} found", null, className );
         }
 
         // class cannot be found, neither through the component nor from an
@@ -179,45 +164,78 @@ public class ClassUtils
         if (logger.isLogEnabled(Level.DEBUG))
         {
             logger.log(Level.DEBUG,
-                "getParameterClass: No class found, falling back to class 
Object", null );
+                "getClassFromComponentClassLoader: No class found, falling 
back to class Object", null );
         }
         return OBJECT_CLASS;
     }
 
-    public static void setBundleContext( BundleContext bundleContext )
-    {
-        ClassUtils.m_context = bundleContext;
-    }
-
-    public static Object getPackageAdmin()
-    {
-        if (m_packageAdmin == null)
+    private static Bundle getExporter(String className, ComponentLogger 
logger) {
+        FrameworkWiring currentFwkWiring = m_fwkWiring;
+        if (currentFwkWiring != null)
         {
-            synchronized (ClassUtils.class)
+            String referenceClassPackage = className.substring(0, 
className.lastIndexOf( '.' ) );
+            Collection<BundleCapability> providers = 
currentFwkWiring.findProviders(getRequirement(referenceClassPackage));
+            for (BundleCapability provider : providers)
             {
-                if (m_packageAdmin == null)
+                BundleWiring wiring = provider.getRevision().getWiring();
+                if (wiring != null)
                 {
-                    m_packageAdmin = new ServiceTracker<>(m_context, 
PACKAGEADMIN_CLASS,
-                        null);
-                    m_packageAdmin.open();
+                    if ((provider.getRevision().getTypes() & 
BundleRevision.TYPE_FRAGMENT) != 0) {
+                        // for fragments just use the first host bundle
+                        List<BundleWire> hostWires = 
wiring.getRequiredWires(HostNamespace.HOST_NAMESPACE);
+                        if (hostWires != null && !hostWires.isEmpty()) {
+                            return hostWires.get(0).getProvider().getBundle();
+                        }
+                    }
+                    else
+                    {
+                        return wiring.getBundle();
+                    }
                 }
             }
         }
+        else if (logger.isLogEnabled(Level.DEBUG))
+        {
+            logger.log(Level.DEBUG,
+                "getClassFromComponentClassLoader: FrameworkWiring not 
available, cannot find class", null );
+        }
+        return null;
+       }
 
-        return m_packageAdmin.getService();
-    }
-
-    public static void close()
+       private static Requirement getRequirement(final String pkgName)
     {
-        // close the PackageAdmin tracker now
-        if (m_packageAdmin != null)
+        return new Requirement()
         {
-            m_packageAdmin.close();
-            m_packageAdmin = null;
-        }
+            @Override
+            public Resource getResource()
+            {
+                return null;
+            }
+
+            @Override
+            public String getNamespace()
+            {
+                return PackageNamespace.PACKAGE_NAMESPACE;
+            }
+
+            @Override
+            public Map<String, String> getDirectives()
+            {
+                String filter = "(" + PackageNamespace.PACKAGE_NAMESPACE + "=" 
+ pkgName + ")";
+                return 
Collections.singletonMap(Namespace.REQUIREMENT_FILTER_DIRECTIVE, filter);
+            }
 
-        // remove the reference to the component context
-        m_context = null;
+            @Override
+            public Map<String, Object> getAttributes()
+            {
+                return Collections.emptyMap();
+            }
+        };
+    }
+
+    public static void setFrameworkWiring( FrameworkWiring fwkWiring )
+    {
+        ClassUtils.m_fwkWiring = fwkWiring;
     }
 
     /**

Reply via email to