Java doesn't seem to have any default way of catching process signals. I found out the jnr-posix module that I am willing to use, and this is what I wrote so far
package org.projectsanatan.restsanatan;
import java.io.File;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.projectsanatan.restsanatan.utils.ResourceUtils;
import jnr.constants.platform.Signal;
import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
import jnr.posix.SignalHandler;
import jnr.posix.util.DefaultPOSIXHandler;
public class Main {
private static RestSanatan sanatan;
public static void main(String[] args) throws Exception {
Options options = new Options();
options.addOption(new Option("h", "help", false, "Show this menu."));
options.addOption(new Option("c", "config", true, "Configuration file."));
CommandLineParser parser = new DefaultParser();
CommandLine cmd = null;
try {
cmd = parser.parse(options, args);
} catch (ParseException ex) {
System.out.printf("Parsing exception: %s%n", ex.getMessage());
System.exit(1);
}
SignalHandler shutdownHandler = new SignalHandler() {
@Override
public void handle(int signal) {
System.out.println("Received signal: " + signal);
sanatan.stop();
}
};
final POSIX posix = POSIXFactory.getPOSIX(new DefaultPOSIXHandler(), true);
posix.signal(Signal.SIGINT, shutdownHandler);
// posix.signal(Signal.SIGHUP, shutdownHandler);
// Command line options
if(cmd.hasOption("help")) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("RestSanatan", options);
System.exit(0);
}
final File cfg = new File(cmd.getOptionValue("c", "config.yaml"));
if(!cfg.exists()) ResourceUtils.extractResource(Main.class.getResourceAsStream("config.yaml"), cfg);
sanatan = new RestSanatan(cfg);
sanatan.start();
}
}
with my gradle build file
plugins {
id 'java'
id 'application'
id 'com.github.johnrengelman.shadow' version '7.1.2'
}
group 'org.projectsanatan.restsanatan'
version '0.7.0'
repositories {
mavenLocal()
mavenCentral()
}
ext {
javaMainClass = "org.projectsanatan.restsanatan.Main"
}
application {
mainClassName = javaMainClass
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
implementation 'org.eclipse.jetty:jetty-server:11.0.8'
implementation 'org.eclipse.jetty:jetty-servlet:11.0.8'
implementation 'org.eclipse.jetty:jetty-servlets:11.0.9'
implementation 'org.eclipse.jetty:jetty-util:11.0.8'
implementation 'es.moki.ratelimitj:ratelimitj-core:0.7.0'
implementation 'org.apache.logging.log4j:log4j-core:2.3.2'
implementation 'org.yaml:snakeyaml:1.30'
implementation 'com.google.guava:guava:31.0.1-jre'
implementation 'org.json:json:20211205'
implementation 'org.glassfish.jersey.core:jersey-server:3.0.4'
implementation 'org.glassfish.jersey.containers:jersey-container-servlet:3.0.4'
implementation 'org.glassfish.jersey.containers:jersey-container-jetty-http:3.0.4'
implementation 'org.glassfish.jersey.core:jersey-common:3.0.4'
implementation 'org.glassfish.jersey.inject:jersey-hk2:3.0.4'
implementation 'commons-cli:commons-cli:1.5.0'
implementation 'com.github.jnr:jnr-posix:3.1.15'
}
test {
useJUnitPlatform()
}
task copyJar(type: Copy) {
from "build/libs/RestSanatan-" + version + "-all.jar"
into "build"
}
build.finalizedBy() {
shadowJar
copyJar
}
It doesn't work. I run the jar, hit ctrl+c multiple times, it doesn't gracefully shutdown neither terminates the process, then I have to SIGKILL the process. I think I need some other dependency? What I am doing wrong?