I have a JSF2 project with Spring. It is developed on eclipse with tomcat attached to it. It is pretty straight forward and mostly with default settings.
But, we have a few background threads that look like this:
public class CrawlingServiceImpl implements CrawlingService, InitializingBean{
private final Runnable crawlingRunnable = new Runnable() {
#Override
public void run() {
//...
}
};
public void startCrawling() {
crawlingThread = new Thread(crawlingRunnable);
crawlingThread.start();
}
public void stopCrawling(){
if ( crawlingThread!=null )
crawlingThread.interrupt();
crawlingThread = null;
}
#Override
public void afterPropertiesSet() throws Exception {
startCrawling();
}
public void destroy(){
stopCrawling();
}
}
Here's who's calling the destroy() method:
<bean
id="crawlingService"
class="com.berggi.myjane.service.CrawlingServiceImpl"
autowire="byName"
scope="singleton"
destroy-method="destroy"/>
I know that there is a better way all this to be done. But this is not my code and I don't want to rewrite it.
My problem is the following:
When I change a class (every single time) or when I change an xhtml file (very rarely) the server attempts to reload it, but it fails with the following errors:
INFO: Illegal access: this web application instance has been stopped already. Could not load org.apache.xml.dtm.ref.DTMManagerDefault. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1562)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1521)
at org.apache.xml.dtm.ObjectFactory.findProviderClass(ObjectFactory.java:508)
...
at package.CrawlingServiceImpl.crawl(CrawlingServiceImpl.java:92)
at package.CrawlingServiceImpl$1.run(CrawlingServiceImpl.java:39)
at java.lang.Thread.run(Thread.java:680)
Note: Check the stacktrace. There are a lot of these exceptions.
Then there are more exceptions for a missing jdbc driver which is absolutely fine.
Any ideas?
are you sure crawlingThread.interrupt(); is killing the running of the Thread.
Without seeing the code of run(). it looks like it probably has a method called crawl and it does 1 of 2 things
1) a loop which expects a boolean variable to stop it running, and some possible sleeps/waits. I see an interupt, but no boolean being set to terminate the threads loop.
2) it runs once (no loop) and when finished dies - however, I don't see how the interupt will help here.
Assigning the Thread variable to null will not help to kill the thread.
if you want a quick fix, you could try set the thread to a daemon thread to allow it to be terminated.
private final Runnable crawlingRunnable = new Runnable() {
{
setDaemon(true);
}
#Override
public void run() {
//...
}
};
//...
}
But without the code, I'd guess the thread is refusing to die properly due to either issue 1 or 2.
Related
I created my own thread class implementing the Runnable interface. But every time I start running my own thread class as a new thread, the main class thread does not terminate anymore by itself. Is this just an issue within Eclipse or would I also have problem running this on a Server? Do I have to change something calling the thread so that the main method can terminate properly?
Here's my basic self-made thread:
public class OwnThread implements Runnable {
#Override
public void run() {
//do something
}
}
Here's the main class that won't terminate anymore:
public static void main(String[] args) {
Thread thread = new Thread(new OwnThread());
thread.start();
}
When I debug it, the last called method is the exit()-method of the Thread-class. After going through these lines of code, the process goes on forever:
/**
* This method is called by the system to give a Thread
* a chance to clean up before it actually exits.
*/
private void exit() {
if (group != null) {
group.threadTerminated(this);
group = null;
}
/* Aggressively null out all reference fields: see bug 4006245 */
target = null;
/* Speed the release of some of these resources */
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
Here's a screenshot of the thread that is running forever. The TestInterface class is where the main-method is located:
But every time I start running my own thread class as a new thread, the main class thread does not terminate anymore by itself.
This is somewhat wrong. Your program does not terminate because there exists at least one non-daemon thread that still is running. The rule is: A Java program is terminated if all non-daemon threads are terminated.
I modified your program to make this behavior clear:
public class OwnThread implements Runnable {
#Override
public void run() {
runForever();
}
public static void main(String[] args) {
Thread thread = new Thread(new OwnThread());
thread.start();
runForever();
}
private static void runForever() {
while (true) {}
}
}
Running that will create two threads that will run forever. One is the main thread which is started by running the program, and the other is the thread started inside the main method:
Modifying the above code by removing the call to runForever in the main method ...
public static void main(String[] args) {
Thread thread = new Thread(new OwnThread());
thread.start();
}
... will result in a different thread picture:
Here the main thread is gone because it is terminated. But the other started thread is still running.
Side note: Suddenly another thread appears - DestroyJavaVM. Have a look at the post DestroyJavaVM thread ALWAYS running for more information.
The issue is indeed not caused by the multithreading logic itself, it is caused by Eclipse and the respective JVM. Running the exact same code in Netbeans or on an Tomcat 8 Server did not lead to any problems. A reinstallation of Eclipse did not solve the malfunction within the Eclipse framework, but having the certainty that the issue does not cause any trouble on a server is sufficient for me to close the case.
Thanks to Seelenvirtuose for the hints and his effort.
The following code is taken from an example in the Jersey project. See here.
public class App {
private static final URI BASE_URI = URI.create("http://localhost:8080/base/");
public static final String ROOT_PATH = "helloworld";
public static void main(String[] args) {
try {
System.out.println("\"Hello World\" Jersey Example App");
final ResourceConfig resourceConfig = new ResourceConfig(HelloWorldResource.class);
final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI, resourceConfig, false);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
server.shutdownNow();
}
}));
server.start();
System.out.println(String.format("Application started.\nTry out %s%s\nStop the application using CTRL+C",
BASE_URI, ROOT_PATH));
//////////////////////////////
Thread.currentThread().join();
//////////////////////////////
} catch (IOException | InterruptedException ex) {
//
}
}
}
I understand what is going on apart from the use of Thread.currentThread().join();.
I'm a Java newbie and my understanding is that this will block the execution of the current thread (in this case, the main thread), and effectively deadlock it. i.e. it will cause the current (main) thread to block until the current (main) thread finishes, which will never happen.
Is this correct? If so, why is it there?
Thread.currentThread().join() blocks the current thread forever. In your example, that prevents the main from exiting, unless the program is killed, e.g. with CTRL+C on Windows.
Without that line, the main method would exit right after the server is started.
An alternative would have been to use Thread.sleep(Long.MAX_VALUE);.
It's a common misunderstanding that if the main thread exits, the program will exit.
This is only true if there is no non-daemon thread running. This may be true here, but usually it is better IMHO to make the background threads this main is "waiting" for non-dameon and let the main thread exit when it doesn't have anything to do. I have see developers put Thread.sleep() wrapped in an infinite loop. etc.
It's an example. It's just not a very good one.
They're trying to show you how to make a thread that runs forever.
Thread.currentThread().join(); is a statement that takes forever to complete. You're supposed to replace it with your own code that runs forever and, presumeably does something useful.
Okay I'm sure I'm missing something simple here but can't see it. I'm using a flag to end a thread and then joining it to clean up neatly, but the join never finishes it just gets stuck waiting. There is currently nothing in the thread's run loop so it isn't getting stuck in a separate loop.
Thread:
package com.nox.willywars;
public class GameThread extends Thread {
//{{Variables
private boolean running;
//}}
//{{Getters/Setters
public void setRunning(boolean running) {
this.running = running;
}
//}}
//{{Constructor
public GameThread() {
running = false;
}
//}}Constructor
//{{Public methods
#Override
public void run() {
while(running) {
///...CODE GO HERE
}
}
public boolean isRunning() {
return running;
}
//}}
}
Code that fails to stop it:
//{{Lifecycle methods
#Override
public void create() {
//LOAD! Probably debug temp
TileFactory.load();
mapScreen = new MapScreen();
setScreen(mapScreen);
gameThread = new GameThread();
gameThread.setRunning(true);
gameThread.start();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
killGameThread();
}
private void killGameThread() {
if(gameThread != null) {
if(gameThread.isAlive() && gameThread.isRunning()) {
gameThread.setRunning(false);
boolean retry = true;
while(retry) {
try {
gameThread.interrupt();
gameThread.join();
retry = false;
} catch (InterruptedException e) {}
}
}
gameThread = null;
}
}
//}}
Currently it reaches gameThread.join() and gets stuck there, waiting for the thread to finish. Am I missing something here? As I understand the thread should finish once running is set to false and then joining should happen normally because it's already stopped.
Edit: Added some more code from the class that runs GameThread. Pause() is where KillGameThread is executed. I've made running volatile but it's had no effect.
I found another weird symptom too: Some people suggested looking at what's inside GameThread when it's stuck, so I went into the debugger. While join() is stuck I suspended the GameThread thread and saw it was on while(running), and running was definitely false. Then when I stepped over the code it exited the loop and finished correctly, seemingly caused by my debugging. It's as if the thread is somehow suspended?
first set the running flag as volatile
private volatile boolean running;
What does game thread do exactly, maybe it has blocked by some I/O operation.
and if the game thread doesn't sleep/wait/join, so interrupting it is useless.
you need to share the game thread code.
As user2511414 pointed out, try with using volatile. In short, this will make sure the value od running is always accessed directly and not cached.
It setting volatile won't solve the situation, he problem most probably lays in the code section of a GameThread#run method that you commented out.
You can try using jstack or jvisualvm to get a Thread Dump of the thread you're trying to join.
This will at least show you where is it hanging, and may lead you to a solution.
The running flag is not properly synchronised. This could (in theory) result in the thread not noticing the state change ... due to the way that the Java memory model works. You should either declare it as volatile or always access and update it in synchronized method calls (or synchronized blocks).
But (IMO) the real problem is in the way (actually the ways) that you are telling the thread to stop, and haw the thread is checking or responding.
If you are going to use a flag to tell the thread to stop, then the thread needs to check that flag frequently. If the thread could spend an indefinitely long amount of time doing something else between the checks, then it may never notice that it needs to stop.
If you are going to use Thread.interrupt() then:
Your code should be calling Thread.isInterrupted() to test the thread's "interrupted" status instead of an ad-hoc flag. Furthermore, it should be testing the status regularly.
Your code need to make sure that it handles the InterruptedException and InterruptedIOException properly. This applies all the way up the call stack.
Note that calling Thread.interrupt() doesn't actually interrupt the thread in most cases. In most cases, it just sets a flag that needs to be tested manually. The only cases you get more than that is in certain blocking calls; e.g. Object.wait(...) and some IO calls.
You've left out most of the code where these things ought to happen. The best we can say is that the problem is most likely in code you haven't shown us.
I'm trying to create a simple thread that started from a Button but something went wrong.
Here is the code:
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
SendInfo si = new SendInfo();
si.start();
error.setText(si.getError());
}
});
And here is the the thread code:
package com.example.android.location;
public class SendInfo extends Thread
{
private String error;
public void run()
{
this.error = "working";
}
public String getError(){
return this.error;
}
}
For some reason the error instance in the first code block stays empty.
You have a race.
After the start() call either:
1) your code continues and getError returns null and AFTER that the thread runs.
or
2) the thread runs AND finishes and getErrorwill return "working".
In your case 1) is happening.
Update: actually in theory during option 2 you might not get "working" anyway as the return value. This is due to memory/thread visibility. Synchronizing access to the error variable or in this case just declaring that field volatile fixes that (but not your original problem).
You should better use ASyncTask than Thread.
There's no guarantee that the thread started after this line
si.start();
so you can't just get error in hope that it's set as expected. Your thread didn't by the looks of it.
Also, it would be wise to synchronize on the method, to prevent nasty reordering of instructions.
One solution to this problem as a whole, is to create a handler on main thread and send a message to it once your thread completes execution.
I have made a java program with GUI and I want a stop button functionality in which when a user clicks on the stop button, the program must be stopped.
In my program, the main thread starts other 10 threads and I want that whenever the stop button has been clicked all the 10 threads must be stopped before the main thread.
Second, I also want that whenever any thread of those 10 threads is stopped, it must first close all the resources it had opened before like connection to a database etc.
I have implemented the code as answered by ........
Now there is one problem.
My thread class is like this:
public class ParserThread implements Runnable {
private volatile boolean stopped = false;
public void stopTheThread() {
stopped = true;
}
:
:
}
And below is the main thread that starts 10 threads from the function start()
public class Main() {
Thread [] threads;
public void start() {
for(int i = 0; i < 10; i++) {
threads[i] = new Thread(new ParserThread());
}
}
public void stop() {
// code to stop all the threads
}
}
Now I want to call the stop method of the ParserThread to set "stopped = true" to stop the thread. I want this thing to be done for all the 10 threads.
How can I call that stop method. I want it to be done in the stopAllThreads() method of the Main class.
Generally speaking, the way to do this is to have each of the other threads periodically check a flag. Often background threads loop, waiting for work - they just have to check the flag each time they go round a loop. If they're using Object.wait() or something similar to be told that there's more work, the same notification should be used to indicate that the thread should stop too. (Don't just spin until you're stopped - that will suck CPU. Don't just use sleep - that will delay termination.)
That allows all threads to terminate cleanly, releasing resources appropriately. Other options such as interrupt() and the deprecated destroy() method are much harder to control properly, IMO. (Interrupting a thread is better than hard-aborting it, but it has its own set of problems - such as the interruption is only processed at certain points anyway.)
EDIT: In code, it would look something like:
// Client code
for (Task task : tasks) {
task.stop();
}
// Threading code
public abstract class Task implements Runnable {
private volatile boolean stopped = false;
public void stop() {
stopped = true;
}
protected boolean shouldStop() {
return stopped;
}
public abstract void run();
}
Your tasks would then subclass Task. You would need to make it slightly more complicated if you wanted the stop() method to also notify a monitor, but that's the basic idea.
Sample task:
public class SomeTask extends Task {
public void run() {
while (!shouldStop()) {
// Do work
}
}
}
I don't think the answer solve the issue. here the code:
public class SomeTask extends Task {
public void run() {
while (!shouldStop()) {
// Do work
}
}
}
But how to handle if the "Do work" hang and does not return? In this case, the while cannot check the flag. The Thread still cannot stop.
The possible solution to this might be using Process.
Have a controller object which has a flag whether the threads should stop or not and each thread checks the controller periodically and exits if stop button is clicked (for example if you are transferring a file, then after each block is received/sent, check if stop is clicked).