Repository: incubator-tamaya Updated Branches: refs/heads/java8 23123bb72 -> 6010c606c
TAMAYA-274: Fixed basic service loading in OSGI. Added missing requirements. Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/6010c606 Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/6010c606 Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/6010c606 Branch: refs/heads/java8 Commit: 6010c606cdccd0121c064b7ba6a32a7ed71c9ab5 Parents: 23123bb Author: anatole <anat...@apache.org> Authored: Sun Sep 17 01:51:20 2017 +0200 Committer: anatole <anat...@apache.org> Committed: Sun Sep 17 01:51:20 2017 +0200 ---------------------------------------------------------------------- .../tamaya/core/internal/OSGIServiceLoader.java | 96 +++++++++++++------- .../examples/minimal/TestConfigProvider.java | 49 ++++++++++ 2 files changed, 110 insertions(+), 35 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/6010c606/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java index 4c12df9..0854b0d 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java @@ -48,6 +48,13 @@ public class OSGIServiceLoader implements BundleListener { public OSGIServiceLoader(BundleContext context){ this.context = Objects.requireNonNull(context); + // Check for matching bundles already installed... + for(Bundle bundle:context.getBundles()){ + switch(bundle.getState()){ + case Bundle.ACTIVE: + checkAndLoadBundle(bundle); + } + } } public BundleContext getBundleContext(){ @@ -62,38 +69,46 @@ public class OSGIServiceLoader implements BundleListener { @Override public void bundleChanged(BundleEvent bundleEvent) { - // Parse and create metadata on STARTING - if (bundleEvent.getType() == BundleEvent.STARTING) { + // Parse and create metadata when installed + if (bundleEvent.getType() == BundleEvent.STARTED) { Bundle bundle = bundleEvent.getBundle(); - if (bundle.getEntry(META_INF_SERVICES) == null) { - return; - } - synchronized (resourceBundles){ - resourceBundles.add(bundle); - log.info("Registered ServiceLoader bundle: " + bundle.getSymbolicName()); - } - Enumeration<String> entryPaths = bundle.getEntryPaths("META-INF/services/"); - while (entryPaths.hasMoreElements()) { - String entryPath = entryPaths.nextElement(); - if(!entryPath.endsWith("/")) { - processEntryPath(bundle, entryPath); - } - } - } else if (bundleEvent.getType() == BundleEvent.STOPPING) { + checkAndLoadBundle(bundle); + } else if (bundleEvent.getType() == BundleEvent.STOPPED) { Bundle bundle = bundleEvent.getBundle(); - if (bundle.getEntry(META_INF_SERVICES) == null) { - return; - } - synchronized (resourceBundles) { - resourceBundles.remove(bundle); - log.finest("Unregistered ServiceLoader bundle: " + bundle.getSymbolicName()); + checkAndUnloadBundle(bundle); + } + } + + private void checkAndUnloadBundle(Bundle bundle) { + if (bundle.getEntry(META_INF_SERVICES) == null) { + return; + } + synchronized (resourceBundles) { + resourceBundles.remove(bundle); + log.fine("Unregistered ServiceLoader bundle: " + bundle.getSymbolicName()); + } + Enumeration<String> entryPaths = bundle.getEntryPaths("META-INF/services/"); + while (entryPaths.hasMoreElements()) { + String entryPath = entryPaths.nextElement(); + if(!entryPath.endsWith("/")) { + removeEntryPath(bundle, entryPath); } - Enumeration<String> entryPaths = bundle.getEntryPaths("META-INF/services/"); - while (entryPaths.hasMoreElements()) { - String entryPath = entryPaths.nextElement(); - if(!entryPath.endsWith("/")) { - removeEntryPath(bundle, entryPath); - } + } + } + + private void checkAndLoadBundle(Bundle bundle) { + if (bundle.getEntry(META_INF_SERVICES) == null) { + return; + } + synchronized (resourceBundles){ + resourceBundles.add(bundle); + log.info("Registered ServiceLoader bundle: " + bundle.getSymbolicName()); + } + Enumeration<String> entryPaths = bundle.getEntryPaths("META-INF/services/"); + while (entryPaths.hasMoreElements()) { + String entryPath = entryPaths.nextElement(); + if(!entryPath.endsWith("/")) { + processEntryPath(bundle, entryPath); } } } @@ -106,10 +121,9 @@ public class OSGIServiceLoader implements BundleListener { return; } Class<?> serviceClass = bundle.loadClass(serviceName); - log.info("Loaded Tamaya service class: " + serviceClass.getName() +"("+serviceName+")"); URL child = bundle.getEntry(entryPath); InputStream inStream = child.openStream(); - + log.info("Loading Services " + serviceClass.getName() +" from bundle...: " + bundle.getSymbolicName()); BufferedReader br = new BufferedReader(new InputStreamReader(inStream, "UTF-8")); String implClassName = br.readLine(); while (implClassName != null){ @@ -124,12 +138,14 @@ public class OSGIServiceLoader implements BundleListener { if (implClassName.length() > 0) { try { // Load the service class + log.fine("Loading Class " + implClassName +" from bundle...: " + bundle.getSymbolicName()); Class<?> implClass = bundle.loadClass(implClassName); if (!serviceClass.isAssignableFrom(implClass)) { log.warning("Configured service: " + implClassName + " is not assignble to " + serviceClass.getName()); continue; } + log.info("Loaded Service Factory ("+serviceName+"): " + implClassName); // Provide service properties Hashtable<String, String> props = new Hashtable<>(); props.put(Constants.VERSION_ATTRIBUTE, bundle.getVersion().toString()); @@ -142,12 +158,16 @@ public class OSGIServiceLoader implements BundleListener { // Register the service factory on behalf of the intercepted bundle JDKUtilServiceFactory factory = new JDKUtilServiceFactory(implClass); BundleContext bundleContext = bundle.getBundleContext(); - log.info("Registering Tamaya service class: " + serviceClass.getName() +"("+serviceName+")"); bundleContext.registerService(serviceName, factory, props); + log.info("Registered Tamaya service class: " + implClassName +"("+serviceName+")"); } catch(Exception e){ log.log(Level.SEVERE, - "Failed to load service class using ServiceLoader logic: " + implClassName, e); + "Failed to load service: " + implClassName, e); + } + catch(NoClassDefFoundError err){ + log.log(Level.SEVERE, + "Failed to load service: " + implClassName, err); } } implClassName = br.readLine(); @@ -186,6 +206,7 @@ public class OSGIServiceLoader implements BundleListener { } implClassName = implClassName.trim(); if (implClassName.length() > 0) { + log.fine("Unloading Service ("+serviceName+"): " + implClassName); try { // Load the service class Class<?> implClass = bundle.loadClass(implClassName); @@ -201,7 +222,11 @@ public class OSGIServiceLoader implements BundleListener { } catch(Exception e){ log.log(Level.SEVERE, - "Failed to unload service class using ServiceLoader logic: " + implClassName, e); + "Failed to unload service: " + implClassName, e); + } + catch(NoClassDefFoundError err){ + log.log(Level.SEVERE, + "Failed to unload service: " + implClassName, err); } } implClassName = br.readLine(); @@ -230,11 +255,12 @@ public class OSGIServiceLoader implements BundleListener { @Override public Object getService(Bundle bundle, ServiceRegistration registration) { try { + log.fine("Creating Service...:" + serviceClass.getName()); return serviceClass.newInstance(); } catch (Exception ex) { ex.printStackTrace(); - throw new IllegalStateException("Cannot create service: " + serviceClass.getName(), ex); + throw new IllegalStateException("Failed to create service: " + serviceClass.getName(), ex); } } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/6010c606/examples/01-minimal/src/main/java/org/apache/tamaya/examples/minimal/TestConfigProvider.java ---------------------------------------------------------------------- diff --git a/examples/01-minimal/src/main/java/org/apache/tamaya/examples/minimal/TestConfigProvider.java b/examples/01-minimal/src/main/java/org/apache/tamaya/examples/minimal/TestConfigProvider.java new file mode 100644 index 0000000..f9fb853 --- /dev/null +++ b/examples/01-minimal/src/main/java/org/apache/tamaya/examples/minimal/TestConfigProvider.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tamaya.examples.minimal; + +import org.apache.tamaya.Configuration; +import org.apache.tamaya.core.internal.DefaultConfigurationProvider; + +/** + * Configuration provider that allows to set and reset a configuration + * different per thread. + */ +public class TestConfigProvider extends DefaultConfigurationProvider{ + + private ThreadLocal<Configuration> threadedConfig = new ThreadLocal<>(); + + @Override + public Configuration getConfiguration() { + Configuration config = threadedConfig.get(); + if(config!=null){ + return config; + } + return super.getConfiguration(); + } + + @Override + public void setConfiguration(Configuration config) { + if(config==null){ + threadedConfig.remove(); + }else { + threadedConfig.set(config); + } + } +}