1

I am using Swingworker to request value from url address to dynamically change a version of displayed information. At certain cases this worker is cancelled. The problem is that I get java.lang.InterruptedException sometimes (but not every time I cancel worker). I am not sure what to do with it, moreover I have no idea where it is thrown, I cannot debug it because I get it when I do lots of version changes in short time (I use slider and this happens when I am dragging it for some time) . Everything works fine but I get this annoying error:

 java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at sun.plugin2.message.Queue.waitForMessage(Unknown Source)
at sun.plugin2.message.Pipe$2.run(Unknown Source)
at com.sun.deploy.util.Waiter$1.wait(Unknown Source)
at com.sun.deploy.util.Waiter.runAndWait(Unknown Source)
at sun.plugin2.message.Pipe.receive(Unknown Source)
at sun.plugin2.main.client.MessagePassingExecutionContext.doCookieOp(Unknown Source)
at sun.plugin2.main.client.MessagePassingExecutionContext.getCookie(Unknown Source)
at sun.plugin2.main.client.PluginCookieSelector.getCookieFromBrowser(Unknown Source)
at com.sun.deploy.net.cookie.DeployCookieSelector.getCookieInfo(Unknown Source)
at com.sun.deploy.net.cookie.DeployCookieSelector.get(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.setCookieHeader(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.writeRequests(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at org.dbwiki.web.applet.ValueRequester.doInBackground(ValueRequester.java:40)
at org.dbwiki.web.applet.ValueRequester.doInBackground(ValueRequester.java:1)
at javax.swing.SwingWorker$1.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at javax.swing.SwingWorker.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Also after each exception which is showed above additional message is thrown:

sun.plugin2.main.client.PluginMain: unrecognized message ID 46

Interesting thing that exception is only being thrown when program is run in the browser as an applet, if program is run as applet from api no exceptions are thrown.

My StringWorker:

    package org.dbwiki.web.applet;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import javax.swing.SwingWorker;

public class ValueRequester extends SwingWorker<Void, Void> {
    HtmlGenerator htmlGen;
    ArrayList<String[]> versionsData;
    String id;
    private String dbName;
    ValueRequester (HtmlGenerator htmlGen, ArrayList<String[]> versionData, int ver){
    try {
        this.htmlGen=htmlGen;
        if (TreeVisualiser.typeParameter.equals(TreeVisualiser.StructureVisualiserParameter))
            this.id=htmlGen.getElem().getVersionElementId(ver);
        else if(TreeVisualiser.typeParameter.equals(TreeVisualiser.HistoryVisualiserParameter))
            this.id=htmlGen.getElem().getId();
        this.dbName=htmlGen.getElem().getDBName();
        this.versionsData=versionData;
    } catch (Exception e) {
        e.printStackTrace();
    }

    }
    protected Void doInBackground() throws Exception {
    try{
        String value="";
        URL historyURL = new URL("http://127.0.0.1:8080/"+dbName+id+"?value");
        URLConnection hc = historyURL.openConnection();     
        BufferedReader in = new BufferedReader(new InputStreamReader(hc.getInputStream()));  
        String line;
        while ((line = in.readLine()) != null) {
            value+=line;
        }
        in.close();

        this.htmlGen.formDisplayerHead();
        this.htmlGen.formNodeDataHtml(value,this.versionsData);
        this.htmlGen.formDisplayerTail();
    }   
    catch(Exception e)
    {
        e.printStackTrace();
    }
        return null;
}

protected void done()
{
    if (!this.isCancelled())
    this.htmlGen.dataDisplayer.setText(this.htmlGen.getHtml());

}

}

I have now idea what causes it, how to handle it or at least how to hide it (as everything works normal). Any help would be appreciated.

UPDATE:

I try to catch this exception in the ValueRequester.doInBackround(), however my catch statement don't catch the exception. My updated code of doInBackground():

protected Void doInBackground() throws Exception {
       try{
          String value="";
            URL historyURL = new URL("http://127.0.0.1:8080/"+dbName+id+"?value");

            URLConnection hc = historyURL.openConnection(); 
            InputStream inputStrm=hc.getInputStream();
           InputStreamReader inputStrmRdr= new InputStreamReader(inputStrm);
            this.in = new BufferedReader(inputStrmRdr);  
            String line;
            while ((line = in.readLine()) != null) {
                value+=line;
            }
            this.htmlGen.formDisplayerHead();
            this.htmlGen.formNodeDataHtml(value,this.versionsData);
            this.htmlGen.formDisplayerTail();
       }catch (InterruptedException e){
           System.out.println("Interrupted Exception caught!");
          // e.printStackTrace();
       }

    return null;
}

Unfortunately stack trace is still printed instead of my system out message. Any idea what could be wrong here?

M T
  • 968
  • 1
  • 8
  • 24
  • This is not the complete stack trace, is it? What you get in fact is an IOException caused by this InterrupedException, right? – JB Nizet Jul 05 '12 at 10:34

2 Answers2

3

As far as I know, an InterruptedException only occurs if some other thread calls Thread.interrupt() on a thread that is blocked. In this case, it is clear that the interrupted thread was in a wait() call at the time.

Looking at the SwingWorker code, it appears that the worker thread will get an interrupt if the thread that scheduled decides to call cancel(true) on it. Depending on what the worker thread is doing at the time, it may get an InterruptedException, or it may just have its Thread.interrupted flag set.

So the solution to your problem would appear to be to find out what is calling cancel(true) on the SwingWorker instance. Then either change it to not do that ... or make your worker class deal with the InterruptedException appropriately. The appropriate behaviour would probably be to catch the exception and quietly return from call(...)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • even I deleted my post here [I think that only get() returns exceptions](http://stackoverflow.com/questions/7053865/cant-get-arrayindexoutofboundsexception-from-future-and-swingworker-if-threa) and not as you described `only occurs if some other thread calls`, there is common issue that everything invoked from SwingWorker didn't returns exceptions directly – mKorbel Jul 05 '12 at 13:27
  • @mKorbel - I know what you are saying, and in a sense you are right. But the question is NOT about exceptions that `get()` throws. Look at the stacktrace. – Stephen C Jul 05 '12 at 14:02
  • agreed, aaach I see that, this is possible only from create a new Object as local variable, maybe could be wrong idea / mistake to create those Objects inside SwingWorker (Object could be created before) or use SwingWorker at all for this type of background tasks – mKorbel Jul 05 '12 at 15:30
  • Yes, the instance is sometimes canceled using cancel(true) method. This is needed in some cases. However I am not sure where to catch this exception. I tried to surround cancel(), execute() and doInBackground() functions and catch this exception but nothing works. I am absolutely beginner with thread programming so pardon me if some of my logic doesn't make too much sense or I miss something really obvious. – M T Jul 05 '12 at 16:04
  • You have to catch it in `ValueRequester.doInBackground` or in the `call` method of the anonymous class that you use to call doInBackground. – Stephen C Jul 05 '12 at 17:13
2

To me it just looks like you are calling worker.cancel(true); (assuming worker is your SwingWorker). The true indicates that if the current Thread is in an interruptible state, the Thread can be interrupted. When this happens, it automatically throws an Exception indicating that the Thread has been interrupted allowing you to release resources and possibly do something. I guess in your case you can safely ignore this and simply close the opened streams.

In your case, depending on how far you are in your "Work", the task may get interrupted or not.

See more information on Thread interruption here.

Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117