From c8a0a773ba7ad002e41384a12a2848b643fc9253 Mon Sep 17 00:00:00 2001 From: Ciprian Ciubotariu Date: Thu, 19 May 2022 11:01:39 +0300 Subject: [PATCH 1/2] [KARAF-7437] Improve DOSGi exported interface property parsing Match with OSGI R7 specs section 100.2 --- .../apache/karaf/cellar/dosgi/Constants.java | 1 + .../cellar/dosgi/ExportServiceListener.java | 30 ++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/Constants.java b/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/Constants.java index c26b686ec..05cfe65ab 100644 --- a/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/Constants.java +++ b/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/Constants.java @@ -28,4 +28,5 @@ public abstract class Constants { public static final String EXPORTED_INTERFACES = "service.exported.interfaces"; public static final String ENDPOINT_FRAMEWORK_UUID = "frameworkUUID"; + public static final String[] NO_EXPORTED_INTERFACES = {}; } diff --git a/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/ExportServiceListener.java b/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/ExportServiceListener.java index fff299b73..a636a780e 100644 --- a/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/ExportServiceListener.java +++ b/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/ExportServiceListener.java @@ -26,6 +26,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; @@ -111,10 +112,9 @@ public void exportService(ServiceReference serviceReference) { try { Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - String exportedServices = (String) serviceReference.getProperty(Constants.EXPORTED_INTERFACES); - if (exportedServices != null && exportedServices.length() > 0) { - LOGGER.debug("CELLAR DOSGI: registering services {} in the cluster", exportedServices); - String[] interfaces = exportedServices.split(Constants.INTERFACE_SEPARATOR); + String[] interfaces = getExportedInterfaces(serviceReference); + if (interfaces.length > 0) { + LOGGER.debug("CELLAR DOSGI: registering services {} in the cluster", (Object) interfaces); Object service = bundleContext.getService(serviceReference); Set exportedInterfaces = getServiceInterfaces(service, interfaces); @@ -159,10 +159,9 @@ public void unExportService(ServiceReference serviceReference) { ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - String exportedServices = (String) serviceReference.getProperty(Constants.EXPORTED_INTERFACES); - if (exportedServices != null && exportedServices.length() > 0) { - LOGGER.debug("CELLAR DOSGI: un-register service {} from the cluster", exportedServices); - String[] interfaces = exportedServices.split(Constants.INTERFACE_SEPARATOR); + String[] interfaces = getExportedInterfaces(serviceReference); + if (interfaces.length > 0) { + LOGGER.debug("CELLAR DOSGI: un-register service {} from the cluster", (Object) interfaces); Object service = bundleContext.getService(serviceReference); Set exportedInterfaces = getServiceInterfaces(service, interfaces); @@ -188,6 +187,21 @@ public void unExportService(ServiceReference serviceReference) { } } + + private String[] getExportedInterfaces(ServiceReference serviceReference) { + Object property = serviceReference.getProperty(Constants.EXPORTED_INTERFACES); + if (property != null) { + if (property instanceof String) + return ((String) property).split(Constants.INTERFACE_SEPARATOR); + if (property instanceof String[]) + return (String[]) property; + if (property instanceof Collection) + return (String[])((Collection) property).toArray(); + LOGGER.warn("CELLAR DOSGI: Illegal value type on property {} on service reference {}", Constants.EXPORTED_INTERFACES, serviceReference); + } + return Constants.NO_EXPORTED_INTERFACES; + } + /** * Get the interfaces that match the exported service interfaces. * From 4047d443bd16c7be2b78a17dcc2935543ac4544a Mon Sep 17 00:00:00 2001 From: Ciprian Ciubotariu Date: Thu, 2 Feb 2023 23:34:18 +0200 Subject: [PATCH 2/2] [KARAF-7437] Parse DOSGi exported interface of java.lang.Class type The OSGi annotations for DS and CDI expose the service.exported.interfaces typed as Class[]. Account for this value type when parsing this property in Karaf Cellar --- .../cellar/dosgi/ExportServiceListener.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/ExportServiceListener.java b/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/ExportServiceListener.java index a636a780e..01f27be6b 100644 --- a/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/ExportServiceListener.java +++ b/dosgi/src/main/java/org/apache/karaf/cellar/dosgi/ExportServiceListener.java @@ -195,13 +195,31 @@ private String[] getExportedInterfaces(ServiceReference serviceReference) { return ((String) property).split(Constants.INTERFACE_SEPARATOR); if (property instanceof String[]) return (String[]) property; + if (property instanceof Class) + return getClassBinaryNames(serviceReference, property); + if (property instanceof Class[]) + return getClassBinaryNames(serviceReference, (Object[]) property); if (property instanceof Collection) - return (String[])((Collection) property).toArray(); - LOGGER.warn("CELLAR DOSGI: Illegal value type on property {} on service reference {}", Constants.EXPORTED_INTERFACES, serviceReference); + return getClassBinaryNames(serviceReference, ((Collection) property).toArray()); + LOGGER.warn("CELLAR DOSGI: Illegal value type of property {} on service reference {}", Constants.EXPORTED_INTERFACES, serviceReference); } return Constants.NO_EXPORTED_INTERFACES; } + private String[] getClassBinaryNames(ServiceReference serviceReference, Object... classes) { + String[] names = new String[classes.length]; + for (int i = 0; i < classes.length; ++i) { + Object o = classes[i]; + if (o instanceof String) + names[i] = (String) o; + else if (o instanceof Class) + names[i] = ((Class)o).getName(); + else + LOGGER.warn("CELLAR DOSGI: Illegal value type of property {} on service reference {}", Constants.EXPORTED_INTERFACES, serviceReference); + } + return names; + } + /** * Get the interfaces that match the exported service interfaces. *