This discussion is archived
10 Replies Latest reply: Jun 6, 2012 4:21 PM by EJP RSS

Stuck Inside Native Method

638189 Newbie
Currently Being Moderated
I have developed some Java code to call a third party DLL using JNI. Most of the time everything works as expected, but once in a while (generally after several days of processing) my program hangs. The root cause appears to be related to an intermittent issue with the driver that I am calling, something that I have no control over. When I perform a thread dump I can see that the thread is "stuck" inside the native method that I am calling. I am able to detect the hangup using a timer, and even obtain the "stuck" thread, but I cannot kick it back into life...or kill it in any way. Does anyone have any ideas?

My code that is calling the native method is as follows:
public void process() {
    System.out.println("Hello world from Java");
    Timer timer = new Timer();
    timer.schedule(new MyTimerTask(), 1000);
    myNativeMethod();
    System.out.println("Goodbye world from Java");
}
And the code for my timer task is as follows:
public class MyTimerTask extends TimerTask {
    @Override
    public void run() {
        System.out.println("Timeout");
        ThreadGroup tg = Thread.currentThread().getThreadGroup();
        Thread[] list = new Thread[tg.activeCount()];
        tg.enumerate(list);
        for (Thread t : list) {
            System.out.println(t);
            System.out.println("---------------------------------------");
            StackTraceElement[] st = t.getStackTrace();
            for (StackTraceElement ste : st) {
                System.out.println(ste);
                if (ste.getMethodName().equals("myNativeMethod") && ste.isNativeMethod()) {
                    System.out.println("stuck thread " + t.getName() + " detected!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
                    t.interrupt();
                    break;
                }
            }
        }
    }
}
  • 1. Re: Stuck Inside Native Method
    KevinPas Explorer
    Currently Being Moderated
    What does the DLL do? Do you get data out of it? Can you launch it in a separate java Process?

    private Process process = null;

    // The following only works in Windows.
    // Something like this might work in Linux: String command="ps -A -U "+System.getProperty("user.name")+" -d";
    String line;

    Process p = Runtime.getRuntime().exec("tasklist.exe /FI \"IMAGENAME eq " + "name of process" + "\"");
    BufferedReader input = new BufferedReader (new InputStreamReader(p.getInputStream()));

    while ((line = input.readLine()) != null) {
    if ( line.contains( "name of process" ) ) {
    alreadyLoaded = true; // Already Loaded.
    break;
    }
    }

    // Try to load it.
    if ( alreadyLoaded == false )
    {
    process = Runtime.getRuntime().exec( path + " -m" );
    }

    else
    {
    }
  • 2. Re: Stuck Inside Native Method
    KevinPas Explorer
    Currently Being Moderated
    I forgot. Then you can kill it.

    if ( process != null )
    process .destroy ();

    Edited by: KevinPas on Jun 5, 2012 4:36 PM
  • 3. Re: Stuck Inside Native Method
    638189 Newbie
    Currently Being Moderated
    Thanks for your response KevinPas.

    I am communicating with PC/SC smart card readers, using the javax.smartcardio classes, and it is these classes that are actually communicating with a DLL, so it's not really possible for me to use the approach that you have suggested. I really just wanted to illustrate a simplified view of what is happening with my code above. In an effort to simulate the issue in a repeatable manner I developed a DLL that simply contains an infinite loop, this is what I then called in my illustration.
  • 4. Re: Stuck Inside Native Method
    EJP Guru
    Currently Being Moderated
    There's no guarantee that interrupt() can interrupt everything. java.io comes to mind. You might have to use System.exit() ;-(
  • 5. Re: Stuck Inside Native Method
    638189 Newbie
    Currently Being Moderated
    You are quite correct EJP, interrupt() was doing nothing for me. Unfortunately using System.exit() is not an option in my solution, as the final code will be running inside the JBoss application server. I was really hoping for a solution that would not require a re-start of the application server, but it is looking more and more as if this is unlikely.
  • 6. Re: Stuck Inside Native Method
    EJP Guru
    Currently Being Moderated
    As it's a server you must use a separate process as per the suggestion above, no two ways about it.
  • 7. Re: Stuck Inside Native Method
    638189 Newbie
    Currently Being Moderated
    Just so I am clear, do you mean that:
    a) As it's a server I must use a separate process to communicate with a DDL because that's the only way to communicate with a DLL inside the server
    b) As it's a server I must use a separate process to communicate with a DLL if I want to be able to kill a stuck process

    I am assuming that you mean b), which is not really an option due to the fact that it is not my code that is communicating with the DLL, it is the javax.smartcardio classes that are communicating with the DLL. I could of course not use the javax.smartcardio classes and write something myself, but I figured there wasn't much point in re-inventing the wheel if I didn't need to.
  • 8. Re: Stuck Inside Native Method
    KevinPas Explorer
    Currently Being Moderated
    Just to finish my thought which will only be useful as a last resort and only if you have permissions to do this on your server:

    It seems possible, but maybe not practical and a lot of extra work:

    1) Launch a separate process that runs your dll (or the code that uses the dll).
    2) Pass a tcp port number on the command line when you start it.
    3) Get and set values via tcp
    4) If it locks up (you say you know when that happens) have the tcp client ask for a process kill.
    5) Maybe your primary app can destroy the secondary process (which should dump the dll too) and restart it.

    No need to respond I'm just doing a brain dump.

    Edited by: KevinPas on Jun 6, 2012 9:26 AM

    Edited by: KevinPas on Jun 6, 2012 9:31 AM
  • 9. Re: Stuck Inside Native Method
    jschellSomeoneStoleMyAlias Expert
    Currently Being Moderated
    StuartyBoarder wrote:
    a) As it's a server I must use a separate process to communicate with a DDL because that's the only way to communicate with a DLL inside the server
    No
    b) As it's a server I must use a separate process to communicate with a DLL if I want to be able to kill a stuck process
    Absolutely.
    I am assuming that you mean b), which is not really an option
    A process is a process. Doesn't matter what it runs.

    An advantage that hasn't been mentioned in terms of a separate process is that if the dll has a system exception it will cause the process to exit. And there is no way to stop that. If that process is your JBoss server then it will exit. Which probably isn't what you want.

    As a separate process if if exits all you need to is detect that (via correct usage of Process) and then just start it up again.
  • 10. Re: Stuck Inside Native Method
    EJP Guru
    Currently Being Moderated
    Just so I am clear, do you mean that:
    a) As it's a server [snip]
    None of the above. As it's a server that you don't want to restart you must put the bits that get stuck into a separate process that you can restart.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points