X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.init%2Fsrc%2Forg%2Fargeo%2Finit%2Fosgi%2FOsgiRuntimeContext.java;h=b7079f60e87fa7611bbf936bd3603fd78a52e3d7;hb=6bfcb81dd21d8fdd9094610c00f5f8ad9c6a36a7;hp=c35046b20aec4f0576f272a6e1b4bd11a013418f;hpb=e90495f6155a3996fa8b7009a5f7dc7f33a2ecb8;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.init/src/org/argeo/init/osgi/OsgiRuntimeContext.java b/org.argeo.init/src/org/argeo/init/osgi/OsgiRuntimeContext.java index c35046b20..b7079f60e 100644 --- a/org.argeo.init/src/org/argeo/init/osgi/OsgiRuntimeContext.java +++ b/org.argeo.init/src/org/argeo/init/osgi/OsgiRuntimeContext.java @@ -1,11 +1,12 @@ package org.argeo.init.osgi; import java.io.Serializable; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; import java.lang.System.LoggerFinder; import java.util.Collections; import java.util.Hashtable; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.ServiceLoader; import java.util.concurrent.Flow; @@ -22,9 +23,16 @@ import org.osgi.framework.launch.FrameworkFactory; /** An OSGi runtime context. */ public class OsgiRuntimeContext implements RuntimeContext, AutoCloseable { + private final static Logger logger = System.getLogger(OsgiRuntimeContext.class.getName()); + + private final static long STOP_FOR_UPDATE_TIMEOUT = 60 * 1000; + private final static long CLOSE_TIMEOUT = 60 * 1000; + + private final static String SYMBOLIC_NAME_FELIX_SCR = "org.apache.felix.scr"; + private Map config; private Framework framework; - private OsgiBoot osgiBoot; +// private OsgiBoot osgiBoot; /** * Constructor to use when the runtime context will create the OSGi @@ -44,11 +52,17 @@ public class OsgiRuntimeContext implements RuntimeContext, AutoCloseable { @Override public void run() { - ServiceLoader sl = ServiceLoader.load(FrameworkFactory.class); - Optional opt = sl.findFirst(); - if (opt.isEmpty()) - throw new IllegalStateException("Cannot find OSGi framework"); - framework = opt.get().newFramework(config); + if (framework != null && framework.getState() >= Framework.STARTING) + throw new IllegalStateException("OSGi framework is already started"); + + if (framework == null) { + ServiceLoader sl = ServiceLoader.load(FrameworkFactory.class); + Optional opt = sl.findFirst(); + if (opt.isEmpty()) + throw new IllegalStateException("Cannot find OSGi framework"); + framework = opt.get().newFramework(config); + } + try { framework.start(); BundleContext bundleContext = framework.getBundleContext(); @@ -58,7 +72,7 @@ public class OsgiRuntimeContext implements RuntimeContext, AutoCloseable { } } - public void start(BundleContext bundleContext) { + protected void start(BundleContext bundleContext) { // preferences // SystemRootPreferences systemRootPreferences = ThinPreferencesFactory.getInstance().getSystemRootPreferences(); // bundleContext.registerService(AbstractPreferences.class, systemRootPreferences, new Hashtable<>()); @@ -80,17 +94,38 @@ public class OsgiRuntimeContext implements RuntimeContext, AutoCloseable { bundleContext.registerService(Flow.Publisher.class, supplier.get(), new Hashtable<>(Collections.singletonMap(Constants.SERVICE_PID, "argeo.logging.publisher"))); } - osgiBoot = new OsgiBoot(bundleContext); + OsgiBoot osgiBoot = new OsgiBoot(bundleContext); osgiBoot.bootstrap(config); - } public void update() { - Objects.requireNonNull(osgiBoot); - osgiBoot.update(); + stop(); + try { + waitForStop(STOP_FOR_UPDATE_TIMEOUT); + } catch (InterruptedException e) { + logger.log(Level.TRACE, "Wait for stop interrupted", e); + } + run(); + + // TODO Optimise with OSGi mechanisms (e.g. framework.update()) +// if (osgiBoot != null) { +// Objects.requireNonNull(osgiBoot); +// osgiBoot.update(); +// } } - public void stop(BundleContext bundleContext) { + protected void stop() { + if (framework == null) + return; + stop(framework.getBundleContext()); + try { + framework.stop(); + } catch (BundleException e) { + throw new IllegalStateException("Cannot stop OSGi framework", e); + } + } + + protected void stop(BundleContext bundleContext) { // if (loggingConfigurationSr != null) // try { // loggingConfigurationSr.unregister(); @@ -108,26 +143,41 @@ public class OsgiRuntimeContext implements RuntimeContext, AutoCloseable { @Override public void waitForStop(long timeout) throws InterruptedException { if (framework == null) - throw new IllegalStateException("Framework is not initialised"); + return; framework.waitForStop(timeout); } public void close() throws Exception { + if (framework == null) + return; +// Bundle scrBundle = osgiBoot.getBundlesBySymbolicName().get(); +// if (scrBundle != null && scrBundle.getState() > Bundle.RESOLVED) { +// scrBundle.stop(); +// while (!(scrBundle.getState() <= Bundle.RESOLVED)) { +// Thread.sleep(500); +// } +// Thread.sleep(1000); +// } + // TODO make shutdown of dynamic service more robust - Bundle scrBundle = osgiBoot.getBundlesBySymbolicName().get("org.apache.felix.scr"); - if (scrBundle != null) { - scrBundle.stop(); - while (!(scrBundle.getState() <= Bundle.RESOLVED)) { - Thread.sleep(500); + for (Bundle scrBundle : framework.getBundleContext().getBundles()) { + if (scrBundle.getSymbolicName().equals(SYMBOLIC_NAME_FELIX_SCR)) { + if (scrBundle.getState() > Bundle.RESOLVED) { + scrBundle.stop(); + while (!(scrBundle.getState() <= Bundle.RESOLVED)) { + Thread.sleep(100); + } + Thread.sleep(100); + } } - Thread.sleep(1000); } - stop(framework.getBundleContext()); - if (framework != null) - framework.stop(); - + stop(); + waitForStop(CLOSE_TIMEOUT); + framework = null; +// osgiBoot = null; + config.clear(); } public Framework getFramework() {