1 package org
.argeo
.init
;
3 import java
.io
.IOException
;
4 import java
.io
.InputStream
;
5 import java
.lang
.System
.Logger
;
6 import java
.nio
.file
.Files
;
7 import java
.nio
.file
.Path
;
8 import java
.nio
.file
.Paths
;
9 import java
.util
.HashMap
;
11 import java
.util
.Objects
;
12 import java
.util
.Properties
;
13 import java
.util
.TreeMap
;
15 import org
.argeo
.init
.logging
.ThinLoggerFinder
;
16 import org
.argeo
.init
.osgi
.OsgiBoot
;
17 import org
.argeo
.init
.osgi
.OsgiRuntimeContext
;
19 /** Configure and launch an Argeo service. */
20 public class Service
{
21 private final static Logger logger
= System
.getLogger(Service
.class.getName());
23 final static String FILE_SYSTEM_PROPERTIES
= "system.properties";
25 public final static String PROP_ARGEO_INIT_MAIN
= "argeo.init.main";
27 private static RuntimeContext runtimeContext
= null;
29 protected Service(String
[] args
) {
32 public static void main(String
[] args
) {
33 final long pid
= ProcessHandle
.current().pid();
34 logger
.log(Logger
.Level
.DEBUG
, () -> "Argeo Init starting with PID " + pid
);
37 Runtime
.getRuntime().addShutdownHook(new Thread(() -> {
39 if (Service
.runtimeContext
!= null) {
40 // System.out.println("Argeo Init stopping with PID " + pid);
41 Service
.runtimeContext
.close();
42 Service
.runtimeContext
.waitForStop(0);
44 } catch (Exception e
) {
46 Runtime
.getRuntime().halt(1);
48 }, "Runtime shutdown"));
50 // TODO use args as well
51 String dataArea
= System
.getProperty(OsgiBoot
.PROP_OSGI_INSTANCE_AREA
);
52 String stateArea
= System
.getProperty(OsgiBoot
.PROP_OSGI_CONFIGURATION_AREA
);
53 String configArea
= System
.getProperty(OsgiBoot
.PROP_OSGI_SHARED_CONFIGURATION_AREA
);
55 if (configArea
!= null) {
56 Path configAreaPath
= Paths
.get(configArea
);
57 Path additionalSystemPropertiesPath
= configAreaPath
.resolve(FILE_SYSTEM_PROPERTIES
);
58 if (Files
.exists(additionalSystemPropertiesPath
)) {
59 Properties properties
= new Properties();
60 try (InputStream in
= Files
.newInputStream(additionalSystemPropertiesPath
)) {
62 } catch (IOException e
) {
63 logger
.log(Logger
.Level
.ERROR
,
64 "Cannot load additional system properties " + additionalSystemPropertiesPath
, e
);
67 for (Object key
: properties
.keySet()) {
68 String currentValue
= System
.getProperty(key
.toString());
69 String value
= properties
.getProperty(key
.toString());
70 if (currentValue
!= null) {
71 if (!Objects
.equals(value
, currentValue
))
72 logger
.log(Logger
.Level
.WARNING
, "System property " + key
+ " already set with value "
73 + currentValue
+ " instead of " + value
+ ". Ignoring new value.");
75 System
.setProperty(key
.toString(), value
);
76 logger
.log(Logger
.Level
.TRACE
, () -> "Added " + key
+ "=" + value
77 + " to system properties, from " + additionalSystemPropertiesPath
.getFileName());
80 ThinLoggerFinder
.reloadConfiguration();
84 Map
<String
, String
> config
= new HashMap
<>();
85 config
.put(PROP_ARGEO_INIT_MAIN
, "true");
87 // add OSGi system properties to the configuration
88 sysprops
: for (Object key
: new TreeMap
<>(System
.getProperties()).keySet()) {
89 String keyStr
= key
.toString();
91 case OsgiBoot
.PROP_OSGI_CONFIGURATION_AREA
:
92 case OsgiBoot
.PROP_OSGI_SHARED_CONFIGURATION_AREA
:
93 case OsgiBoot
.PROP_OSGI_INSTANCE_AREA
:
94 // we should already have dealt with those
99 if (keyStr
.startsWith("osgi.") || keyStr
.startsWith("org.osgi.") || keyStr
.startsWith("eclipse.")
100 || keyStr
.startsWith("org.eclipse.equinox.") || keyStr
.startsWith("felix.")) {
101 String value
= System
.getProperty(keyStr
);
102 config
.put(keyStr
, value
);
103 logger
.log(Logger
.Level
.TRACE
,
104 () -> "Added " + key
+ "=" + value
+ " to configuration, from system properties");
110 if (stateArea
!= null)
111 config
.put(OsgiBoot
.PROP_OSGI_CONFIGURATION_AREA
, stateArea
);
112 if (configArea
!= null)
113 config
.put(OsgiBoot
.PROP_OSGI_SHARED_CONFIGURATION_AREA
, configArea
);
114 if (dataArea
!= null)
115 config
.put(OsgiBoot
.PROP_OSGI_INSTANCE_AREA
, dataArea
);
116 // config.put(OsgiBoot.PROP_OSGI_USE_SYSTEM_PROPERTIES, "true");
118 OsgiRuntimeContext osgiRuntimeContext
= new OsgiRuntimeContext(config
);
119 osgiRuntimeContext
.run();
120 Service
.runtimeContext
= osgiRuntimeContext
;
121 Service
.runtimeContext
.waitForStop(0);
122 } catch (NoClassDefFoundError e
) {
123 StaticRuntimeContext staticRuntimeContext
= new StaticRuntimeContext((Map
<String
, String
>) config
);
124 staticRuntimeContext
.run();
125 Service
.runtimeContext
= staticRuntimeContext
;
126 Service
.runtimeContext
.waitForStop(0);
128 } catch (Exception e
) {
132 logger
.log(Logger
.Level
.DEBUG
, "Argeo Init stopped with PID " + pid
);
135 /** The root runtime context in this JVM. */
136 public static RuntimeContext
getRuntimeContext() {
137 return runtimeContext
;