-
Bug
-
Resolution: Cannot Reproduce
-
P3
-
None
-
7u25
-
Windows 7/32Bit
copy / paste the following piece of code and try running. Once you have started a gui less JavaFX thread you can not stop it anymore, not even if you use Thread.currentThread().getThreadGroup().interrupt();
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.embed.swing.JFXPanel;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
public class D31 extends Thread {
private static JFXPanel USELESS = new JFXPanel();
public static synchronized void main(String[] args) throws InterruptedException {
System.out.println("begin of main " + Thread.currentThread());
D31 d31 = new D31();
Platform.runLater(d31);
// d31.wait();
System.out.println("end of main " + d31);
}
public synchronized void run() {
final Thread THIS = this;
final WebView webView = new WebView();
final WebEngine engine = webView.getEngine();
System.out.println("begin run " + Thread.currentThread() );
//final WebEngine engine = new WebEngine();
//engine.documentProperty().addListener( new ChangeListener<Document>() { @Override public void changed(ObservableValue<? extends Document> prop, Document oldDoc, Document newDoc) {
engine.getLoadWorker().stateProperty().addListener(new MyListner(engine));
engine.load("http://google.com");
// try { this.wait(); } catch (Exception e) { e.printStackTrace(); }
System.out.println("end of start");
// try { this.stop(); } catch (Exception e) {}
}
/*
public void exit() {
Platform.runLater( new Runnable(){@Override public void run(){
System.out.println( "exit/runLater/run" );
engine.getLoadWorker().cancel();
Platform.exit();
}});
}*/
public ThreadGroup getRootThreadGroup( ) {
ThreadGroup tg = Thread.currentThread( ).getThreadGroup( );
ThreadGroup ptg;
while ( (ptg = tg.getParent( )) != null )
tg = ptg;
return tg;
}
public ThreadGroup[] getAllThreadGroups( ) {
final ThreadGroup root = getRootThreadGroup( );
int nAlloc = root.activeGroupCount( );
int n = 0;
ThreadGroup[] groups;
do {
nAlloc *= 2;
groups = new ThreadGroup[ nAlloc ];
n = root.enumerate( groups, true );
} while ( n == nAlloc );
ThreadGroup[] allGroups = new ThreadGroup[n+1];
allGroups[0] = root;
System.arraycopy( groups, 0, allGroups, 1, n );
for (ThreadGroup tg : allGroups) {
System.out.println("group: " + tg);
for (Thread t : getGroupThreads(tg)) {
System.out.println("\t: " + t);
}
}
return allGroups;
}
Thread[] getGroupThreads( final ThreadGroup group ) {
if ( group == null )
throw new NullPointerException( "Null thread group" );
int nAlloc = group.activeCount( );
int n = 0;
Thread[] threads;
do {
nAlloc *= 2;
threads = new Thread[ nAlloc ];
n = group.enumerate( threads );
} while ( n == nAlloc );
return java.util.Arrays.copyOf( threads, n );
}
Thread[] getAllThreads( ) {
final ThreadGroup root = getRootThreadGroup( );
final ThreadMXBean thbean = ManagementFactory.getThreadMXBean( );
int nAlloc = thbean.getThreadCount( );
int n = 0;
Thread[] threads;
do {
nAlloc *= 2;
threads = new Thread[ nAlloc ];
n = root.enumerate( threads, true );
} while ( n == nAlloc );
return java.util.Arrays.copyOf( threads, n );
}
public void log(String msg) {
System.out.println(msg);
}
public class MyListner implements ChangeListener<Worker.State> {
private final WebEngine engine;
public MyListner(WebEngine engine) {
this.engine = engine;
}
public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
System.out.println("changed " + Thread.currentThread() + " " + newState + " " + ov);
if (newState == Worker.State.SUCCEEDED) {
JSObject jsobj = (JSObject) engine.executeScript("window");
jsobj.setMember("console", this);
//System.out.println(DomUtils.getDocumentString(engine.getDocument()));
System.out.println(engine.getDocument());
Platform.setImplicitExit(true);
// engine.executeScript("println('-----------------------lala');");
// try { Thread.sleep(1000); } catch (Exception e) {}
System.out.println("want exit " + Thread.currentThread() );
// getAllThreadGroups();
Platform.setImplicitExit(false);
engine.getLoadWorker().cancel();
Platform.exit();
Thread.currentThread().getThreadGroup().interrupt();
for (Thread t : getAllThreads()) {
System.out.println(t.getName());
//if (t.getName().contains("URL")||t.getName().contains("FX")||t.getName().contains("Quant")) {
if (!t.getName().contains("Thread")) {
t.interrupt();
System.out.println(t.getState());
}
}
try { Thread.sleep(1000); } catch (Exception e) {}
// getAllThreadGroups();
// System.out.println(THIS.isAlive());
// engine.getLoadWorker().cancel();
Platform.exit(); // platform will not exit ...
// exit();
}
/*
USELESS.invalidate();
USELESS = null;
System.out.println(engine.getLoadWorker().cancel());
Platform.exit();
engine.getLoadWorker().stateProperty().removeListener(this);
*/
}
}
}
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.embed.swing.JFXPanel;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
public class D31 extends Thread {
private static JFXPanel USELESS = new JFXPanel();
public static synchronized void main(String[] args) throws InterruptedException {
System.out.println("begin of main " + Thread.currentThread());
D31 d31 = new D31();
Platform.runLater(d31);
// d31.wait();
System.out.println("end of main " + d31);
}
public synchronized void run() {
final Thread THIS = this;
final WebView webView = new WebView();
final WebEngine engine = webView.getEngine();
System.out.println("begin run " + Thread.currentThread() );
//final WebEngine engine = new WebEngine();
//engine.documentProperty().addListener( new ChangeListener<Document>() { @Override public void changed(ObservableValue<? extends Document> prop, Document oldDoc, Document newDoc) {
engine.getLoadWorker().stateProperty().addListener(new MyListner(engine));
engine.load("http://google.com");
// try { this.wait(); } catch (Exception e) { e.printStackTrace(); }
System.out.println("end of start");
// try { this.stop(); } catch (Exception e) {}
}
/*
public void exit() {
Platform.runLater( new Runnable(){@Override public void run(){
System.out.println( "exit/runLater/run" );
engine.getLoadWorker().cancel();
Platform.exit();
}});
}*/
public ThreadGroup getRootThreadGroup( ) {
ThreadGroup tg = Thread.currentThread( ).getThreadGroup( );
ThreadGroup ptg;
while ( (ptg = tg.getParent( )) != null )
tg = ptg;
return tg;
}
public ThreadGroup[] getAllThreadGroups( ) {
final ThreadGroup root = getRootThreadGroup( );
int nAlloc = root.activeGroupCount( );
int n = 0;
ThreadGroup[] groups;
do {
nAlloc *= 2;
groups = new ThreadGroup[ nAlloc ];
n = root.enumerate( groups, true );
} while ( n == nAlloc );
ThreadGroup[] allGroups = new ThreadGroup[n+1];
allGroups[0] = root;
System.arraycopy( groups, 0, allGroups, 1, n );
for (ThreadGroup tg : allGroups) {
System.out.println("group: " + tg);
for (Thread t : getGroupThreads(tg)) {
System.out.println("\t: " + t);
}
}
return allGroups;
}
Thread[] getGroupThreads( final ThreadGroup group ) {
if ( group == null )
throw new NullPointerException( "Null thread group" );
int nAlloc = group.activeCount( );
int n = 0;
Thread[] threads;
do {
nAlloc *= 2;
threads = new Thread[ nAlloc ];
n = group.enumerate( threads );
} while ( n == nAlloc );
return java.util.Arrays.copyOf( threads, n );
}
Thread[] getAllThreads( ) {
final ThreadGroup root = getRootThreadGroup( );
final ThreadMXBean thbean = ManagementFactory.getThreadMXBean( );
int nAlloc = thbean.getThreadCount( );
int n = 0;
Thread[] threads;
do {
nAlloc *= 2;
threads = new Thread[ nAlloc ];
n = root.enumerate( threads, true );
} while ( n == nAlloc );
return java.util.Arrays.copyOf( threads, n );
}
public void log(String msg) {
System.out.println(msg);
}
public class MyListner implements ChangeListener<Worker.State> {
private final WebEngine engine;
public MyListner(WebEngine engine) {
this.engine = engine;
}
public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
System.out.println("changed " + Thread.currentThread() + " " + newState + " " + ov);
if (newState == Worker.State.SUCCEEDED) {
JSObject jsobj = (JSObject) engine.executeScript("window");
jsobj.setMember("console", this);
//System.out.println(DomUtils.getDocumentString(engine.getDocument()));
System.out.println(engine.getDocument());
Platform.setImplicitExit(true);
// engine.executeScript("println('-----------------------lala');");
// try { Thread.sleep(1000); } catch (Exception e) {}
System.out.println("want exit " + Thread.currentThread() );
// getAllThreadGroups();
Platform.setImplicitExit(false);
engine.getLoadWorker().cancel();
Platform.exit();
Thread.currentThread().getThreadGroup().interrupt();
for (Thread t : getAllThreads()) {
System.out.println(t.getName());
//if (t.getName().contains("URL")||t.getName().contains("FX")||t.getName().contains("Quant")) {
if (!t.getName().contains("Thread")) {
t.interrupt();
System.out.println(t.getState());
}
}
try { Thread.sleep(1000); } catch (Exception e) {}
// getAllThreadGroups();
// System.out.println(THIS.isAlive());
// engine.getLoadWorker().cancel();
Platform.exit(); // platform will not exit ...
// exit();
}
/*
USELESS.invalidate();
USELESS = null;
System.out.println(engine.getLoadWorker().cancel());
Platform.exit();
engine.getLoadWorker().stateProperty().removeListener(this);
*/
}
}
}