Reputation: 143
I am trying to open "engine.load("https://login.microsoftonline.com");" in JavaFX WebView.
When using jdk1.8.0_161 the page is loaded. When using jdk1.8.0_181 the page does not load. It displays empty window and does not return any error: engine.getLoadWorker().exceptionProperty() is null.
Do you have any idea what might have changed in new version updates of Java? I tested on Java 10 latest release and the page is also not loaded. This code works with JDK8.161 and JDK9.0.4 but does not work with JDK8.181 and JDK10.0.2
Here is the source code of the sample app I have created:
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker.State;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebErrorEvent;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import javafx.util.Callback;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.swing.*;
import org.w3c.dom.Document;
public class LoginApplicationWindow {
public static void main(String args[]) {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(620, 440);
final JFXPanel fxpanel = new JFXPanel();
frame.add(fxpanel);
Platform.runLater(new Runnable() {
@Override
public void run() {
WebEngine engine;
WebView wv = new WebView();
engine = wv.getEngine();
engine.setJavaScriptEnabled(true);
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
}};
// Install the all-trusting trust manager
SSLContext sc;
try {
sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
// TODO Auto-generated method stub
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
engine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
public void changed(ObservableValue ov, State oldState, State newState) {
if (newState == State.SUCCEEDED) {
Document doc = engine.getDocument();
// operations on dom occur here.
System.out.println(engine.getLoadWorker().exceptionProperty());
System.out.print("load finished " + doc.getBaseURI());
}
}
});
engine.setOnAlert(new EventHandler<WebEvent<String>>() {
@Override
public void handle(WebEvent<String> event) {
System.out.print("setOnAlert " + event.getData());
}
});
engine.setOnError(new EventHandler<WebErrorEvent>() {
@Override
public void handle(WebErrorEvent event) {
System.out.print("onError " + event.getMessage());
}
});
engine.setConfirmHandler(new Callback<String, Boolean>() {
@Override
public Boolean call(String param) {
// TODO Auto-generated method stub
System.out.print("setConfirmHandler " + param);
return null;
}
});
fxpanel.setScene(new Scene(wv));
engine.load("https://login.microsoftonline.com");
//engine.load("https://facebook.com");
}
});
frame.setVisible(true);
}
}
Upvotes: 1
Views: 3136
Reputation: 1513
It turned out that ANY network problem (DNS/connection) can cause the error and the load will not throw any proper exception. The good news is that if you replace the .load(url) call, at least you will see the problems in the log.
On replacing I mean that load the site separately to a String
private static String getData(String address) throws Exception {
URL page = new URL(address);
StringBuffer text = new StringBuffer();
HttpURLConnection conn = (HttpURLConnection) page.openConnection();
conn.connect();
try (InputStreamReader in = new InputStreamReader(
(InputStream) conn.getContent())) {
BufferedReader buff = new BufferedReader(in);
String line;
do {
line = buff.readLine();
text.append(line + "\n");
} while (line != null);
return text.toString();
} finally {
conn.disconnect();
}
}
And replace the .load:
//engine.load("https://login.microsoftonline.com");
engine.loadContent(getData("https://login.microsoftonline.com"));
Of course, the exception should be catched and logged properly. (The funny thing is that the referenced resources (images/js/css whatever files) will be loaded well in this way too.)
Upvotes: 1