Some of my users have been reporting IllegalThreadStateExceptions, which lead back to the following code. I was unable to recreate it, and most people are able to execute this part of the code with no issues.
The code is re-executed periodically, so the old thread should be replaced by a new one and started, but that's where the error occurs.
if (head.threadSeal != null)
{
head.threadSeal.interrupt();
}
head.threadSeal = new ThreadFindSeal();
head.threadSeal.start(); // IllegalThreadStateException here
Relevant stack trace:
java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:704)
Am I missing something in the documentation, why would start ever fail on a new thread?
The javadoc of Thread#start() states
Throws: IllegalThreadStateException - if the thread was already
started.
You haven't give much information, but the following could happen.
First thread executes
head.threadSeal = new ThreadFindSeal();
Second thread then executes
head.threadSeal = new ThreadFindSeal();
head.threadSeal.start();
replacing the Thread and starting it.
The first thread then executes
head.threadSeal.start();
which is called on the same Thread object as before, which was already started.
Related
Will an unhandled runtime exception stop the whole server (i.e. Spring Boot application) or just the specific HTTP request ?
It is true that an unhandled runtime exception will instantly shut down normal Java application, right ?
Will an unhandled runtime exception stop the whole server (i.e. Spring Boot application) or just the specific HTTP request ?
Just the current HTTP request ... assuming that the exception is thrown by the request thread. (If it is thrown by a child thread, it won't even terminate the HTTP request.)
It is true that an unhandled runtime exception will instantly shut down normal Java application, right?
Actually, not right.
An uncaught exception causes the thread on which it was thrown to terminate. In a simple Java application where there is only one (non-daemon) "main" thread, and an uncaught exception occurs on that thread, the JVM then exit because the last non-daemon thread has terminated.
But if there are other threads ... the uncaught exception doesn't stop the JVM.
To illustrate, run this program:
public class Test {
public static void main(String[] args) {
new Thread(() -> {
try {
Thread.sleep(10000);
} catch (Exception e) {
System.err.println("Caught " + e);
}
}).start();
throw new RuntimeException("Goodbye cruel world");
}
}
When you run this, you will observe that there is a 10 second delay between the stacktrace printing (from the uncaught exception in main) and the program actually ending. The JVM is waiting for the child thread to terminate.
This could also indirectly answer your main question ... except:
We don't know for sure if the request threads are daemon threads or not.
We don't know for sure that the request threads are not actually catching / handling the exceptions thrown by your request processing code.
Suffice it to say that a framework will typically do something sensible depending one what the thrown exception is. For example, a framework might handle Error exceptions on a worker thread by attempting a shutdown ... on the basis that the error may have put the JVM into a potentially unsafe / non-recoverable state.
Just the thread in question
An unhandled RuntimeException will kill the thread, not the application. Usually each HTTP request is handled by its own thread, so nothing else in the server should be affected. I don’t know how the server handles the dead thread. A wise move would probably be creating a new thread for upcoming requests.
Only when all threads (except so-called demon threads) are terminated, will your Spring Boot application stop. This in turn means that in an application that isn’t threaded — one that has everything running in the main thread — an uncaught exception (RuntimeException or some other type) will bring the whole program down.
In most applications it matters which thread is killed. Your application probably has more threads handling HTTP requests and can spawn new ones as needed. In this case a thread death will hardly be noticed except by the user having sent this HTTP request. Other threads are probably more vital to the functioning of the server, and such a thread being killed, while not stopping the server completely, will stop it from working properly. For a different example, if the event dispatching thread in a desktop application is killed by an exception, the application can no longer accept user input.
Try it out for yourself
It doesn’t take a lot to try it out. The following program spawns a thread that throws an unhandled exception.
public class DemoUnhandledException {
public static void main(String[] args) throws InterruptedException {
new Thread(() -> { throw new RuntimeException("Demo"); }).start();
TimeUnit.MINUTES.sleep(1);
System.out.println("A minute later the main thread is still alive and well");
}
}
Let the program run for a full minute to get the full output, which is:
Exception in thread "Thread-0" java.lang.RuntimeException: Demo
at ovv.so.exception.DemoUnhandledException.lambda$0(DemoUnhandledException.java:8)
at java.base/java.lang.Thread.run(Thread.java:834)
A minute later the main thread is still alive and well
Link
How uncaught exceptions are handled in Java on Javamex
Will an unhandled runtime exception stop the whole server (i.e. Spring Boot application) or just the specific HTTP request ?
There is usually a thread pool in web server to handle all requests(e.g tomcat). Uncaught exceptions that occur in your controller will eventually be caught somewhere, so it will not cause the worker thread in the thread pool to be killed.
Tomcat#AbstractEndpoint#processSocket:
Executor executor = getExecutor();
if (dispatch && executor != null) {
// handle request in thread poll
executor.execute(sc);
}
I did a simple debug. Assuming that an unhandle exception occurred in your controller, then the exception was actually caught by FrameworkServlet#processRequest. After the capture, it will be wrapped into a NestedServletException and continue to be thrown to the upper layer. Eventually, it will be caught and printed in StandardWrapperValve#invoke.
I'm developing an Android App in Java. I used a lot of library: firebase crashlytics, SQLCipher, ButterKnife etc.. The problem is: when I run the app from Android Studio, I notice the app still remain active as process, even if I close all activities. I know that there are some thread that works on background.. but I don't know how to check which thread is active, and more important, what does it do. Any idea about?
You can get what state a thread is in by using the getState() method which returns an Enum of Thread.States. A thread can only be in one of the following states at a given point in time.
NEW A Fresh thread that has not yet started to execute.
RUNNABLE A thread that is executing in the Java virtual machine.
BLOCKED A thread that is blocked waiting for a monitor lock.
WAITING A thread that is wating to be notified by another thread.
TIMED_WAITING A thread that is wating to be notified by another thread for a specific amount of time.
TERMINATED A thread whos run method has ended.
Thread t = new Thread();
Thread.State e = t.getState();
Thread.State[] ts = e.values();
for(int i = 0; i < ts.length; i++){
System.out.println(ts[i]);
}
To kill the thread , u can do this :
myService.getThread().interrupt();
NOTE : the method Thread.stop() is deprecated
EDIT : : try this
public void stopThread(){
if(myService.getThread()!=null){
myService.getThread().interrupt();
myService.setThread(null);
}
}
I get this error in the log file while thread is running, i don't know where this error occurs since the threads didn't stop and process data with no issues and only my problem that this error appears multiple times in the log file
java.util.concurrent.RejectedExecutionException: Task
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask#419a9977
rejected from
java.util.concurrent.ScheduledThreadPoolExecutor#2522cdb9[Terminated,
pool size = 0, active threads = 0, queued tasks = 0, completed tasks =
2123929]
I did some research, i found that in some places i shutdown the task, but that did not happen at all.
Without looking at the code we can't really inform you more about the problem. If you look at the exception then it clearly states that the threads have been terminated and their active count is zero. It seems even after shutting down the executor you are trying to process more code using executors. Are you trying to add more task after the call executor.shutdown()
As per docs, New tasks submitted in method execute(Runnable) will be rejected when the Executor has been shut down, and also when the Executor uses finite bounds for both maximum threads and work queue capacity, and is saturated. In either case, the execute method invokes the RejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor) method of its RejectedExecutionHandler.
Look at the doc here: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html
Old question, but I had the issue and the comment of #lambad saves my day. I had this piece of code:
ttlExecutorService.schedule(new Runnable() {
public void run() {
...
...
...
}
}, 1, TimeUnit.MINUTES);
ttlExecutorService.shutdown();
I removed the shutdown call and exception was no longer thrown
Is it possible to recover java thread by doing the next?
Thread.setDefaultExceptionHandler(new UncaughtExceptionHandler() {
public void unchaughtException(Thread t, Throwable e) {
t.start();
}
});
Yes it is possible to run a Thread in a Thread.UncaughtExceptionHandler.uncaughtException ... provided that the Thread hasn't been started previously.
But it is NOT possible to start the Thread that was pass as the t argument. That will (always) be a Thread that has already been started and has terminated.
You can start a given Thread at most once. If you try to start one a second time you will get an InvalidStateException. Always.
No, you cannot run the thread that threw the exception, as shown in your code. It has already run. That's how it threw the exception. A thread cannot be started more than once.
I am trying to execute my SOAPUI test suites through a Java app rather than on the UI. However, when creating a WSDLProject a thread is starting that never gets killed, so when my code is executed and all the tests are run, the app doesnt end as this thread is still sitting there.
It looks like an AWT Daemon Thread
In the Eclipse Debugger:
Daemon Thread [AWT-Windows] (Running)
Here is my code:
WsdlProject projectName = String.format(
"src/main/resources/%s-soapui-project.xml", projectName);
WsdlProject project = new WsdlProject(projectName); //This line starts the thread
List<TestSuite> testSuites = project.getTestSuiteList();
//Loop over each testsuite
//Loop over each test case
Does anyone know how to kill this thread?
Ive searched and searched the SOAPUI API, but the documentation is terrible and I cant find any decent examples of how to approach this.
For the past two days I have been struggling with the same problem. I have a solution which may help. The reason your does not end is not the AWT-Windows thread. The culprit is the thread labeled "Thread-2" which is of type SoapUIMultiThreadedHttpConnectionManager.IdleConnectionMonitorThread
Unfortunately this thread which is created when you instantiate WsdlProject, has no directly accessible shutdown method. This is what I had to do in-order to shut it down and have the JVM exit when my main routine exits:
Have your main method or some other method execute the following at the end:
// Need to shutdown all the threads invoked by each SoapUI TestSuite
SoapUI.getThreadPool().shutdown();
try {
SoapUI.getThreadPool().awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Now to shutdown the monitor thread setup by SoapUI
Thread[] tarray = new Thread[Thread.activeCount()];
Thread.enumerate(tarray);
for (Thread t : tarray) {
if (t instanceof SoapUIMultiThreadedHttpConnectionManager.IdleConnectionMonitorThread) {
((SoapUIMultiThreadedHttpConnectionManager.IdleConnectionMonitorThread) t)
.shutdown();
}
}
// Finally Shutdown SoapUI itself.
SoapUI.shutdown();
Although ugly, I hope this solution helps you.
I have fixed this with the following solution. It is not ideal but I could not find a way round this and the SOAP UI documentation is incredibly painful.
Firstly, I save the results of each test step to an xml file.
Next, once the tests have run I exit:
System.exit(runner.getOverallResult() ? 0 : 1);
Finally, another app executes this through a command line .sh script. After executing it the other app reads the XML file to determine the results.