diff -r d0eb4fb4bc55 netx/net/sourceforge/swing/SwingUtils.java
--- a/netx/net/sourceforge/swing/SwingUtils.java Thu Oct 18 13:09:29 2018 +0200
+++ b/netx/net/sourceforge/swing/SwingUtils.java Thu Oct 18 21:32:37 2018 +0200
@@ -40,6 +40,17 @@
import java.awt.EventQueue;
import java.awt.Window;
import java.lang.reflect.InvocationTargetException;
+/* */
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+/* */
import javax.swing.JWindow;
import javax.swing.RepaintManager;
import javax.swing.SwingUtilities;
@@ -49,6 +60,7 @@
/**
* Swing / AWT utility class
*/
+
public final class SwingUtils {
private static final boolean DEBUG_EDT = System.getProperty("icedtea-web.edt.debug", "false").equalsIgnoreCase("true");
@@ -67,6 +79,51 @@
/* shared Window owner */
private static Window window = null;
+/* */
+ private static final boolean TRACE_BRIDGE = false;
+
+ private static final boolean ENABLE_EDT_BRIDGE;
+
+ /** single thread pool with max 1 live daemon thread */
+ private static final ExecutorService EDT_DAEMON_THREAD_POOL;
+
+ static {
+ ENABLE_EDT_BRIDGE = System.getProperty("icedtea-web.edt.bridge", "false").equalsIgnoreCase("true");
+ if (ENABLE_EDT_BRIDGE) {
+ trace("Enable EDT Bridge.");
+
+ EDT_DAEMON_THREAD_POOL = new ThreadPoolExecutor(0, 1,
+ 60L, TimeUnit.SECONDS,
+ new LinkedBlockingQueue(),
+ new MainAppContextDaemonThreadFactory()
+ );
+ } else {
+ EDT_DAEMON_THREAD_POOL = null;
+ }
+ }
+
+ private static final class MainAppContextDaemonThreadFactory implements ThreadFactory {
+
+ private final AtomicInteger threadNumber = new AtomicInteger(1);
+ private final String namePrefix = "itw-edt-thread-";
+
+ @Override
+ public Thread newThread(Runnable r) {
+ final Thread t = new Thread(MAIN_GROUP, r,
+ namePrefix + threadNumber.getAndIncrement()
+ );
+ if (!t.isDaemon()) {
+ t.setDaemon(true);
+ }
+ if (t.getPriority() != Thread.NORM_PRIORITY) {
+ t.setPriority(Thread.NORM_PRIORITY);
+ }
+ return t;
+ }
+ }
+
+/* */
+
private SwingUtils() {
// forbidden
}
@@ -134,6 +191,31 @@
traceWithStack("invokeLater() from EDT: MAY be fixed (useless) ?");
}
}
+/* */
+ else if (ENABLE_EDT_BRIDGE) {
+ // AppContext bridge
+ final ClassLoader doRunCL = doRun.getClass().getClassLoader();
+
+ if (TRACE_BRIDGE) {
+ trace("invokeLater(doRun): "
+ + doRun.getClass().getName() + " @ "
+ + ((doRunCL == null) ? "BootClassLoader" : doRunCL));
+ }
+
+ // Ensure bridge is only used by Boot class loader:
+ if (doRunCL == null) {
+ EDT_DAEMON_THREAD_POOL.submit(new Runnable() {
+ @Override
+ public void run() {
+ SwingUtilities.invokeLater(doRun);
+ }
+ });
+ return;
+ } else {
+ traceWithStack("SwingUtils.invokeLater() called from external class loader: " + doRunCL);
+ }
+ }
+/* */
EventQueue.invokeLater(doRun);
}
@@ -150,6 +232,44 @@
}
public static void invokeAndWait(final Runnable doRun) {
+/* */
+ if (!isMainThreadGroup() && ENABLE_EDT_BRIDGE) {
+ // AppContext bridge
+ final ClassLoader doRunCL = doRun.getClass().getClassLoader();
+
+ if (TRACE_BRIDGE) {
+ trace("invokeAndWait(doRun): "
+ + doRun.getClass().getName() + " @ "
+ + ((doRunCL == null) ? "BootClassLoader" : doRunCL));
+ }
+
+ // Ensure bridge is only used by Boot class loader:
+ if (doRunCL == null) {
+ final Future> future = EDT_DAEMON_THREAD_POOL.submit(new Callable() {
+ @Override
+ public Void call() throws Exception {
+ callOnAppContext(doRun);
+ return null;
+ }
+ });
+ try {
+ // Wait on Future:
+ future.get();
+ } catch (InterruptedException ie) {
+ OutputController.getLogger().log(OutputController.Level.ERROR_ALL, ie);
+ } catch (ExecutionException ee) {
+ if (ee.getCause() != null) {
+ OutputController.getLogger().log(OutputController.Level.ERROR_ALL, ee.getCause());
+ } else {
+ OutputController.getLogger().log(OutputController.Level.ERROR_ALL, ee);
+ }
+ }
+ return;
+ } else {
+ traceWithStack("SwingUtils.invokeAndWait() called from external class loader: " + doRunCL);
+ }
+ }
+/* */
if (isEventDispatchThread()) {
if (TRACE_INVOKE_EDT) {
traceWithStack("invokeAndWait() from EDT: to be fixed (illegal) ?");