Stop jvm from commandline for gracefull shutdown - java

I am doing some Poc for Stilts stomp server. Need to prevent server jvm termination and do it through another jvm. Here is a code snippet
public static void main(String[] args) {
try {
log.debug("Starting server...");
StompServer<MockStompProvider> server = new StompServer<MockStompProvider>();
server.setStompProvider( new MockStompProvider() );
server.addConnector( new InsecureConnector() );
server.start();
while (true) {
Thread.sleep(200000);
}
} catch (Exception ex) {
log.error("Exception ", ex);
}
}
There are two requirements.
Is there any other way to prevent termination the above jvm without using while loop.
I would like to stop jvm using command like java -jar server.jar -- stop for example a server like jetty. Jetty use ports and listens for signal for stop request. Is there any simple way.
One option for second one can be using a AnchorFile, create file when start jvm and monitor for file existence and using stop jvm remove that file.

You could do this with ServerSocket
static final int PORT = Integer.getInteger("port", 65432);
public static void main(String[] args) {
if (args.length > 0) {
new Socket("localhost", PORT);
return;
}
try {
log.debug("Starting server...");
StompServer<MockStompProvider> server = new StompServer<MockStompProvider>();
server.setStompProvider( new MockStompProvider() );
server.addConnector( new InsecureConnector() );
server.start();
new ServerSocket(PORT).accept();
} catch (Exception ex) {
log.error("Exception ", ex);
}
}

Related

Jetty 11 with Jersey is not accepting requests

I am learning java web application and started with jetty and jersey for creating the rest api. I am following this article https://mkyong.com/webservices/jax-rs/jersey-and-jetty-http-server-examples/#start-jersey-jetty-application
By this, I am able to compile and run the server however it does not accept any requests. I tried telnet, curl and other things - I always get connection refused.
My MainApp.java looks like this
public class MainApp {
public static final String BASE_URI = "http://localhost:8080/";
public static Server startServer() {
// scan packages
// final ResourceConfig config = new ResourceConfig().packages("com.mkyong");
final ResourceConfig config = new ResourceConfig(Receiver.class); -- This is my resouce.
final Server server =
JettyHttpContainerFactory.createServer(URI.create(BASE_URI), config);
return server;
}
public static void main(String[] args) {
try {
final Server server = startServer();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
System.out.println("Shutting down the application...");
server.stop();
System.out.println("Done, exit.");
} catch (Exception e) {
Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, e);
}
}));
System.out.println(
String.format("Application started.%nStop the application using CTRL+C"));
// block and wait shut down signal, like CTRL+C
Thread.currentThread().join();
// alternative
// Thread.sleep(Long.MAX_VALUE); // sleep forever...
// Thread.sleep(Integer.MAX_VALUE); // sleep around 60+ years
} catch (InterruptedException ex) {
Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Am I missing any other configuration? Any help would be appreciated.

Java - Iterate through IP Address List and call thread with IP Address as argument

I'm relatively new to Java and I'm writing an application to interrogate an Apache HTTP server's access_log file; with this, I want to submit the IP Addresses individually (probably via the Apache HTTPClient library) to another Java instance on another server (as the Web server does not have FTP enabled) to pull some log files. At the moment I've managed to bumble my way through modifying a 'tail -f' equivalent class to suit the programs needs and then manipulate that data to get the IP Addresses that I need to do something with - I even managed to make the 'tail' class threaded so it could address multiple periods of time!
With that said, I want to use a for loop to iterate through each entry in my computerRebootList String Array and with each address create a thread to perform some more work but all I can think of is this;
for (String tmpIpAddress : computerRebootList ) {
ComputerIpHandler handler = new ComputerIpHandler();
}
and then create another class named ComputerIpHandler like so;
public class KioskIpHandler implements Runnable {
static final Logger logger = LogManager.getLogger( ComputerIpHandler.class );
#Override public void run() {
//do some code
}
public static void main(String computerIp) {
Thread mainThread = new Thread(new ComputerIpHandler());
mainThread.start();
try {
logger.info("log some stuff");
mainThread.join();
logger.info("yay it's done");
}
catch (InterruptedException errInterrupted) {
logger.error(errInterrupted.getMessage());
logger.error(errInterrupted.getStackTrace());
}
}
}
I read somewhere about ensuring that I need to manage resource limitations so I would have to create a maximum number of threads - arguably I could send something like 10 IPs to this class and then have the rest of the addresses 'queue' until the one has returned... I'm just not confident or fluent enough to be able to conceptualise these ideas.
EDIT: I omitted that I am restricted to Java 1.6 as this is the maximum compatible version of the JRE that we can use on this server - not sure if that hinders this effort somewhat...
Can anyone point me in the right direction?
Check ScheduledThreadPoolExecutor and ScheduledExecutorService classes in package java.util.concurrent in java API. Those and some other classes in that package would manage all resources for you. They are available in java since version 1.5
I recommend using Java's built in FTP connection platform to make a thread for continually receiving data on a specified port, until it receives a termination key.
Basically, one class will create a ServerSocket (open socket on server) and upon connection with another socket (the client socket) it would create a new thread for receiving information.
public class Server {
public ServerSocket ss;
public Socket clientSocket;
public Thread receiveingThread;
public BufferedReader inFromClient = null;
public boolean running = false;
public Server(int port) {
try {
ss = new ServerSocket(port);
startReceiving();
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void startReceiving() {
receiveingThread = new Thread("Recieve") {
public void run() {
String dataFromClient = new String("");
while (running) {
try {
inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
dataFromClient = inFromClient.readLine();
} catch (Exception e) {
e.printStackTrace();
}
if (dataFromClient.equals("TERMINATOR_KEY") {
stopRecieving();
}
else if(!dataFromClient.equals("")) {
//add item to array
}
}
}
};
receiveingThread.start();
}
public synchronized void stopReceiving() {
try {
running = false;
receivingThread.join();
ss.close();
clientSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}
public static void main(String[] args) {
new Server(yourPortHere);
}
}
then the client class would look something like:
public class Client {
public Socket socket;
public Thread send;
public Client(string serverPublicIP, int port) {
try {
socket = new Socket(serverPublicIP, port);
send("some IP address");
} catch (Exception e) {
e.printStackTrace();
}
}
public void send(String toSend) {
send = new Thread("Send") {
public void run() {
PrintWriter outToServer;
try {
outToServer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
outToServer.print(toSend);
outToServer.flush();
} catch (Exception e) {
e.printStackTrace();
}
finally {
outToServer.close();
}
}
};
send.start();
}
public static void main(String[] args) {
new Client("127.0.0.1", yourPortHere);
}
}
This is the link for the start of socket tutorials on the oracle site.
This is the Oracle Documentation for java.net.ServerSocket
This is the Oracle Documentation for java.net.Socket

how to check if javafx application is already running programatically?

i'm trying to run a javafx application from a thread outside the scope of the application class. Th problem i'm using a while loop to generate the application and it throws an illegalstatexception whenever it is called twice, so i need a way to distinguish if the application is already running to continue with my other tasks, any ideas?
Based on #nejinx 's answer, you have to do this when calling Application.launch():
try {
Application.launch(args);
} catch (IllegalStateException e) {}
That way, if the error happens, your program will just keep running and not try to start the application again.
public class MyServer implements Runnable{
public static final int PORT = 99 ;
private static ServerSocket serverSocket;
private Window window;
public MyServer(Stage window) throws AlreadyBoundException {
if(serverSocket!=null && !serverSocket.isClosed())
throw new AlreadyBoundException("The server is already running.");
this.window = window;
try( Socket clientSocket = new Socket("localhost", PORT);) {
Platform.exit();
} catch (IOException e) {
final Thread thread = new Thread(this);
thread.setDaemon(true);
int priority = thread.getPriority();
if(priority>Thread.MIN_PRIORITY)
thread.setPriority(--priority);
thread.start();
}
}
public void run() {
try {
serverSocket = new ServerSocket(PORT, 1);
while (true) {
Socket clientSocket = serverSocket.accept();
clientSocket.close();
Platform.runLater(()->window.requestFocus());
}
}catch (IOException e) {
System.out.println("Error in MyServer: " + e);
}
}
}
And in the JavaFX APP:
#Override
public void start(Stage stage) throws Exception {
// Start server
new MyServer(stage);
// ...
}
The only way you can do this is to catch the IllegalStateException
If you dig down into the JavaFX source code you see this:
if (launchCalled.getAndSet(true)) {
throw new IllegalStateException("Application launch must not be called more than once");
}

Handle incoming sockets in another thread

I'm trying to do something potentially stupid, but I reckon it's a good idea, so bear with me. I tried to implement it, but I hit an awkward issue with sockets closing between threads - so I want some fresh eyes on the case.
Scenario
I want to write an object from a Client to a Server via sockets. There may be more than one Client communicating with the Server concurrently.
The object, a Message, is handled by the Server through its handling mechanisms. It is proposed that instead of the Server's main thread looking out for new incoming connections, a Listener thread is set up. Once it spots an incoming connection, it alerts the Server, storing the socket in a queue without receiving the data, so it can go back to listening quickly.
In its own time, the Server picks up the waiting socket, spawns a new thread, reads the Message, and closes the socket.
The code
Here's my first thoughts on how this should be implemented. There is a fundamental flaw in it which I will explain below.
Ignore the use of public fields - I'm just trying to make the code short for you guys
public class Server {
public boolean messageWaiting = false;
public static void main(String[] args) {
new Server().run();
}
public void run() {
Listener l = new Listener();
l.listen(this);
try {
while (true) {
System.out.println("I'm happily doing my business!");
Thread.sleep(1000);
if (messageWaiting) {
acceptMessages(l);
}
}
} catch (InterruptedException die) {}
}
private void acceptMessages(Listener l) {
while (!l.waiting.isEmpty()) {
try (
Socket client = l.waiting.poll();
ObjectInputStream ois = new ObjectInputStream(client.getInputStream())
) {
// Handle messages in new threads! (or a thread pool)
new Thread() {
public void run() {
try {
System.out.println(ois.readObject());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}.start();
} catch (Exception ex) {
// Oh no! The socket has already been closed!
ex.printStackTrace();
}
}
}
}
public class Listener {
public ConcurrentLinkedQueue<Socket> waiting = new ConcurrentLinkedQueue<>();
public void listen(final Server callback) {
new Thread() {
public void run() {
try (ServerSocket rxSock = new ServerSocket(7500)) {
while (!isInterrupted()) {
try (Socket client = rxSock.accept()) {
// Once a new socket arrives, add it to the waiting queue
waiting.add(client);
// Alert the server
callback.messageWaiting = true;
} catch (IOException ex) {
ex.printStackTrace();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}.start();
}
}
public class Client {
public static void main(String[] args) {
try (
Socket txSock = new Socket(InetAddress.getLoopbackAddress(), 7500);
ObjectOutputStream oos = new ObjectOutputStream(txSock.getOutputStream())
) {
oos.writeObject("This is a Message, trust me.");
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
What's wrong with this?
This:
I'm happily doing my business!
I'm happily doing my business!
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Unknown Source)
at Server.acceptMessages(Server.java:30)
at Server.run(Server.java:20)
at Server.main(Server.java:9)
This is because the Java 7 try blocks I'm using close the sockets once they're finished. So why don't I do this manually? Try yourself - you end up with a warning saying you're only ever going to call close() on a null object!
So, how do I avoid the whole issue of my incoming socket being closed before the Server thread picks up on it? Or is this a bad idea anyway and I should do something else?
Your statement in Listener
try (Socket client = rxSock.accept()) { ...
Is a try-with-resources for the client socket. As soon as you add it to the queue and exit the try block, the socket gets auto-closed.

How can I re-spawn a thrift server in java after an exception?

I'm new to java and have written a small, but quite important, thrift service in java.
I've noticed that occasionally it'll stop serving without any error messages; it seems that the java process just dies, randomly, without a stack-trace or exception.
What would be the best way to ensure this process stays alive even after an error? Here's the main function, if it will help:
public static void main(String [] args) {
try {
MyAppServiceHandler handler = new MyAppServiceHandler();
MyApp.Processor processor = new MyApp.Processor(handler);
TServerTransport serverTransport = new TServerSocket(8080);
TServer server = null;
server = new TSimpleServer(processor, serverTransport);
System.out.println("Starting thrift server...");
server.serve();
}
catch (TTransportException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
}
I've changed to a better solution.
My main function in java looks like this:
public static void main(String [] args) {
try {
MyAppServiceHandler handler = new MyAppServiceHandler();
MyApp.Processor processor = new MyApp.Processor(handler);
TServerTransport serverTransport = new TServerSocket(8080);
TServer server = null;
server = new TSimpleServer(processor, serverTransport);
System.out.println("Starting thrift server...");
server.serve();
}
catch (TTransportException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
}
This leaves the sever to die, which goes against what I wanted from the original solution. However, the java process/server is now initiated from Supervisor which keeps an eye on the process and respawns it if it dies, whereas the original solution (to use a while loop) would keep the server alive but printing stack traces if there was a problem in connecting to the port, and those error messages would be missed.
if the call to serve is blocking you can do:
public static void main(String [] args) {
while(true){
try {
MyAppServiceHandler handler = new MyAppServiceHandler();
MyApp.Processor processor = new MyApp.Processor(handler);
TServerTransport serverTransport = new TServerSocket(8080);
TServer server = null;
server = new TSimpleServer(processor, serverTransport);
System.out.println("Starting thrift server...");
server.serve();
}
catch (TTransportException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
//do cleanup
}
}

Categories

Resources