]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.init/src/org/argeo/init/Service.java
Releasing
[lgpl/argeo-commons.git] / org.argeo.init / src / org / argeo / init / Service.java
1 package org.argeo.init;
2
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;
10 import java.util.Map;
11 import java.util.Objects;
12 import java.util.Properties;
13 import java.util.TreeMap;
14
15 import org.argeo.init.logging.ThinLoggerFinder;
16 import org.argeo.init.osgi.OsgiBoot;
17 import org.argeo.init.osgi.OsgiRuntimeContext;
18
19 /** Configure and launch an Argeo service. */
20 public class Service {
21 private final static Logger logger = System.getLogger(Service.class.getName());
22
23 final static String FILE_SYSTEM_PROPERTIES = "system.properties";
24
25 public final static String PROP_ARGEO_INIT_MAIN = "argeo.init.main";
26
27 private static RuntimeContext runtimeContext = null;
28
29 protected Service(String[] args) {
30 }
31
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);
35
36 // shutdown on exit
37 Runtime.getRuntime().addShutdownHook(new Thread(() -> {
38 try {
39 if (Service.runtimeContext != null) {
40 // System.out.println("Argeo Init stopping with PID " + pid);
41 Service.runtimeContext.close();
42 Service.runtimeContext.waitForStop(0);
43 }
44 } catch (Exception e) {
45 e.printStackTrace();
46 Runtime.getRuntime().halt(1);
47 }
48 }, "Runtime shutdown"));
49
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);
54
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)) {
61 properties.load(in);
62 } catch (IOException e) {
63 logger.log(Logger.Level.ERROR,
64 "Cannot load additional system properties " + additionalSystemPropertiesPath, e);
65 }
66
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.");
74 } else {
75 System.setProperty(key.toString(), value);
76 logger.log(Logger.Level.TRACE, () -> "Added " + key + "=" + value
77 + " to system properties, from " + additionalSystemPropertiesPath.getFileName());
78 }
79 }
80 ThinLoggerFinder.reloadConfiguration();
81 }
82 }
83
84 Map<String, String> config = new HashMap<>();
85 config.put(PROP_ARGEO_INIT_MAIN, "true");
86
87 // add OSGi system properties to the configuration
88 sysprops: for (Object key : new TreeMap<>(System.getProperties()).keySet()) {
89 String keyStr = key.toString();
90 switch (keyStr) {
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
95 continue sysprops;
96 default:
97 }
98
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");
105 }
106 }
107
108 try {
109 try {
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");
117
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);
127 }
128 } catch (Exception e) {
129 e.printStackTrace();
130 System.exit(1);
131 }
132 logger.log(Logger.Level.DEBUG, "Argeo Init stopped with PID " + pid);
133 }
134
135 /** The root runtime context in this JVM. */
136 public static RuntimeContext getRuntimeContext() {
137 return runtimeContext;
138 }
139 }