Calling Method at the End of Program Execution - java

I am creating a client library for an API endpoint using Unirest to simulate GET and POST requests. Once the program finishes, the following code must be called in order to terminate the current thread.
Unirest.shutdown(); // must be called in order to clear the high CPU consuming thread
Is there any possible way implicitly call this in my client library at the end of the program's execution?

Yes - your best option is likely a Shutdown Hook. It will be called/executed when the JVM is terminating. As an example:
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
System.out.println("JVM shutting down, closing Unirest");
Unirest.shutdown();
}
}));
You should ideally call the addShutdownHook() method as soon as possible, after you have started the Unirest service.

Related

RMI Service run similar to sockets

So if I have a socket server, I can accept each socket and pass it to a executory
while(true){
Socket conn = socketServ.accept();
Runnable task = new Runnable() {
#Override
public void run() {
try{
server.executor(conn);
} catch(IOException e){
}
}
};
exec1.execute(task);
}
Doing this allows my server to run on my threads and does not block the same thread. Because I also have reference to that socket... called "conn" I can successfully return messages as well.
Now I have an RMI interface, which basically lets me call methods back and forth.
for example if I had this method:
public MusicServerResponseImpl CreatePlayerlist(String Name, UserObjectImpl uo) throws RemoteException {
MusicServerResponseImpl res = new MusicServerResponseImpl();
return res;
}
Which returns a serializable object. My concern is when this message gets called, I think it is going to get called in the main thread of the server, and thus will block that thread and slow down parallelism.
What I think is the solution is to have every single RMI method also create a task for an executor.. to speed up the execution of everything...this issue I am seeing however is unlike the socket where I have an object to send information back to, I am unsure how I would return a response from the RMI method, without somehow having to block the thread.
Does that make sense? Basically I am asking how I can execute in parallel with RMI methods while still being able to return results!
Thanks for the help!
Does that make sense?
No. Concurrent calls are natively supported.
See this documentation page and look for the property named maxConnectionThreads.
You could also have tested your assumptions by, for example, printing the current thread name in your server code, and trying to execute concurrent calls and see what happens.

JavaFX app using retrofit async request quitting very slowly

I'm developing a JavaFX app with Java 8 and for api requests I'm using retrofit 2.1.0 with converter-gson 2.1.0.
If I make the synchronous request:
Patient p = Core.api.getPatient(2).execute().body();
Everything works fine, but if I do the asynchronous version:
Core.api.getPatient(2).enqueue(new Callback<Patient>() {
#Override
public void onResponse(Call<Patient> call, Response<Patient> response) {
System.out.println("DONE");
}
#Override
public void onFailure(Call<Patient> call, Throwable t) {
// Nothing
}
});
Everything also works out correctly (it prints "DONE"). However when I quit the application using the standard JavaFX call Platform.exit() the UI closes but the application lingers open still and will only exit after ~40 seconds.
If I just do System.exit(0) everything works as intended so I'm guessing this might be some threading issue but I'm not sure.
Anyone have an idea on what might be wrong?
EDIT:
I found out that after doing Platform.exit() a few threads, with names like RMI TCP Connection(2) keep alternating and using 100% of the CPU.
OkHttp uses two thread pools that keep threads alive for 60 seconds after use. You can shut em down with force by calling shutdown on the dispatcher's executor and by calling evictAll on the connection pool.

How do you gracefully exit a Process in Java?

I am trying to make a Java program which will run several other unrelated Java programs, specifically a Minecraft server.
Currently, I am trying to work out how to end a java.lang.Process gracefully.
This is the code for my spawner program:
http://dl.dropbox.com/u/26746878/SpawnerSource/Main.java.txt
And this is the code for the program which is spawned:
http://dl.dropbox.com/u/26746878/SpawnerSource/Tester.java.txt
What I do is run my spawner program. Then, after a few seconds, I terminate it with Ctrl-C.
What I want to see is my program output 'Shutting Down' followed by 'Ending'. I also want to see a file 'test.txt'.
What I actually see is only 'Shutting Down', with no 'Ending' nor 'test.txt'
I believe the problem is that Process.destroy() is forcefully ending the process without letting the shutdown hooks run.
Is there an alternative to Process.destroy() which will exit the process gracefully (ie: as if I had pressed Ctrl-C)?
You should never destroy a working process as it might get the whole OS into an unstable state (believe me, this caused us 2 hours downtime and cost 10000$ to my company :( )
What you should do instead is as #Kane mentioned, send a shutdown request to all your child processes and wait until they are all finished (every child process sends an RMI notification back to the main process right before gracefully exiting)
class ParentProcess{
Map<int, CountDownLatch> finishSignals = new ConcurrentHashMap<int, CountDownLatch>();
public void startProcess(){
// Start child process
// get its ID
// and create a count down latch for it
finishSignals.add(processId, new CountDownLatch(1));
}
public void shutDownProcess(processId){
// Send an RMI request to process ID to shutdown
}
// RMI request sent from child process before stopping
public void processFinishedNotification(processId){
finishSignals[processId].countDown()
}
public void waitForChildsToFinish(){
// This for loop will block until all child processes have sent a finish notification
for(CountDownLatch childFinishSignal : finishSignals){
childFinishSignal.await();
}
}
}
You may want to look into Remote Method Invocation, and have your spawner process ask the child processes to shut themselves down instead of having the spawner process kill the child processes itself.

How to keep my program alive for as long a daemon thread is running?

I have a requirement, that I want to start a poller once which will run foreever until the machine is restarted or the process is being killed. Now, I tried to start the poller from a main method using a shell script, but the problem is that as soon as the main method completed its execution, the poller also stoped working, as i am not using any servers to achieve so.
I heard something about daemon threads, but I am wondering how to create a daemon thread, which will run forever, and help my poller to run also.
UPDATE:
public class SomeThread extends Thread {
#Override
public void run() {
UnitPoller unitPoller = new UnitPoller();
unitPoller.doPolling();
}
public static void main(String[] args) {
SomeThread someThread = new SomeThread();
someThread.setDaemon(true);
someThread.start();
}
}
Above is my updated class, now whenever I execute this thread from the main method, it creates a thread but as soon as the execution of main method completes, my poller stops working, as the JVM shuts down.
With this problem, what should i do.
Thanks
You just create a thread and call th.setDaemon(true) before calling th.start().
Edit:
The above answers the question "how to create a daemon thread", but (as the scope of the question has changed), a proper answer would be: don't create a daemon thread if you want your thread to keep the JVM from exiting once the main thread completed.
1) You need someThread.setDaemon(false) instead of 'true'. A daemon thread actualy does NOT stop java from shutting down.
From the javadoc:
void java.lang.Thread.setDaemon(boolean on)
Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.
This method must be called before the thread is started.
2) I think it's not your main, but your run() method that finishes to soon. Try to put a while (true) loop around your doPolling method.
#Override
public void run() {
UnitPoller unitPoller = new UnitPoller();
while (true)
unitPoller.doPolling();
}
3) It's cleaner to call join() inside the main then to rely on daemon thread behavior.
try {
someThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
4) If you need a clean way to shut down the deamonthread. Consider implementing InterruptedException to exit the polling task. You can also use the shutdown hook.
The term "daemon thread" in Java is a bit misleading, as it really means "that thread is not supposed to keep the JVM alive". This means that the JVM will shut down as soon as the last non-daemon thread terminated (as you already stated in your question).
What you are possibly looking for is the Apache Commons Daemon project, which allows to create nice "system services", started through /etc/init.d/ entries and all. This works on Windows and *nix systems.

How can I interrupt IMAP's IDLE?

I am using the Javamail API connecting to my IMAP server. Everything is working great with the javax.mail.Folder.idle() method. My listener gets called when a new mail comes in. However the problem is idle blocks forever, how do I interrupt it? How do I actually stop the listening without killing my Java program?
I've tried calling Thread.interrupt() on the idle'd thread. Nothing happens. I am running out of ideas.
Performing any operation on that folder (from another thread) will cause idle() method to return immediately. So if you want to forcefully interrupt it, just call close() from a new thread.
If you read the documentation properly, and read the source code, you'll realise that you have to create a new thread for calling .idle().
Allocate that thread to a variable, and whenever you want call the interrupt() on that thread, or just ignore notifications!
If you need to get idle() going again, just rerun the thread!
I created something similar, so you might wanna check it out.
https://github.com/mofirouz/JavaPushMail/blob/master/src/main/java/com/mofirouz/javapushmail/JavaPushMailAccount.java
Good luck
A proper way to abort IDLE command is the following snippet. Note that the Folder instance should be the same as the one used to start idling. I've tested the other solutions proposed on this thread but they didn't work in my case.
IMAPFolder folder = store.getFolder("INBOX");
try {
folder.doOptionalCommand("Abort IDLE error mesage", new IMAPFolder.ProtocolCommand() {
#Override
public Object doCommand(IMAPProtocol p) throws ProtocolException {
p.idleAbort();
return Boolean.TRUE;
}
});
} catch (MessagingException e) {
e.printStackTrace();
}

Categories