4

I have a program where I compile java code a user types into a text field, and then run it. A run the code in a seperate thread, so that the GUI they use to input the source code doesn't get locked up.

The GUI has an abort button that should stop the thread. My issue is that I need to stop the compiling thread no matter what is going on inside of it, which means I must account for a case where the thread is caught in an infinite loop (due to user error), and it cannot properly end itself using a safe flag. I've read up on many solutions that involve using a flag of some kind, but they aren't available to me because of this looping issue. I need to have the thread stop and the memory it's using freed (I can't just let it sit in the background forever, unless that is the only solution left). Any advice or alternative solutions? Hopefully some fresh perspectives could help squash this issue.

Edit:

Here's a sample bit of user submitted code:

public class RunMe extends SomethingThatRuns {
    public void run() {
        int i = 0;
        while (i = 0) {
            //Prepare to get stuck!
        }
    }
}

I'll compile this class, and then run it. This is where it will get stuck, and the run() method can never finish, or even loop to check a flag.

kazoo
  • 137
  • 2
  • 7
  • I feel you need have your own interface to have them implement. The correct way is to use `Thread.interrupt()` but if the code doesn't respect the flag then you would be stuck in a loop. I wonder what others think? I be more than happy to provide a sample interface. – Amir Raminfar Aug 22 '11 at 19:40
  • Do you have to use a thread? Could you do the compilation in a separate process? Then if it runs for too long, you could just `kill` the process. – Jack Edmonds Aug 22 '11 at 19:42
  • 1
    Why don't you post some code? It'll make it easier on us to troubleshoot. – mre Aug 22 '11 at 19:47
  • Is it possible to run the code in a debugger? This might give the option to interrupt it at any time.. – daniel kullmann Aug 22 '11 at 19:58

6 Answers6

2

You can run it in a new JVM so you can kill it when you want. Thinking about security this may be a good thing to do too.

aalku
  • 2,860
  • 2
  • 23
  • 44
  • 1
    It interacts with the rest of the program, so it has to be in the same JVM. Also, security isn't a concern in this particular application. – kazoo Aug 22 '11 at 19:46
  • 1
    Agreed on this solution. Inter-process communication won't be fun though. – Amir Raminfar Aug 22 '11 at 19:47
  • After talking this whole thing over with some of my fellow work mates, this is the solution I'm going to persue. – kazoo Aug 22 '11 at 20:45
  • @toriscope How did you do the communication? Have you some sample code of how you ran your code in different JVM – tgoossens Aug 13 '12 at 12:39
2

Call stop() on the thread.

Yes, this is a deprecated method. However, it really shouldn't be "deprecated", it should be "dangerous." In some circumstances, however, there's really no choice but to use it, and the invocation of an "agent" provided by a user is one of those cases.

Make sure that your program doesn't use any data that are manipulated by this user thread; or, if you do, devise some transactional mechanism to exchange data safely between the threads.

Even this method isn't guaranteed to terminate the thread. For example, the user can catch the resulting Throwable and ignore it. Or, the thread implementation might not respond to stop() calls if the thread is in some native code. But it's your best chance.

erickson
  • 265,237
  • 58
  • 395
  • 493
1

The core issue here is the fact that the code even allows an infinite loop to be entered as part of user error. Fix that, and everything else will become easier to deal with.

Properly-behaving threads should usually terminate themselves gracefully when there's no work to do (or return quietly to a thread pool to ask for more work, if that's your application's design). If you feel like you need to have one thread forcefully kill another then you've likely got a fundamental design issue. It's fine to have one thread tell another, "Hey, you should terminate now so that I can join with you..." because that allows your threads to clean things up as they finish. Forcefully destroying threads just isn't the right way to manage these situations.

Brian Kelly
  • 19,067
  • 4
  • 53
  • 55
  • In order to keep power in the hands of the user, we have to account for a user putting in a never ending loop. The fact that their code is being run in a thread should be invisible to them. – kazoo Aug 22 '11 at 20:02
  • How do you check the code for infinite loops (see "halting problem")? – daniel kullmann Aug 22 '11 at 20:12
  • Aha, I missed the part that it was a 3rd-party's code which would get run. In that case, the accepted answer which uses a separate JVM to run the code is more appropriate because then you can isolate the effects of the user's code and use heuristics to determine if/when to terminate their runaway process. Could you also make a simplifying assumption that if the user codes an infinite loop that it be on their own head, and it should be their responsibility for figuring that out? Not knowing your system it's hard to guess if that's a possibility for you. – Brian Kelly Aug 22 '11 at 21:29
1

You can use them to insert a interrputed check in every loop and maybe in other places too.

I can see two options:

  • As you compile the user code you can edit it before. You may use ANTLR to parse and modify the code.
  • There are bytecode manipulation frameworks like ASM that allow you to manipulate code that is already compiled.

I don't think it is easy but it might be a way.

aalku
  • 2,860
  • 2
  • 23
  • 44
0

interupt(); the Thread in the gui

and in the code that the thread runs regularly check for Thread.interrupted() and throw an exception when you do especially inside loops

ratchet freak
  • 47,288
  • 5
  • 68
  • 106
  • Ah, I would love to do this, but I can't, as a user will be writing the actual running code, not me. – kazoo Aug 22 '11 at 20:00
  • @any tell the user to regularly check for interrupted status, not foolproof but running user code rarely is – ratchet freak Aug 22 '11 at 20:11
0

At a high level, you are asking how one thread might go about stopping another thread. To that end, see this SO question Stopping a Thread in Java?.

Community
  • 1
  • 1
Dilum Ranatunga
  • 13,254
  • 3
  • 41
  • 52