Java create/overwrite http server

Skere :

I'm creating a plugin on a certain platform (the details are irrelevant) and need to create a HTTP endpoint. In normal circumstances you'd create a http server and stop it whenever you're done using it or when the application stops, however, in my case I can't detect when the plugin is being uninstalled/reinstalled.

The problem

When someone installs my plugin twice, the second time it will throw an error because I'm trying to create a http server on a port which is already in use. Since it's being reinstalled, I can't save the http server on some static variable either. In other words, I need to be able to stop a previously created http server without having any reference to it.

My attempt

I figured the only way to interact with the original reference to the http server would be to create a thread whenever the http server starts, and then overwrite the interrupt() method to stop the server, but somehow I'm still receiving the 'port is already in use' error. I'm using Undertow as my http server library, but this problem applies to any http server implementation.

import io.undertow.Undertow;
import io.undertow.util.Headers;

public class SomeServlet extends Thread {
    private static final String THREAD_NAME = "some-servlet-container-5391301";
    private static final int PORT = 5839;

    private Undertow server;

    public static void listen() { // this method is called whenever my plugin is installed
        deleteExistingServer();
        new SomeServlet().start();
    }

    private static void deleteExistingServer() {
        for (Thread t : Thread.getAllStackTraces().keySet()) {
            if (t.getName().equals(THREAD_NAME)) {
                t.interrupt();
            }
        }
    }

    @Override
    public void run() {
        createServer();
    }

    @Override
    public void interrupt() {
        try {
            System.out.println("INTERRUPT");
            this.server.stop();
        } finally {
            super.interrupt();
        }
    }

    private void createServer() {
        this.server = Undertow.builder()
            .addHttpListener(PORT, "localhost")
            .setHandler(exchange -> {
                exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
                exchange.getResponseSender().send("Hello World!");
            })
            .build();
        this.server.start();
    }
}

Desired behaviour

Whenever listen() is called, it will remove any previously existing http server and create a new one, without relying on storing the server on a static variable.

i.bondarenko :

You could try com.sun.net.httpserver.HttpServer. Use http://localhost:8765/stop to stop and 'http://localhost:8765/test' for test request:

import com.sun.net.httpserver.HttpServer;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;

public class TestHttpServer {
    public static void main(String[] args) throws IOException {
        final HttpServer server = HttpServer.create();
        server.bind(new InetSocketAddress(8765), 0);

        server.createContext("/test", httpExchange -> {
            String response = "<html>TEST!!!</html>";
            httpExchange.sendResponseHeaders(200, response.length());
            OutputStream os = httpExchange.getResponseBody();
            os.write(response.getBytes());
            os.close();
        });

        server.createContext("/stop", httpExchange -> server.stop(1));

        server.start();
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=165890&siteId=1