1 /* @test
   2    @bug 4714674
   3    @summary Tests that JEditorPane opens HTTP connection asynchronously
   4    @author Peter Zhelezniakov
   5    @run main bug4714674
   6 */
   7 
   8 import javax.swing.*;
   9 
  10 import com.sun.net.httpserver.HttpExchange;
  11 import com.sun.net.httpserver.HttpHandler;
  12 import com.sun.net.httpserver.HttpServer;
  13 import java.io.IOException;
  14 import java.net.InetSocketAddress;
  15 import java.util.concurrent.Executors;
  16 
  17 
  18 public class bug4714674 {
  19 
  20     public static void main(String[] args) throws Exception {
  21         new bug4714674().test();
  22     }
  23 
  24     private void test() throws Exception {
  25         final DeafServer server = new DeafServer();
  26         final String baseURL = "http://localhost:" + server.getPort() + "/";
  27 
  28         SwingUtilities.invokeLater(new Runnable() {
  29             public void run() {
  30                 try {
  31                     JEditorPane pane = new JEditorPane();
  32                     ((javax.swing.text.AbstractDocument)pane.getDocument()).
  33                             setAsynchronousLoadPriority(1);
  34 
  35                     // this will block EDT unless 4714674 is fixed
  36                     pane.setPage(baseURL);
  37                 } catch (IOException e) {
  38                     // should not happen
  39                     throw new Error(e);
  40                 }
  41             }
  42         });
  43 
  44         // if 4714674 is fixed, this executes before connection times out
  45         SwingUtilities.invokeLater(new Runnable() {
  46             public void run() {
  47                 synchronized (server) {
  48                     server.wakeup = true;
  49                     server.notifyAll();
  50                 }
  51                 pass();
  52             }
  53         });
  54 
  55         // wait, then check test status
  56         try {
  57             Thread.sleep(5000);
  58             if (!passed()) {
  59                 throw new RuntimeException("Failed: EDT was blocked");
  60             }
  61         } finally {
  62             server.destroy();
  63         }
  64     }
  65 
  66     private boolean passed = false;
  67 
  68     private synchronized boolean passed() {
  69         return passed;
  70     }
  71 
  72     private synchronized void pass() {
  73         passed = true;
  74     }
  75 }
  76 
  77 /**
  78  * A "deaf" HTTP server that does not respond to requests.
  79  */
  80 class DeafServer {
  81     HttpServer server;
  82     boolean wakeup = false;
  83 
  84     /**
  85      * Create and start the HTTP server.
  86      */
  87     public DeafServer() throws IOException {
  88         InetSocketAddress addr = new InetSocketAddress(0);
  89         server = HttpServer.create(addr, 0);
  90         HttpHandler handler = new DeafHandler();
  91         server.createContext("/", handler);
  92         server.setExecutor(Executors.newCachedThreadPool());
  93         server.start();
  94     }
  95 
  96     /**
  97      * Stop server without any delay.
  98      */
  99     public void destroy() {
 100         server.stop(0);
 101     }
 102 
 103     /**
 104      * Return actual server port number, useful for constructing request URIs.
 105      */
 106     public int getPort() {
 107         return server.getAddress().getPort();
 108     }
 109 
 110 
 111     class DeafHandler implements HttpHandler {
 112         public void handle(HttpExchange r) throws IOException {
 113             synchronized (DeafServer.this) {
 114                 while (! wakeup) {
 115                     try {
 116                         DeafServer.this.wait();
 117                     } catch (InterruptedException e) {
 118                         // just wait again
 119                     }
 120                 }
 121             }
 122         }
 123     }
 124 }