package org.argeo.api.a2;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import java.util.Collections;
import java.util.SortedMap;
import java.util.TreeMap;
-import org.argeo.init.osgi.OsgiBootUtils;
import org.osgi.framework.Version;
/**
* compatibility.
*/
public class A2Branch implements Comparable<A2Branch> {
+ private final static Logger logger = System.getLogger(A2Branch.class.getName());
+
private final A2Component component;
private final String id;
A2Module getOrAddModule(Version version, Object locator) {
if (modules.containsKey(version)) {
A2Module res = modules.get(version);
- if (OsgiBootUtils.isDebug() && !res.getLocator().equals(locator)) {
- OsgiBootUtils.debug("Inconsistent locator " + locator + " (registered: " + res.getLocator() + ")");
+ if (!res.getLocator().equals(locator)) {
+ logger.log(Level.TRACE,
+ () -> "Inconsistent locator " + locator + " (registered: " + res.getLocator() + ")");
}
return res;
} else
return Os.local().toString() + "/" + Arch.local().toString();
}
+ /** Well-known operating systems. */
static enum Os {
LINUX, WIN32, MACOSX, UNKOWN;
return name().toLowerCase();
}
+ /** The local operating system. */
public static Os local() {
String osStr = System.getProperty("os.name").toLowerCase();
if (osStr.startsWith("linux"))
}
+ /** Well-known processor architectures. */
static enum Arch {
X86_64, AARCH64, X86, POWERPC, UNKOWN;
return name().toLowerCase();
}
+ /** The locla processor architecture. */
public static Arch local() {
String archStr = System.getProperty("os.arch").toLowerCase();
return switch (archStr) {
import java.io.File;
import java.io.IOException;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
-import org.argeo.init.osgi.OsgiBootUtils;
import org.osgi.framework.Version;
/**
* been started.
*/
public class ClasspathSource extends AbstractProvisioningSource {
-
+ private final static Logger logger = System.getLogger(ClasspathSource.class.getName());
+
public ClasspathSource() {
super(true);
}
void load() throws IOException {
- A2Contribution classpathContribution = getOrAddContribution( A2Contribution.CLASSPATH);
+ A2Contribution classpathContribution = getOrAddContribution(A2Contribution.CLASSPATH);
List<String> classpath = Arrays.asList(System.getProperty("java.class.path").split(File.pathSeparator));
parts: for (String part : classpath) {
Path file = Paths.get(part);
String moduleName = readSymbolicNameFromModule(file);
A2Component component = classpathContribution.getOrAddComponent(moduleName);
A2Module module = component.getOrAddModule(version, file);
- if (OsgiBootUtils.isDebug())
- OsgiBootUtils.debug("Registered " + module);
+ logger.log(Level.TRACE, () -> "Registered " + module);
}
}
package org.argeo.api.a2;
import java.io.IOException;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.DirectoryStream;
import java.util.StringJoiner;
import java.util.TreeMap;
-import org.argeo.init.osgi.OsgiBootUtils;
import org.osgi.framework.Version;
/** A file system {@link AbstractProvisioningSource} in A2 format. */
public class FsA2Source extends AbstractProvisioningSource implements A2Source {
+ private final static Logger logger = System.getLogger(FsA2Source.class.getName());
+
private final Path base;
private final Map<String, String> variantsXOr;
if (versionStr != null) {
version = new Version(versionStr);
} else {
- OsgiBootUtils.debug("Ignore " + modulePath + " since version cannot be found");
+ logger.log(Level.TRACE, () -> "Ignore " + modulePath + " since version cannot be found");
continue modules;
}
// }
A2Component component = contribution.getOrAddComponent(componentName);
A2Module module = component.getOrAddModule(version, modulePath);
- if (OsgiBootUtils.isDebug())
- OsgiBootUtils.debug("Registered " + module);
+ logger.log(Level.TRACE, () -> "Registered " + module);
}
}
}
import java.io.File;
import java.io.IOException;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
-import org.argeo.init.osgi.OsgiBootUtils;
import org.osgi.framework.Version;
/** A file system {@link AbstractProvisioningSource} in Maven 2 format. */
public class FsM2Source extends AbstractProvisioningSource {
+ private final static Logger logger = System.getLogger(FsM2Source.class.getName());
+
private final Path base;
public FsM2Source(Path base) {
A2Contribution contribution = getOrAddContribution(contributionName);
A2Component component = contribution.getOrAddComponent(moduleName);
A2Module module = component.getOrAddModule(version, file);
- if (OsgiBootUtils.isDebug())
- OsgiBootUtils.debug("Registered " + module);
+ logger.log(Level.TRACE, () -> "Registered " + module);
}
return super.visitFile(file, attrs);
}
package org.argeo.api.a2;
-import org.argeo.init.osgi.OsgiBootUtils;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
* A running OSGi bundle context seen as a {@link AbstractProvisioningSource}.
*/
class OsgiContext extends AbstractProvisioningSource {
+ private final static Logger logger = System.getLogger(OsgiContext.class.getName());
+
private final BundleContext bc;
private A2Contribution runtimeContribution;
Version version = bundle.getVersion();
A2Component component = runtimeContribution.getOrAddComponent(componentId);
A2Module module = component.getOrAddModule(version, bundle);
- if (OsgiBootUtils.isDebug())
- OsgiBootUtils.debug("Registered bundle module " + module + " (location id: " + bundle.getLocation() + ")");
+ logger.log(Level.TRACE,
+ () -> "Registered bundle module " + module + " (location id: " + bundle.getLocation() + ")");
}
}
package org.argeo.api.a2;
+import static java.lang.System.Logger.Level.DEBUG;
+import static java.lang.System.Logger.Level.ERROR;
+import static java.lang.System.Logger.Level.INFO;
+import static java.lang.System.Logger.Level.TRACE;
import static org.argeo.api.a2.A2Source.SCHEME_A2;
import static org.argeo.api.a2.A2Source.SCHEME_A2_REFERENCE;
import java.io.File;
import java.io.UnsupportedEncodingException;
+import java.lang.System.Logger;
import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Set;
-import org.argeo.init.osgi.OsgiBootUtils;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
/** Loads provisioning sources into an OSGi context. */
public class ProvisioningManager {
- BundleContext bc;
- OsgiContext osgiContext;
- List<ProvisioningSource> sources = Collections.synchronizedList(new ArrayList<>());
+ private final static Logger logger = System.getLogger(ProvisioningManager.class.getName());
+
+ private BundleContext bc;
+ private OsgiContext osgiContext;
+ private List<ProvisioningSource> sources = Collections.synchronizedList(new ArrayList<>());
public ProvisioningManager(BundleContext bc) {
this.bc = bc;
includes, excludes);
source.load();
addSource(source);
- OsgiBootUtils.info("Registered " + uri + " as source");
+ logger.log(INFO, () -> "Registered " + uri + " as source");
// OS specific / native
String localRelPath = A2Contribution.localOsArchRelativePath();
SCHEME_A2_REFERENCE.equals(u.getScheme()), includes, excludes);
libSource.load();
addSource(libSource);
- OsgiBootUtils.info("Registered OS-specific " + uri + " as source (" + localRelPath + ")");
+ logger.log(DEBUG,
+ () -> "Registered OS-specific base " + localLibBase + " for source " + uri);
}
} else {
- OsgiBootUtils.debug("Source " + base + " does not exist, ignoring.");
+ logger.log(TRACE, () -> "Source " + base + " does not exist, ignoring.");
}
} else {
throw new UnsupportedOperationException(
baseStr = '/' + baseStr.replace(File.separatorChar, '/');
URI baseUri = new URI(A2Source.SCHEME_A2, null, null, 0, baseStr, null, null);
registerSource(baseUri.toString());
- OsgiBootUtils.debug("Default source from framework location " + frameworkLocation);
+ logger.log(TRACE, () -> "Default source from framework location " + frameworkLocation);
return true;
}
}
} catch (Exception e) {
- OsgiBootUtils.error("Cannot register default source based on framework location " + frameworkLocation, e);
+ logger.log(ERROR, "Cannot register default source based on framework location " + frameworkLocation, e);
}
return false;
}
// TODO remove old module? Or keep update history?
osgiContext.registerBundle(bundle);
if (compare == 0)
- OsgiBootUtils
- .debug("Updated bundle " + bundle.getLocation() + " to same version " + moduleVersion);
+ logger.log(TRACE,
+ () -> "Updated bundle " + bundle.getLocation() + " to same version " + moduleVersion);
else
- OsgiBootUtils.info("Updated bundle " + bundle.getLocation() + " to version " + moduleVersion);
+ logger.log(INFO, "Updated bundle " + bundle.getLocation() + " to version " + moduleVersion);
return bundle;
} else {
- if (OsgiBootUtils.isDebug())
- OsgiBootUtils.debug("Did not install as bundle module " + module
- + " since a module with higher version " + lastOsgiModule.getVersion()
- + " is already installed for branch " + osgiBranch);
+ logger.log(TRACE,
+ () -> "Did not install as bundle module " + module + " since a module with higher version "
+ + lastOsgiModule.getVersion() + " is already installed for branch " + osgiBranch);
}
}
} catch (Exception e) {
- OsgiBootUtils.error("Could not install module " + module + ": " + e.getMessage(), e);
+ logger.log(ERROR, "Could not install module " + module + ": " + e.getMessage(), e);
}
return null;
}
String fragmentHost = bundle.getHeaders().get(Constants.FRAGMENT_HOST);
if (fragmentHost != null)
fragmentsUpdated = true;
- OsgiBootUtils.info("Updated bundle " + bundle.getLocation() + " to version " + moduleVersion);
+ logger.log(INFO, "Updated bundle " + bundle.getLocation() + " to version " + moduleVersion);
updatedBundles.add(bundle);
} catch (Exception e) {
- OsgiBootUtils.error("Cannot update with module " + module, e);
+ logger.log(ERROR, "Cannot update with module " + module, e);
}
}
}
public interface RuntimeManager {
public void startRuntime(String relPath, Consumer<Map<String, String>> configCallback);
- public void stopRuntime(String relPath, boolean async);
+ public void closeRuntime(String relPath, boolean async);
}
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.launch.Framework;
/**
* Dynamically configures and launches multiple runtimes, coordinated by a main
Map<String, RuntimeContext> shutdowning = new HashMap<>(runtimeContexts);
for (String id : new HashSet<>(runtimeContexts.keySet())) {
logger.log(Logger.Level.DEBUG, "Shutting down runtime " + id + " ...");
- stopRuntime(id, true);
+ closeRuntime(id, true);
}
for (String id : shutdowning.keySet())
try {
runtimeContext.waitForStop(RUNTIME_SHUTDOWN_TIMEOUT);
} catch (InterruptedException e) {
// silent
+ } catch (Exception e) {
+ logger.log(Logger.Level.DEBUG, "Cannot wait for " + id + " to shutdown", e);
}
-
// shutdown manager runtime
try {
InternalState.getMainRuntimeContext().close();
public static void loadConfig(Path dir, Map<String, String> config) {
try {
- System.out.println("Load from " + dir);
+// System.out.println("Load from " + dir);
Path jvmArgsPath = dir.resolve(JVM_ARGS);
if (!Files.exists(jvmArgsPath)) {
// load from parent directory
}
OsgiRuntimeContext loadRuntime(String relPath, Consumer<Map<String, String>> configCallback) {
- stopRuntime(relPath, false);
+ closeRuntime(relPath, false);
Path stateArea = baseStateArea.resolve(relPath);
Path configArea = baseConfigArea.resolve(relPath);
Map<String, String> config = new HashMap<>();
public void startRuntime(String relPath, Consumer<Map<String, String>> configCallback) {
OsgiRuntimeContext runtimeContext = loadRuntime(relPath, configCallback);
runtimeContext.run();
+ Framework framework = runtimeContext.getFramework();
+ if (framework != null) {// in case the framework has closed very quickly after run
+ framework.getBundleContext().addFrameworkListener((e) -> {
+ if (e.getType() >= FrameworkEvent.STOPPED) {
+ logger.log(Level.DEBUG, "Externally stopped runtime " + relPath + ". Unregistering...", e);
+ runtimeContexts.remove(relPath);
+ }
+ });
+ } else {
+ closeRuntime(relPath, false);
+ }
}
- public void stopRuntime(String relPath, boolean async) {
+ public void closeRuntime(String relPath, boolean async) {
if (!runtimeContexts.containsKey(relPath))
return;
RuntimeContext runtimeContext = runtimeContexts.get(relPath);
public static void main(String[] args) {
ThinLoggerFinder.reloadConfiguration();
- logger.log(Logger.Level.INFO, () -> "Argeo Init starting with PID " + ProcessHandle.current().pid());
+ logger.log(Logger.Level.DEBUG, () -> "Argeo Init starting with PID " + ProcessHandle.current().pid());
Map<String, String> env = System.getenv();
// for (String envName : new TreeSet<>(env.keySet())) {
// System.out.format("%s=%s%n", envName, env.get(envName));
case "org.osgi.service.log.Logger":
case "org.eclipse.osgi.internal.log.LoggerImpl":
case "org.argeo.api.cms.CmsLog":
- case "org.argeo.init.osgi.OsgiBootUtils":
- case "org.slf4j.impl.ArgeoLogger":
- case "org.argeo.cms.internal.osgi.CmsOsgiLogger":
case "org.eclipse.jetty.util.log.Slf4jLog":
case "sun.util.logging.internal.LoggingProviderImpl$JULWrapper":
+ case "org.slf4j.impl.ArgeoLogger":
+ case "org.argeo.cms.internal.osgi.CmsOsgiLogger":
+ case "org.argeo.init.osgi.OsgiBootUtils":
lowestLoggerInterface = i;
continue stack;
default:
+++ /dev/null
-package org.argeo.init.osgi;
-
-import java.io.File;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.launch.Framework;
-
-/** Monitors the runtime and can shut it down. */
-@Deprecated
-public class AdminThread extends Thread {
- public final static String PROP_ARGEO_OSGI_SHUTDOWN_FILE = "argeo.osgi.shutdownFile";
- private File shutdownFile;
- private final BundleContext bundleContext;
-
- public AdminThread(BundleContext bundleContext) {
- super("OSGi Boot Admin");
- this.bundleContext = bundleContext;
- if (System.getProperty(PROP_ARGEO_OSGI_SHUTDOWN_FILE) != null) {
- shutdownFile = new File(
- System.getProperty(PROP_ARGEO_OSGI_SHUTDOWN_FILE));
- if (!shutdownFile.exists()) {
- shutdownFile = null;
- OsgiBootUtils.warn("Shutdown file " + shutdownFile
- + " not found, feature deactivated");
- }
- }
- }
-
- public void run() {
- if (shutdownFile != null) {
- // wait for file to be removed
- while (shutdownFile.exists()) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- Framework framework = (Framework) bundleContext.getBundle(0);
- try {
- // shutdown framework
- framework.stop();
- // wait 10 mins for shutdown
- framework.waitForStop(10 * 60 * 1000);
- // close VM
- System.exit(0);
- } catch (Exception e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
- }
-}
package org.argeo.init.osgi;
+import static java.lang.System.Logger.Level.TRACE;
+
import java.io.File;
import java.io.IOException;
+import java.lang.System.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/** Intermediary structure used by path matching */
class BundlesSet {
+ private final static Logger logger = System.getLogger(BundlesSet.class.getName());
+
private String baseUrl = "reference:file";// not used yet
private final String dir;
private List<String> includes = new ArrayList<String>();
dirPath = dirPath.substring("file:".length());
dir = new File(dirPath.replace('/', File.separatorChar)).getCanonicalPath();
- if (OsgiBootUtils.isDebug())
- OsgiBootUtils.debug("Base dir: " + dir);
+ logger.log(TRACE, () -> "Base dir: " + dir);
} catch (IOException e) {
throw new RuntimeException("Cannot convert to absolute path", e);
}
package org.argeo.init.osgi;
+import static java.lang.System.Logger.Level.WARNING;
+
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.lang.System.Logger;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
* name of the URL and of the content of the index.
*/
public class DistributionBundle {
+ private final static Logger logger = System.getLogger(DistributionBundle.class.getName());
+
private final static String INDEX_FILE_NAME = "modularDistribution.csv";
private final String url;
public void processUrl() {
JarInputStream jarIn = null;
try {
- URL u = new URL(url);
+ URL u = new URI(url).toURL();
// local cache
URI localUri = new URI(localCache + relativeUrl);
try {
localUri = new URI(localCache + relativeUrl);
} catch (URISyntaxException e) {
- OsgiBootUtils.warn(e.getMessage());
+ logger.log(WARNING, e.getMessage());
localUri = null;
}
Version version = new Version(osgiArtifact.getVersion());
+++ /dev/null
-package org.argeo.init.osgi;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.osgi.framework.BundleContext;
-
-/** An OSGi launcher executing first another class in the system class path. */
-public class Launcher {
-
- public static void main(String[] args) {
- // Try to load system properties
- String systemPropertiesFilePath = getProperty(OsgiBoot.PROP_ARGEO_OSGI_BOOT_SYSTEM_PROPERTIES_FILE);
- if (systemPropertiesFilePath != null) {
- FileInputStream in;
- try {
- in = new FileInputStream(systemPropertiesFilePath);
- System.getProperties().load(in);
- } catch (IOException e1) {
- throw new RuntimeException("Cannot load system properties from " + systemPropertiesFilePath, e1);
- }
- if (in != null) {
- try {
- in.close();
- } catch (Exception e) {
- // silent
- }
- }
- }
-
- // Start main class
- startMainClass();
-
- // Start Equinox
- BundleContext bundleContext = null;
- try {
- bundleContext = OsgiBootUtils.launch(OsgiBootUtils.equinoxArgsToConfiguration(args)).getBundleContext();
- } catch (Exception e) {
- throw new RuntimeException("Cannot start Equinox.", e);
- }
-
- // OSGi bootstrap
- OsgiBoot osgiBoot = new OsgiBoot(bundleContext);
- osgiBoot.bootstrap();
- }
-
- protected static void startMainClass() {
- String className = getProperty(OsgiBoot.PROP_ARGEO_OSGI_BOOT_APPCLASS);
- if (className == null)
- return;
-
- String line = System.getProperty(OsgiBoot.PROP_ARGEO_OSGI_BOOT_APPARGS, "");
-
- String[] uiArgs = readArgumentsFromLine(line);
-
- try {
- // Launch main method using reflection
- Class<?> clss = Class.forName(className);
- Class<?>[] mainArgsClasses = new Class[] { uiArgs.getClass() };
- Object[] mainArgs = { uiArgs };
- Method mainMethod = clss.getMethod("main", mainArgsClasses);
- mainMethod.invoke(null, mainArgs);
- } catch (Exception e) {
- throw new RuntimeException("Cannot start main class.", e);
- }
-
- }
-
- /**
- * Transform a line into an array of arguments, taking "" as single arguments.
- * (nested \" are not supported)
- */
- private static String[] readArgumentsFromLine(String lineOrig) {
- String line = lineOrig.trim();// remove trailing spaces
- List<String> args = new ArrayList<String>();
- StringBuffer curr = new StringBuffer("");
- boolean inQuote = false;
- char[] arr = line.toCharArray();
- for (int i = 0; i < arr.length; i++) {
- char c = arr[i];
- switch (c) {
- case '\"':
- inQuote = !inQuote;
- break;
- case ' ':
- if (!inQuote) {// otherwise, no break: goes to default
- if (curr.length() > 0) {
- args.add(curr.toString());
- curr = new StringBuffer("");
- }
- break;
- }
- default:
- curr.append(c);
- break;
- }
- }
-
- // Add last arg
- if (curr.length() > 0) {
- args.add(curr.toString());
- curr = null;
- }
-
- String[] res = new String[args.size()];
- for (int i = 0; i < args.size(); i++) {
- res[i] = args.get(i).toString();
- }
- return res;
- }
-
- public static String getProperty(String name, String defaultValue) {
- final String value;
- if (defaultValue != null)
- value = System.getProperty(name, defaultValue);
- else
- value = System.getProperty(name);
-
- if (value == null || value.equals(""))
- return null;
- else
- return value;
- }
-
- public static String getProperty(String name) {
- return getProperty(name, null);
- }
-
-}
+++ /dev/null
-package org.argeo.init.osgi;
-
-import java.lang.management.ManagementFactory;
-
-public class Main {
-
- public static void main(String[] args) {
- String mainClass = System.getProperty(OsgiBoot.PROP_ARGEO_OSGI_BOOT_APPCLASS);
- if (mainClass == null) {
- throw new IllegalArgumentException(
- "System property " + OsgiBoot.PROP_ARGEO_OSGI_BOOT_APPCLASS + " must be specified");
- }
-
- OsgiBuilder osgi = new OsgiBuilder();
- String distributionUrl = System.getProperty(OsgiBoot.PROP_ARGEO_OSGI_DISTRIBUTION_URL);
- if (distributionUrl != null)
- osgi.install(distributionUrl);
- // osgi.conf("argeo.node.useradmin.uris", "os:///");
- // osgi.conf("osgi.clean", "true");
- // osgi.conf("osgi.console", "true");
- osgi.launch();
-
- if (OsgiBootUtils.isDebug()) {
- long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
- String jvmUptimeStr = (jvmUptime / 1000) + "." + (jvmUptime % 1000) + "s";
- OsgiBootUtils.debug("Ready to launch " + mainClass + " in " + jvmUptimeStr);
- }
-
- osgi.main(mainClass, args);
-
- osgi.shutdown();
-
- }
-
-}
+++ /dev/null
-package org.argeo.init.osgi;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.ServiceLoader;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.launch.Framework;
-import org.osgi.framework.launch.FrameworkFactory;
-
-/** Launch an OSGi framework and deploy a CMS Node into it. */
-public class NodeRunner {
- private Long timeout = 30 * 1000l;
- private final Path baseDir;
- private final Path confDir;
- private final Path dataDir;
-
- private String baseUrl = "http://forge.argeo.org/data/java/argeo-2.1/";
- private String distributionUrl = null;
-
- private Framework framework = null;
-
- public NodeRunner(String distributionUrl, Path baseDir) {
- this.distributionUrl = distributionUrl;
- Path mavenBase = Paths.get(System.getProperty("user.home") + "/.m2/repository");
- Path osgiBase = Paths.get("/user/share/osgi");
- if (Files.exists(mavenBase)) {
- Path mavenPath = mavenBase.resolve(distributionUrl);
- if (Files.exists(mavenPath))
- baseUrl = mavenBase.toUri().toString();
- } else if (Files.exists(osgiBase)) {
- Path osgiPath = osgiBase.resolve(distributionUrl);
- if (Files.exists(osgiPath))
- baseUrl = osgiBase.toUri().toString();
- }
-
- this.baseDir = baseDir;
- this.confDir = this.baseDir.resolve("state");
- this.dataDir = this.baseDir.resolve("data");
-
- }
-
- public void start() {
- long begin = System.currentTimeMillis();
- // log4j
- Path log4jFile = confDir.resolve("log4j.properties");
- if (!Files.exists(log4jFile))
- copyResource("/org/argeo/osgi/boot/log4j.properties", log4jFile);
- System.setProperty("log4j.configuration", "file://" + log4jFile.toAbsolutePath());
-
- // Start Equinox
- try {
- ServiceLoader<FrameworkFactory> ff = ServiceLoader.load(FrameworkFactory.class);
- FrameworkFactory frameworkFactory = ff.iterator().next();
- Map<String, String> configuration = new HashMap<String, String>();
- configuration.put("osgi.configuration.area", confDir.toAbsolutePath().toString());
- configuration.put("osgi.instance.area", dataDir.toAbsolutePath().toString());
- defaultConfiguration(configuration);
-
- framework = frameworkFactory.newFramework(configuration);
- framework.start();
- info("## Date : " + new Date());
- info("## Data : " + dataDir.toAbsolutePath());
- } catch (Exception e) {
- throw new IllegalStateException("Cannot start OSGi framework", e);
- }
- BundleContext bundleContext = framework.getBundleContext();
- try {
-
- // Spring configs currently require System properties
- // System.getProperties().putAll(configuration);
-
- // expected by JAAS as System.property FIXME
- System.setProperty("osgi.instance.area", bundleContext.getProperty("osgi.instance.area"));
-
- // OSGi bootstrap
- OsgiBoot osgiBoot = new OsgiBoot(bundleContext);
-
- osgiBoot.installUrls(osgiBoot.getDistributionUrls(distributionUrl, baseUrl));
-
- // Start runtime
- Properties startProperties = new Properties();
- // TODO make it possible to override it
- startProperties.put("argeo.osgi.start.2.node",
- "org.eclipse.equinox.http.servlet,org.eclipse.equinox.http.jetty,"
- + "org.eclipse.equinox.metatype,org.eclipse.equinox.cm,org.eclipse.rap.rwt.osgi");
- startProperties.put("argeo.osgi.start.3.node", "org.argeo.cms");
- startProperties.put("argeo.osgi.start.4.node",
- "org.eclipse.gemini.blueprint.extender,org.eclipse.equinox.http.registry");
- osgiBoot.startBundles(startProperties);
-
- // Find node repository
- ServiceReference<?> sr = null;
- while (sr == null) {
- sr = bundleContext.getServiceReference("javax.jcr.Repository");
- if (System.currentTimeMillis() - begin > timeout)
- throw new RuntimeException("Could find node after " + timeout + "ms");
- Thread.sleep(100);
- }
- Object nodeDeployment = bundleContext.getService(sr);
- info("Node Deployment " + nodeDeployment);
-
- // Initialization completed
- long duration = System.currentTimeMillis() - begin;
- info("## CMS Launcher initialized in " + (duration / 1000) + "s " + (duration % 1000) + "ms");
- } catch (Exception e) {
- shutdown();
- throw new RuntimeException("Cannot start CMS", e);
- } finally {
-
- }
- }
-
- private void defaultConfiguration(Map<String, String> configuration) {
- // all permissions to OSGi security manager
- Path policyFile = confDir.resolve("node.policy");
- if (!Files.exists(policyFile))
- copyResource("/org/argeo/osgi/boot/node.policy", policyFile);
- configuration.put("java.security.policy", "file://" + policyFile.toAbsolutePath());
-
- configuration.put("org.eclipse.rap.workbenchAutostart", "false");
- configuration.put("org.eclipse.equinox.http.jetty.autostart", "false");
- configuration.put("org.osgi.framework.bootdelegation",
- "com.sun.jndi.ldap,com.sun.jndi.ldap.sasl,com.sun.security.jgss,com.sun.jndi.dns,"
- + "com.sun.nio.file,com.sun.nio.sctp");
-
- // Do clean
- // configuration.put("osgi.clean", "true");
- // if (args.length == 0) {
- // configuration.put("osgi.console", "");
- // }
- }
-
- public void shutdown() {
- try {
- framework.stop();
- framework.waitForStop(15 * 1000);
- } catch (Exception silent) {
- }
- }
-
- public Path getConfDir() {
- return confDir;
- }
-
- public Path getDataDir() {
- return dataDir;
- }
-
- public Framework getFramework() {
- return framework;
- }
-
- public static void main(String[] args) {
- try {
- String distributionUrl;
- Path executionDir;
- if (args.length == 2) {
- distributionUrl = args[0];
- executionDir = Paths.get(args[1]);
- } else if (args.length == 1) {
- executionDir = Paths.get(System.getProperty("user.dir"));
- distributionUrl = args[0];
- } else if (args.length == 0) {
- executionDir = Paths.get(System.getProperty("user.dir"));
- distributionUrl = "org/argeo/commons/org.argeo.dep.cms.sdk/2.1.70/org.argeo.dep.cms.sdk-2.1.70.jar";
- }else{
- printUsage();
- System.exit(1);
- return;
- }
-
- NodeRunner nodeRunner = new NodeRunner(distributionUrl, executionDir);
- nodeRunner.start();
-// if (args.length != 0)
-// System.exit(0);
- } catch (Exception e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
-
- protected static void info(Object msg) {
- System.out.println(msg);
- }
-
- protected static void err(Object msg) {
- System.err.println(msg);
- }
-
- protected static void debug(Object msg) {
- System.out.println(msg);
- }
-
- protected static void copyResource(String resource, Path targetFile) {
- InputStream input = null;
- OutputStream output = null;
- try {
- input = NodeRunner.class.getResourceAsStream(resource);
- Files.createDirectories(targetFile.getParent());
- output = Files.newOutputStream(targetFile);
- byte[] buf = new byte[8192];
- while (true) {
- int length = input.read(buf);
- if (length < 0)
- break;
- output.write(buf, 0, length);
- }
- } catch (Exception e) {
- throw new RuntimeException("Cannot write " + resource + " file to " + targetFile, e);
- } finally {
- try {
- input.close();
- } catch (Exception ignore) {
- }
- try {
- output.close();
- } catch (Exception ignore) {
- }
- }
-
- }
-
- static void printUsage(){
- err("Usage: <distribution url> <base dir>");
- }
-}
package org.argeo.init.osgi;
-import static org.argeo.init.osgi.OsgiBootUtils.debug;
-import static org.argeo.init.osgi.OsgiBootUtils.warn;
+import static java.lang.System.Logger.Level.DEBUG;
+import static java.lang.System.Logger.Level.ERROR;
+import static java.lang.System.Logger.Level.TRACE;
+import static java.lang.System.Logger.Level.WARNING;
import java.io.File;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Properties;
+import java.util.ServiceLoader;
import java.util.Set;
import java.util.SortedMap;
import java.util.StringTokenizer;
import org.osgi.framework.BundleException;
import org.osgi.framework.FrameworkEvent;
import org.osgi.framework.Version;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.launch.FrameworkFactory;
import org.osgi.framework.startlevel.BundleStartLevel;
import org.osgi.framework.startlevel.FrameworkStartLevel;
import org.osgi.framework.wiring.FrameworkWiring;
* properties. The approach is to generate list of URLs based on various
* methods, configured via properties.
*/
-public class OsgiBoot implements OsgiBootConstants {
+public class OsgiBoot {
+ private final static Logger logger = System.getLogger(OsgiBoot.class.getName());
+
@Deprecated
final static String PROP_ARGEO_OSGI_BUNDLES = "argeo.osgi.bundles";
final static String PROP_ARGEO_OSGI_BASE_URL = "argeo.osgi.baseUrl";
String osgiInstancePath = getProperty(InitConstants.PROP_OSGI_INSTANCE_AREA);
String osgiConfigurationPath = getProperty(InitConstants.PROP_OSGI_CONFIGURATION_AREA);
String osgiSharedConfigurationPath = getProperty(InitConstants.PROP_OSGI_CONFIGURATION_AREA);
- OsgiBootUtils.info("OSGi bootstrap starting" //
+ logger.log(DEBUG, () -> "OSGi bootstrap starting" //
+ (osgiInstancePath != null ? " data: " + osgiInstancePath + "" : "") //
+ (osgiConfigurationPath != null ? " state: " + osgiConfigurationPath + "" : "") //
+ (osgiSharedConfigurationPath != null ? " config: " + osgiSharedConfigurationPath + "" : "") //
// complete
long duration = System.currentTimeMillis() - begin;
- OsgiBootUtils.info("OSGi bootstrap completed in " + Math.round(((double) duration) / 1000) + "s ("
+ logger.log(DEBUG, () -> "OSGi bootstrap completed in " + Math.round(((double) duration) / 1000) + "s ("
+ duration + "ms), " + bundleContext.getBundles().length + " bundles");
} catch (RuntimeException e) {
- OsgiBootUtils.error("OSGi bootstrap FAILED", e);
+ logger.log(ERROR, "OSGi bootstrap FAILED", e);
throw e;
}
// diagnostics
- if (OsgiBootUtils.isDebug()) {
+ if (logger.isLoggable(TRACE)) {
OsgiBootDiagnostics diagnostics = new OsgiBootDiagnostics(bundleContext);
diagnostics.checkUnresolved();
Map<String, Set<String>> duplicatePackages = diagnostics.findPackagesExportedTwice();
if (duplicatePackages.size() > 0) {
- OsgiBootUtils.info("Packages exported twice:");
+ logger.log(TRACE, "Packages exported twice:");
Iterator<String> it = duplicatePackages.keySet().iterator();
while (it.hasNext()) {
String pkgName = it.next();
- OsgiBootUtils.info(pkgName);
+ logger.log(TRACE, pkgName);
Set<String> bdles = duplicatePackages.get(pkgName);
Iterator<String> bdlesIt = bdles.iterator();
while (bdlesIt.hasNext())
- OsgiBootUtils.info(" " + bdlesIt.next());
+ logger.log(TRACE, " " + bdlesIt.next());
}
}
}
try {
if (installedBundles.containsKey(url)) {
Bundle bundle = (Bundle) installedBundles.get(url);
- if (OsgiBootUtils.isDebug())
- debug("Bundle " + bundle.getSymbolicName() + " already installed from " + url);
+ logger.log(TRACE, () -> "Bundle " + bundle.getSymbolicName() + " already installed from " + url);
} else if (url.contains("/" + InitConstants.SYMBOLIC_NAME_EQUINOX + "/")
|| url.contains("/" + InitConstants.SYMBOLIC_NAME_INIT + "/")) {
- if (OsgiBootUtils.isDebug())
- warn("Skip " + url);
+ if (logger.isLoggable(TRACE))
+ logger.log(WARNING, "Skip " + url);
return;
} else {
Bundle bundle = bundleContext.installBundle(url);
if (url.startsWith("http"))
- OsgiBootUtils
- .info("Installed " + bundle.getSymbolicName() + "-" + bundle.getVersion() + " from " + url);
- else if (OsgiBootUtils.isDebug())
- OsgiBootUtils.debug(
- "Installed " + bundle.getSymbolicName() + "-" + bundle.getVersion() + " from " + url);
+ logger.log(DEBUG,
+ () -> "Installed " + bundle.getSymbolicName() + "-" + bundle.getVersion() + " from " + url);
+ else
+ logger.log(TRACE,
+ () -> "Installed " + bundle.getSymbolicName() + "-" + bundle.getVersion() + " from " + url);
assert bundle.getSymbolicName() != null;
// uninstall previous versions
bundles: for (Bundle b : bundleContext.getBundles()) {
if (bundleV.getMicro() > bV.getMicro()) {
// uninstall older bundles
b.uninstall();
- OsgiBootUtils.debug("Uninstalled " + b);
+ logger.log(TRACE, () -> "Uninstalled " + b);
} else if (bundleV.getMicro() < bV.getMicro()) {
// uninstall just installed bundle if newer
bundle.uninstall();
- OsgiBootUtils.debug("Uninstalled " + bundle);
+ logger.log(TRACE, () -> "Uninstalled " + bundle);
break bundles;
} else {
// uninstall any other with same major/minor
if (!bundleV.getQualifier().equals(bV.getQualifier())) {
b.uninstall();
- OsgiBootUtils.debug("Uninstalled " + b);
+ logger.log(TRACE, () -> "Uninstalled " + b);
}
}
}
// have already been installed...
} else {
if (message.contains(ALREADY_INSTALLED)) {
- if (OsgiBootUtils.isDebug())
- OsgiBootUtils.warn("Duplicate install from " + url + ": " + message);
+ if (logger.isLoggable(TRACE))
+ logger.log(WARNING, "Duplicate install from " + url + ": " + message);
} else
- OsgiBootUtils.warn("Could not install bundle from " + url + ": " + message);
+ logger.log(WARNING, "Could not install bundle from " + url + ": " + message);
}
- if (OsgiBootUtils.isDebug() && !message.contains(ALREADY_INSTALLED))
+ if (logger.isLoggable(TRACE) && !message.contains(ALREADY_INSTALLED))
e.printStackTrace();
}
}
}
}
// then try all start level until a maximum
- int maxStartLevel = Integer.parseInt(getProperty(InitConstants.PROP_ARGEO_OSGI_MAX_START_LEVEL, DEFAULT_MAX_START_LEVEL));
+ int maxStartLevel = Integer
+ .parseInt(getProperty(InitConstants.PROP_ARGEO_OSGI_MAX_START_LEVEL, DEFAULT_MAX_START_LEVEL));
for (int i = 1; i <= maxStartLevel; i++) {
String key = InitConstants.PROP_ARGEO_OSGI_START + "." + i;
String value = getProperty(key);
doStartBundles(map);
}
- @Deprecated
- public void startBundles(Properties properties) {
+ void startBundles(Properties properties) {
Map<String, String> map = new TreeMap<>();
// first use properties
if (properties != null) {
startBundles(map);
}
- /** Start bundle based on keys starting with {@link InitConstants#PROP_ARGEO_OSGI_START}. */
+ /**
+ * Start bundle based on keys starting with
+ * {@link InitConstants#PROP_ARGEO_OSGI_START}.
+ */
protected void doStartBundles(Map<String, String> properties) {
FrameworkStartLevel frameworkStartLevel = bundleContext.getBundle(0).adapt(FrameworkStartLevel.class);
int initialStartLevel = frameworkStartLevel.getInitialBundleStartLevel();
int defaultStartLevel = Integer.parseInt(getProperty(InitConstants.PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL, "4"));
int activeStartLevel = Integer.parseInt(getProperty(InitConstants.PROP_OSGI_STARTLEVEL, "6"));
- if (OsgiBootUtils.isDebug()) {
- OsgiBootUtils.debug("OSGi default start level: "
- + getProperty(InitConstants.PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL, "<not set>") + ", using " + defaultStartLevel);
- OsgiBootUtils.debug("OSGi active start level: " + getProperty(InitConstants.PROP_OSGI_STARTLEVEL, "<not set>")
+ if (logger.isLoggable(TRACE)) {
+ logger.log(TRACE,
+ "OSGi default start level: "
+ + getProperty(InitConstants.PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL, "<not set>") + ", using "
+ + defaultStartLevel);
+ logger.log(TRACE, "OSGi active start level: " + getProperty(InitConstants.PROP_OSGI_STARTLEVEL, "<not set>")
+ ", using " + activeStartLevel);
- OsgiBootUtils.debug("Framework start level: " + frameworkStartLevel.getStartLevel() + " (initial: "
+ logger.log(TRACE, "Framework start level: " + frameworkStartLevel.getStartLevel() + " (initial: "
+ initialStartLevel + ")");
}
try {
bundle.start();
} catch (BundleException e) {
- OsgiBootUtils.error("Cannot mark " + bsn + " as started", e);
+ logger.log(ERROR, "Cannot mark " + bsn + " as started", e);
}
- if (OsgiBootUtils.isDebug())
- OsgiBootUtils.debug(bsn + " v" + bundle.getVersion() + " starts at level " + level);
+ logger.log(TRACE, () -> bsn + " v" + bundle.getVersion() + " starts at level " + level);
}
}
}
- if (OsgiBootUtils.isDebug())
- OsgiBootUtils.debug("About to set framework start level to " + activeStartLevel + " ...");
+ logger.log(TRACE, () -> "About to set framework start level to " + activeStartLevel + " ...");
frameworkStartLevel.setStartLevel(activeStartLevel, (FrameworkEvent event) -> {
if (event.getType() == FrameworkEvent.ERROR) {
- OsgiBootUtils.error("Start sequence failed", event.getThrowable());
+ logger.log(ERROR, "Start sequence failed", event.getThrowable());
} else {
- if (OsgiBootUtils.isDebug())
- OsgiBootUtils.debug("Framework started at level " + frameworkStartLevel.getStartLevel());
+ logger.log(TRACE, () -> "Framework started at level " + frameworkStartLevel.getStartLevel());
}
});
Integer defaultStartLevel) {
// default (and previously, only behaviour)
- appendToStartLevels(startLevels, defaultStartLevel, properties.getOrDefault(InitConstants.PROP_ARGEO_OSGI_START, ""));
+ appendToStartLevels(startLevels, defaultStartLevel,
+ properties.getOrDefault(InitConstants.PROP_ARGEO_OSGI_START, ""));
// list argeo.osgi.start.* system properties
Iterator<String> keys = properties.keySet().iterator();
return urls;
// bundlePatterns = SystemPropertyUtils.resolvePlaceholders(bundlePatterns);
- if (OsgiBootUtils.isDebug())
- debug(PROP_ARGEO_OSGI_BUNDLES + "=" + bundlePatterns);
+ logger.log(TRACE, () -> PROP_ARGEO_OSGI_BUNDLES + "=" + bundlePatterns);
StringTokenizer st = new StringTokenizer(bundlePatterns, ",");
List<BundlesSet> bundlesSets = new ArrayList<BundlesSet>();
File[] files = baseDir.listFiles();
if (files == null) {
- if (OsgiBootUtils.isDebug())
- OsgiBootUtils.warn("Base dir " + baseDir + " has no children, exists=" + baseDir.exists()
+ if (logger.isLoggable(TRACE))
+ logger.log(Level.WARNING, "Base dir " + baseDir + " has no children, exists=" + baseDir.exists()
+ ", isDirectory=" + baseDir.isDirectory());
return;
}
// }
} else {
boolean nonDirectoryOk = matcher.matches(Paths.get(newCurrentPath));
- if (OsgiBootUtils.isDebug())
- debug(currentPath + " " + (ok ? "" : " not ") + " matched with " + pattern);
+ logger.log(TRACE,
+ () -> currentPath + " " + (ok ? "" : " not ") + " matched with " + pattern);
if (nonDirectoryOk)
matched.add(relativeToFullPath(base, newCurrentPath));
}
return getProperty(name, null);
}
+ /*
+ * PLAIN OSGI LAUNCHER
+ */
+ /** Launch an OSGi framework. OSGi Boot initialisation is NOT performed. */
+ public static Framework defaultOsgiLaunch(Map<String, String> configuration) {
+ Optional<FrameworkFactory> frameworkFactory = ServiceLoader.load(FrameworkFactory.class).findFirst();
+ if (frameworkFactory.isEmpty())
+ throw new IllegalStateException("No framework factory found");
+ return defaultOsgiLaunch(frameworkFactory.get(), configuration);
+ }
+
+ /** Launch an OSGi framework. OSGi Boot initialisation is NOT performed. */
+ public static Framework defaultOsgiLaunch(FrameworkFactory frameworkFactory, Map<String, String> configuration) {
+ // start OSGi
+ Framework framework = frameworkFactory.newFramework(configuration);
+ try {
+ framework.start();
+ } catch (BundleException e) {
+ throw new IllegalStateException("Cannot start OSGi framework", e);
+ }
+ return framework;
+ }
+
/*
* BEAN METHODS
*/
+++ /dev/null
-package org.argeo.init.osgi;
-
-public interface OsgiBootConstants {
-
-}
package org.argeo.init.osgi;
+import static java.lang.System.Logger.Level.WARNING;
+
+import java.lang.System.Logger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
-@SuppressWarnings("deprecation")
class OsgiBootDiagnostics {
+ private final static Logger logger = System.getLogger(OsgiBootDiagnostics.class.getName());
+
private final BundleContext bundleContext;
public OsgiBootDiagnostics(BundleContext bundleContext) {
}
if (unresolvedBundles.size() != 0) {
- OsgiBootUtils.warn("Unresolved bundles " + unresolvedBundles);
+ logger.log(WARNING, "Unresolved bundles " + unresolvedBundles);
}
// try to start unresolved bundles in order to trigger diagnostics
+++ /dev/null
-package org.argeo.init.osgi;
-
-import java.lang.System.Logger;
-import java.lang.System.Logger.Level;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.ServiceLoader;
-import java.util.StringTokenizer;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.launch.Framework;
-import org.osgi.framework.launch.FrameworkFactory;
-
-/** Utilities, mostly related to logging. */
-public class OsgiBootUtils {
- private final static Logger logger = System.getLogger(OsgiBootUtils.class.getName());
-
- public static void info(Object obj) {
- logger.log(Level.INFO, () -> Objects.toString(obj));
- }
-
- public static void debug(Object obj) {
- logger.log(Level.TRACE, () -> Objects.toString(obj));
- }
-
- public static void warn(Object obj) {
- logger.log(Level.WARNING, () -> Objects.toString(obj));
- }
-
- public static void error(Object obj, Throwable e) {
- logger.log(Level.ERROR, () -> Objects.toString(obj), e);
- }
-
- public static boolean isDebug() {
- return logger.isLoggable(Level.TRACE);
- }
-
- public static String stateAsString(int state) {
- switch (state) {
- case Bundle.UNINSTALLED:
- return "UNINSTALLED";
- case Bundle.INSTALLED:
- return "INSTALLED";
- case Bundle.RESOLVED:
- return "RESOLVED";
- case Bundle.STARTING:
- return "STARTING";
- case Bundle.ACTIVE:
- return "ACTIVE";
- case Bundle.STOPPING:
- return "STOPPING";
- default:
- return Integer.toString(state);
- }
- }
-
- /**
- * @return ==0: versions are identical, <0: tested version is newer, >0:
- * currentVersion is newer.
- */
- public static int compareVersions(String currentVersion, String testedVersion) {
- List<String> cToks = new ArrayList<String>();
- StringTokenizer cSt = new StringTokenizer(currentVersion, ".");
- while (cSt.hasMoreTokens())
- cToks.add(cSt.nextToken());
- List<String> tToks = new ArrayList<String>();
- StringTokenizer tSt = new StringTokenizer(currentVersion, ".");
- while (tSt.hasMoreTokens())
- tToks.add(tSt.nextToken());
-
- int comp = 0;
- comp: for (int i = 0; i < cToks.size(); i++) {
- if (tToks.size() <= i) {
- // equals until then, tested shorter
- comp = 1;
- break comp;
- }
-
- String c = (String) cToks.get(i);
- String t = (String) tToks.get(i);
-
- try {
- int cInt = Integer.parseInt(c);
- int tInt = Integer.parseInt(t);
- if (cInt == tInt)
- continue comp;
- else {
- comp = (cInt - tInt);
- break comp;
- }
- } catch (NumberFormatException e) {
- if (c.equals(t))
- continue comp;
- else {
- comp = c.compareTo(t);
- break comp;
- }
- }
- }
-
- if (comp == 0 && tToks.size() > cToks.size()) {
- // equals until then, current shorter
- comp = -1;
- }
-
- return comp;
- }
-
- public static Framework launch(Map<String, String> configuration) {
- Optional<FrameworkFactory> frameworkFactory = ServiceLoader.load(FrameworkFactory.class).findFirst();
- if (frameworkFactory.isEmpty())
- throw new IllegalStateException("No framework factory found");
- return launch(frameworkFactory.get(), configuration);
- }
-
- /** Launch an OSGi framework. */
- public static Framework launch(FrameworkFactory frameworkFactory, Map<String, String> configuration) {
- // start OSGi
- Framework framework = frameworkFactory.newFramework(configuration);
- try {
- framework.start();
- } catch (BundleException e) {
- throw new IllegalStateException("Cannot start OSGi framework", e);
- }
- return framework;
- }
-
- @Deprecated
- public static Map<String, String> equinoxArgsToConfiguration(String[] args) {
- // FIXME implement it
- return new HashMap<>();
- }
-
-}
package org.argeo.init.osgi;
+import static java.lang.System.Logger.Level.ERROR;
+import static java.lang.System.Logger.Level.TRACE;
+
+import java.lang.System.Logger;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.ArrayList;
/** OSGi builder, focusing on ease of use for scripting. */
public class OsgiBuilder {
+ private final static Logger logger = System.getLogger(OsgiBuilder.class.getName());
+
private final static String PROP_HTTP_PORT = "org.osgi.service.http.port";
private final static String PROP_HTTPS_PORT = "org.osgi.service.https.port";
private final static String PROP_OSGI_CLEAN = "osgi.clean";
public OsgiBuilder() {
// configuration.put("osgi.clean", "true");
- configuration.put(InitConstants.PROP_OSGI_CONFIGURATION_AREA, System.getProperty(InitConstants.PROP_OSGI_CONFIGURATION_AREA));
- configuration.put(InitConstants.PROP_OSGI_INSTANCE_AREA, System.getProperty(InitConstants.PROP_OSGI_INSTANCE_AREA));
+ configuration.put(InitConstants.PROP_OSGI_CONFIGURATION_AREA,
+ System.getProperty(InitConstants.PROP_OSGI_CONFIGURATION_AREA));
+ configuration.put(InitConstants.PROP_OSGI_INSTANCE_AREA,
+ System.getProperty(InitConstants.PROP_OSGI_INSTANCE_AREA));
configuration.put(PROP_OSGI_CLEAN, System.getProperty(PROP_OSGI_CLEAN));
}
public Framework launch() {
// start OSGi
- framework = OsgiBootUtils.launch(configuration);
+ framework = OsgiBoot.defaultOsgiLaunch(configuration);
BundleContext bc = framework.getBundleContext();
String osgiData = bc.getProperty(InitConstants.PROP_OSGI_INSTANCE_AREA);
// String osgiConf = bc.getProperty(OsgiBoot.CONFIGURATION_AREA_PROP);
String osgiConf = framework.getDataFile("").getAbsolutePath();
- if (OsgiBootUtils.isDebug())
- OsgiBootUtils.debug("OSGi starting - data: " + osgiData + " conf: " + osgiConf);
+ logger.log(TRACE, () -> "OSGi starting - data: " + osgiData + " conf: " + osgiConf);
OsgiBoot osgiBoot = new OsgiBoot(framework.getBundleContext());
if (distributionBundles.isEmpty()) {
try {
return st.waitForService(timeout);
} catch (InterruptedException e) {
- OsgiBootUtils.error("Interrupted", e);
+ logger.log(ERROR, "Interrupted", e);
return null;
} finally {
st.close();
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;
/** 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<String, String> config;
private Framework framework;
- private OsgiBoot osgiBoot;
+// private OsgiBoot osgiBoot;
/**
* Constructor to use when the runtime context will create the OSGi
@Override
public void run() {
- ServiceLoader<FrameworkFactory> sl = ServiceLoader.load(FrameworkFactory.class);
- Optional<FrameworkFactory> 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<FrameworkFactory> sl = ServiceLoader.load(FrameworkFactory.class);
+ Optional<FrameworkFactory> 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();
}
}
- public void start(BundleContext bundleContext) {
+ protected void start(BundleContext bundleContext) {
// preferences
// SystemRootPreferences systemRootPreferences = ThinPreferencesFactory.getInstance().getSystemRootPreferences();
// bundleContext.registerService(AbstractPreferences.class, systemRootPreferences, new Hashtable<>());
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();
@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() {
return entryPoint;
}, properties);
if (log.isDebugEnabled())
- log.info("Added web entry point " + (contextName != null ? "/" + contextName : "") + entryPointName);
+ log.debug("Added web entry point " + (contextName != null ? "/" + contextName : "") + entryPointName);
}
// if (log.isDebugEnabled())
// log.debug("Published CMS web app /" + (contextName != null ? contextName : ""));
rwtAppReg.unregister();
if (bundleContext != null) {
rwtAppReg = bundleContext.registerService(ApplicationConfiguration.class, this, regProps);
- if (log.isDebugEnabled())
- log.debug("Publishing CMS web app /" + (contextName != null ? contextName : "") + " ...");
+ log.info("Publishing CMS web app /" + (contextName != null ? contextName : "") + " ...");
}
}