Skip to content

Commit a0559cb

Browse files
committed
✨ update --fork startup option implementation with Process API
#548
1 parent dcf9da3 commit a0559cb

File tree

8 files changed

+47
-61
lines changed

8 files changed

+47
-61
lines changed

Diff for: core/pom.xml

-13
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,6 @@
3737
<groupId>org.restheart</groupId>
3838
<artifactId>restheart-commons</artifactId>
3939
</dependency>
40-
<dependency>
41-
<groupId>org.kohsuke</groupId>
42-
<artifactId>akuma</artifactId>
43-
<!-- Will be removed due to https://github.com/SoftInstigate/restheart/issues/548
44-
When done, also remove <Enable-Native-Access>ALL-UNNAMED</Enable-Native-Access> in maven-jar-plugin configuration
45-
-->
46-
</dependency>
47-
<dependency>
48-
<groupId>net.java.dev.jna</groupId>
49-
<artifactId>jna</artifactId>
50-
</dependency>
5140
<dependency>
5241
<groupId>io.github.classgraph</groupId>
5342
<artifactId>classgraph</artifactId>
@@ -192,8 +181,6 @@
192181
</manifest>
193182
<manifestEntries>
194183
<Build-Time>${maven.build.timestamp}</Build-Time>
195-
<!-- akuma required JNA that logs warnings with Java 24. The following avoids it: -->
196-
<Enable-Native-Access>ALL-UNNAMED</Enable-Native-Access>
197184
</manifestEntries>
198185
</archive>
199186
</configuration>

Diff for: core/src/main/java/org/restheart/Bootstrapper.java

+1-6
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ private static void run() {
247247
System.exit(-1);
248248
}
249249

250-
// RHSecDaemon only works on POSIX OSes
250+
// RESTHeartDaemon only works on POSIX OSes
251251
final boolean isPosix = FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
252252

253253
if (!isPosix) {
@@ -257,7 +257,6 @@ private static void run() {
257257
var d = new RESTHeartDaemon();
258258
if (d.isDaemonized()) {
259259
try {
260-
d.init();
261260
initLogging(configuration, d, IS_FORKED);
262261
} catch (Exception t) {
263262
logErrorAndExit("Error staring forked process", t, false, false, -1);
@@ -827,10 +826,6 @@ private static void plugProxies(final Configuration conf, final Set<PluginRecord
827826
* plug the static resources specified in the configuration file
828827
*
829828
* @param conf
830-
* @param pathHandler
831-
* @param authenticationMechanism
832-
* @param identityManager
833-
* @param accessManager
834829
*/
835830
private static void plugStaticResourcesHandlers(final Configuration conf) {
836831
if (conf.getStaticResources() == null || conf.getStaticResources().isEmpty()) {

Diff for: core/src/main/java/org/restheart/Shutdowner.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121
package org.restheart;
2222

23-
import com.sun.akuma.CLibrary;
23+
import java.io.IOException;
2424
import java.nio.file.Path;
2525

2626
import org.restheart.configuration.Configuration;
@@ -80,7 +80,8 @@ protected static void shutdown(final String[] args) {
8080
LOGGER.info("Pid file {}", pidFilePath);
8181
}
8282

83-
CLibrary.LIBC.kill(pid, 15); // 15 is SIGTERM
83+
// destroy process
84+
ProcessHandle.of(pid).ifPresent(ProcessHandle::destroy);
8485

8586
LOGGER.info("SIGTERM signal sent to RESTHeart instance with pid {} ", pid);
8687

Diff for: core/src/main/java/org/restheart/utils/FileUtils.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
*/
2121
package org.restheart.utils;
2222

23-
import static com.sun.akuma.CLibrary.LIBC;
2423
import java.io.BufferedReader;
2524
import java.io.File;
2625
import java.io.FileNotFoundException;
@@ -129,7 +128,7 @@ public static void createPidFile(Path pidFile) {
129128
throw new IllegalStateException("createPidFile() is not supported on Windows.");
130129
}
131130
try (FileWriter fw = new FileWriter(pidFile.toFile())) {
132-
fw.write(String.valueOf(LIBC.getpid()));
131+
fw.write(String.valueOf(ProcessHandle.current().pid()));
133132
} catch (IOException e) {
134133
LOGGER.warn("error writing pid file", e);
135134
}

Diff for: core/src/main/java/org/restheart/utils/RESTHeartDaemon.java

+42-18
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,22 @@
2020
*/
2121
package org.restheart.utils;
2222

23+
import org.restheart.graal.ImageInfo;
24+
import org.slf4j.Logger;
25+
import org.slf4j.LoggerFactory;
26+
27+
import java.io.File;
28+
import java.util.ArrayList;
29+
import java.util.Arrays;
30+
import java.util.HashMap;
31+
import java.util.LinkedList;
32+
2333
/**
2434
* utility class to help daemonizing process
2535
*
26-
* See<a href="http://akuma.kohsuke.org">Akuma</a>
2736
* @author Andrea Di Cesare {@literal <[email protected]>}
2837
*/
29-
import com.sun.akuma.Daemon;
30-
import com.sun.akuma.JavaVMArguments;
31-
32-
import org.restheart.graal.ImageInfo;
33-
import org.slf4j.Logger;
34-
import org.slf4j.LoggerFactory;
35-
36-
public class RESTHeartDaemon extends Daemon {
38+
public class RESTHeartDaemon {
3739

3840
private static final Logger LOGGER = LoggerFactory.getLogger(RESTHeartDaemon.class);
3941

@@ -43,7 +45,6 @@ public class RESTHeartDaemon extends Daemon {
4345
*
4446
* @return
4547
*/
46-
@Override
4748
public boolean isDaemonized() {
4849
return System.getProperty(RESTHeartDaemon.class.getName()) != null;
4950
}
@@ -52,7 +53,6 @@ public boolean isDaemonized() {
5253
* Relaunches the JVM as a daemon.
5354
*
5455
*/
55-
@Override
5656
public void daemonize() {
5757
if (isDaemonized()) {
5858
throw new IllegalStateException("Already running as a daemon");
@@ -61,19 +61,43 @@ public void daemonize() {
6161
try {
6262
LOGGER.info("Forking...");
6363

64-
var args = JavaVMArguments.current();
65-
args.setSystemProperty(RESTHeartDaemon.class.getName(), "daemonized");
64+
var processInfo = ProcessHandle.current().info();
65+
var __args = processInfo.arguments();
6666

67-
String _args[] = args.toArray(new String[0]);
67+
var args = new LinkedList<>(Arrays.asList(__args.orElseGet(() -> new String[0])));
6868

69+
LOGGER.info("args: {}", (Object) args);
70+
71+
if (processInfo.command().isEmpty()) {
72+
throw new IllegalStateException("Command not available");
73+
}
74+
75+
var command = processInfo.command().get();
76+
77+
// add system property to identify daemon process
78+
args.addFirst("-D".concat(RESTHeartDaemon.class.getName()).concat("=daemonized"));
79+
80+
// create child process
6981
if (isExecutable()) {
70-
_args[0] = FileUtils.getFileAbsolutePath(_args[0]).toString();
82+
args.addFirst(FileUtils.getFileAbsolutePath(command).toString());
7183
} else {
72-
_args[0] = getCurrentExecutable();
84+
args.addFirst(command);
7385
}
7486

75-
// create child process
76-
var p = new ProcessBuilder().command(_args).start();
87+
LOGGER.info("newArgs: {}", args);
88+
89+
var p = new ProcessBuilder()
90+
.command(args.toArray(new String[0]))
91+
.directory(new File(System.getProperty("user.dir")))
92+
.inheritIO()
93+
.redirectOutput(ProcessBuilder.Redirect.DISCARD)
94+
.redirectError(ProcessBuilder.Redirect.DISCARD)
95+
.start();
96+
97+
// disconnect std io
98+
p.getInputStream().close();
99+
p.getOutputStream().close();
100+
p.getErrorStream().close();
77101

78102
LOGGER.info("Forked process: {}", p.pid());
79103
// parent exists

Diff for: core/src/main/resources/META-INF/native-image/org.restheart/restheart-core/proxy-config.json

-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
[
2-
{
3-
"interfaces":["com.sun.akuma.CLibrary"]
4-
},
52
{
63
"interfaces":["java.security.PrivilegedAction"]
74
},

Diff for: core/src/main/resources/META-INF/native-image/org.restheart/restheart-core/reflect-config.json

-7
Original file line numberDiff line numberDiff line change
@@ -286,13 +286,6 @@
286286
"allDeclaredMethods":true,
287287
"allDeclaredConstructors":true
288288
},
289-
{
290-
"name":"com.sun.akuma.CLibrary",
291-
"methods":[
292-
{"name":"execv","parameterTypes":["java.lang.String","com.sun.jna.StringArray"] },
293-
{"name":"readlink","parameterTypes":["java.lang.String","com.sun.jna.Memory","com.sun.jna.NativeLong"] }
294-
]
295-
},
296289
{
297290
"name":"com.sun.crypto.provider.AESCipher$General",
298291
"methods":[{"name":"<init>","parameterTypes":[] }]

Diff for: pom.xml

-10
Original file line numberDiff line numberDiff line change
@@ -272,16 +272,6 @@
272272
<artifactId>slf4j-api</artifactId>
273273
<version>2.0.17</version>
274274
</dependency>
275-
<dependency>
276-
<groupId>org.kohsuke</groupId>
277-
<artifactId>akuma</artifactId>
278-
<version>1.10</version>
279-
</dependency>
280-
<dependency>
281-
<groupId>net.java.dev.jna</groupId>
282-
<artifactId>jna</artifactId>
283-
<version>5.16.0</version>
284-
</dependency>
285275
<dependency>
286276
<groupId>org.fusesource.jansi</groupId>
287277
<artifactId>jansi</artifactId>

0 commit comments

Comments
 (0)