1

I faced very strange problem. Writing an application to download some data from Internet with proxy server support I decided to use Apache's HttpClient library. jar binaries were successfully added to NetBeans project and the following code snippet was executed (successfully too) in a simple application:

DefaultHttpClient httpclient = new DefaultHttpClient();
String proxyHost = "192.168.4.10";
Integer proxyPort = 8080;

HttpHost targetHost = new HttpHost("noaasis.noaa.gov", 80, "http");
HttpGet httpget = new HttpGet("/ptbus/ptbus167");

try {

    HttpHost proxy = new HttpHost(proxyHost, proxyPort);
    httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

    System.out.println("executing request: " + httpget.getRequestLine());
    System.out.println("via proxy: " + proxy);
    System.out.println("to target: " + targetHost);

    HttpResponse response = httpclient.execute(targetHost, httpget);
    HttpEntity entity = response.getEntity();

    System.out.println("----------------------------------------");
    System.out.println(response.getStatusLine());
    Header[] headers = response.getAllHeaders();
    for (int i = 0; i<headers.length; i++) {
        System.out.println(headers[i]);
    }

    System.out.println("----------------------------------------");
    System.out.println(response.getStatusLine());
    if (entity != null) {
        System.out.println("Response content length: " + entity.getContentLength());
    }
    EntityUtils.consume(entity);

}
catch (IOException ex) {

}
finally {
    // When HttpClient instance is no longer needed,
    // shut down the connection manager to ensure
    // immediate deallocation of all system resources
    httpclient.getConnectionManager().shutdown();
}

But when I try to do the same thing in Swing application it doesn't work. For example, rewriting default Netbeans desktop application's "about" action listener as follows

@Action
public void showAboutBox() {

    new Thread(new Runnable() {

        public void run() {

            DefaultHttpClient httpclient = new DefaultHttpClient();

            ......
            ......
            ......

            finally {
                // When HttpClient instance is no longer needed,
                // shut down the connection manager to ensure
                // immediate deallocation of all system resources
                httpclient.getConnectionManager().shutdown();
            }

        }
    }).start();
}

causes application's execution to stop somewhere in

HttpResponse response = httpclient.execute(targetHost, httpget);

Leastways, it never returns...

The interesting thing is if I also put this code snippet in application's main method just before creating any Swing instance the mentioned line is passed and HTTP response is received. And calling showAboutBox() doesn't cause the problem anymore then - I receive HTTP response too.

What am I doing wrong, guys? What's the trick? Can I use Apache's library in my Swing application? I cannot understand what happens and didn't find anything similar to this spending hours in the net.

Thank You for attention. Hope for any help!

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
ezze
  • 3,933
  • 2
  • 34
  • 58
  • Is this a [Java Desktop Application](http://stackoverflow.com/questions/2561480/netbeans-gui-editor-generating-its-own-incomprehensible-code/2561540#2561540)? – trashgod Jun 24 '11 at 20:33
  • Yes, it is. But in my application GUI forms generated by NetBeans are replaced by hand-written code with using of [SpringLayout](http://download.oracle.com/javase/tutorial/uiswing/layout/spring.htmlSpringLayout). Only main class extending SingleFrameApplication is left. – ezze Jun 24 '11 at 20:57
  • OK. I added the `jsr296` tag in case it's relevant. – trashgod Jun 25 '11 at 01:50

3 Answers3

2

You're blocking the event dispatch thread (EDT). Use SwingWorker, as shown here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Hello, trashgod. Thank you for the reply... How can I block event dispatch thread when I create a separate thread for my download task? (`SwingUtilities.isEventDispatchThread()` returns `false`). Placing this code in `SwingWorker`'s `doInBackground()` method delivers the same result. Probably, I had to be more precise - I can manipulate GUI controls but a thread I had run never returns (I can see it in debugging window). Invoking `showAboutBox()` few times I have few "sleeping" threads as the result. – ezze Jun 24 '11 at 20:47
  • Hmmn, the EDT will automatically restart if it encounters an exception. Any chance one's getting swallowed? On _any_ thread? See also [this](http://stackoverflow.com/questions/95767). Sorry for the false lead. – trashgod Jun 25 '11 at 01:47
  • Hi, trashgod. I have no any exceptions in output and I still can't figure out how this non-EDT can influence EDT. – ezze Jun 27 '11 at 08:26
  • Sorry , I don't know enough about `jsr296` or `HttpClient` to say _why_ it blocks. If it's running on another thread, be sure to use `invokeLater()` when updating the GUI. – trashgod Jun 27 '11 at 08:47
2

that only comments but its longer than allowed number of chars....

to avoid wrong directions, Swing based gui doesn't any care that you running any of BackGround Task, Swing is single threaded and all output to the GUI must be done on EDT

1/ wrap output to the GUI to the SwingUtilities.invokeLater(), that's created your own EDT, and if there EDT exist then move actual task to the ends of the EDT

2/ wrap output to the GUI by using javax.swing.Action

3/ or as trashgod suggested let's SwingWorker works for that +1

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • I think you may be right; it's not clear how `showAboutBox` reports it's results from the its thread to the EDT. – trashgod Jun 25 '11 at 08:19
  • Hello, mMorbel. Thank You for the reply. As You can see, I didn't update GUI controls in my example and have no deal with Swing components at all. I simply want to execute HTTP request. Of course, if I will need to update something I will use one of `SwingUtilities`' methods or `SwingWorker.done()`. – ezze Jun 27 '11 at 08:31
  • hmmm, I can run Thread from Runnable, any times as I wants, check details in my thread about JTable&Timer http://stackoverflow.com/questions/6051755/java-wait-cursor-display-problem/6051893#6051893 – mKorbel Jun 27 '11 at 08:48
1

I solved the problem by excluding org.jdesktop.application.SingleFrameApplication and replacing FrameView by JFrame. Of course, one loses advantages of FrameView but all required things can be implemented extending JFrame.

Unfortunately, I have no enough time to examine why HttpClient doesn't work with SingleFrameApplication so the solution proposed is acceptable for me.

Hope this will help somebody else.

And thanks to trashgod and mKorbel for participation. Thank you, guys. Both +1.

ezze
  • 3,933
  • 2
  • 34
  • 58