1

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?

0 Answers0