ADDITIONAL SYSTEM INFORMATION :
From what I can tell, it is present on OSes and versions of JavaFX.
A DESCRIPTION OF THE PROBLEM :
If an exception occurs in the showDocument() method (e.g. SecurityException or Exception("No web browser found")), it is not passed to the caller. Instead, a stack trace is printed and execution proceeds. A comment in the catch block states "should not happen" even though the method itself could raise an exception.
Searching the bug database, I find a somewhat related bug (JDK-1262595) that stated:
"showDocument() calls the browser to display the URL, but the browser may not return any notification back when the URL is invalid or failed to be displayed. This is why showDocument() doesn't currently throw exception in the API. Will not fix."
I think this logic may have been approriate in 1996, but does not apply today--particularly with the SecurityException framework.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Create an application that uses a security controller that does not grant the execute permission or run on a system without a browser installed.
2) Call the HostServices.showDocument() method in a try/catch block.
3) Execute the application
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A SecurityException or the "No web browser found" exceptions should be passed to the caller.
ACTUAL -
Execution proceeds without exception.
---------- BEGIN SOURCE ----------
package com.example.showdocbug;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
* JavaFX App
*/
public class App extends Application {
@Override
public void start(Stage stage) {
var policy = App.class.getResource("demo.policy");
System.setProperty(
"java.security.policy",
policy.toString());
System.setSecurityManager(new SecurityManager());
try {
getHostServices().showDocument("irrelevant");
var label = new Label("Should not see this");
var scene = new Scene(new StackPane(label), 640, 480);
stage.setScene(scene);
stage.show();
} catch (Exception e) {
var label = new Label("Should see this");
var scene = new Scene(new StackPane(label), 640, 480);
stage.setScene(scene);
stage.show();
}
}
public static void main(String[] args) {
launch();
}
}
// put in the resources location
// demo.policy
// Security Policy for the Data Manager Tool
// NOTE: Some of the permissions may span grant {} blocks
// Debugging--might be able to turn off in production
grant {
permission java.util.PropertyPermission "jdk.proxy.debug", "read";
};
// Access for files inside the JRE and other fundamental items
grant {
// Allow reading of JRE files
permission java.util.PropertyPermission "java.home", "read";
permission java.io.FilePermission "${java.home}/-", "read";
// System resources--OS dependent
// Linux
permission java.io.FilePermission "/etc/-", "read";
permission java.io.FilePermission "/usr/share/-", "read";
permission java.io.FilePermission "/dev/random", "read";
permission java.io.FilePermission "/dev/urandom", "read";
// MacOS
permission java.io.FilePermission "/System/Library/Fonts/-", "read";
// Windows
// NOTE: Do not forget to escape the '\' character by using "\\"
permission java.io.FilePermission "C:\\WINDOWS\\Fonts\\-", "read";
permission java.io.FilePermission "${user.home}/.m2/-", "read";
};
// SecurityManager
grant {
permission java.security.SecurityPermission "getPolicy";
};
// JavaFX
grant {
permission java.util.PropertyPermission "javafx.*", "read,write";
permission java.util.PropertyPermission "com.sun.javafx.*", "read";
permission java.util.PropertyPermission "embedded", "read";
permission java.util.PropertyPermission "use.*", "read";
permission java.util.PropertyPermission "quantum.*", "read";
permission java.util.PropertyPermission "glass.*", "read";
permission java.util.PropertyPermission "decora.*", "read";
permission java.util.PropertyPermission "prism.*", "read";
permission java.util.PropertyPermission "java.library.path", "read";
permission java.util.PropertyPermission "javax.xml.*", "read";
permission java.util.PropertyPermission "jdk.xml.*", "read";
permission java.util.PropertyPermission "binary.css", "read";
permission java.util.PropertyPermission "entityExpansionLimit", "read";
permission java.util.PropertyPermission "maxOccurLimit", "read";
permission java.util.PropertyPermission "elementAttributeLimit", "read";
permission java.lang.RuntimePermission "modifyThread";
permission java.lang.RuntimePermission "shutdownHooks";
permission java.lang.RuntimePermission "getStackWalkerWithClassReference";
permission java.lang.RuntimePermission "loadLibrary.*";
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.RuntimePermission "getProtectionDomain";
permission java.lang.RuntimePermission "modifyThreadGroup";
permission java.lang.RuntimePermission "setContextClassLoader";
permission java.lang.RuntimePermission "accessSystemModules";
permission java.lang.RuntimePermission "createClassLoader";
permission java.lang.RuntimePermission "localeServiceProvider";
permission java.lang.RuntimePermission "enableContextClassLoaderOverride";
permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
permission java.lang.RuntimePermission "getenv.glass.*";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
permission javafx.util.FXPermission "createTransparentWindow";
permission javafx.util.FXPermission "accessWindowList";
// Are these JavaFX?
permission java.security.SecurityPermission "getProperty.security.provider.*";
permission java.security.SecurityPermission "getProperty.jdk.security.provider.preferred";
permission java.security.SecurityPermission "getProperty.securerandom.source";
permission java.security.SecurityPermission "putProviderProperty.SUN";
// Are these only needed when running with the JDK?
permission java.util.PropertyPermission "jdk.proxy.ProxyGenerator.saveGeneratedFiles", "read";
permission java.util.PropertyPermission "sun.reflect.debugModuleAccessChecks", "read";
};
// File and Network I/O
grant {
permission java.util.PropertyPermission "file.encoding", "read";
permission java.lang.RuntimePermission "readFileDescriptor";
permission java.lang.RuntimePermission "writeFileDescriptor";
permission java.lang.RuntimePermission "selectorProvider";
// Needed for ACL permissions
permission java.lang.RuntimePermission "lookupUserInformation";
// Allow access to the user properties
permission java.util.PropertyPermission "user.*", "read";
// Enable access to logging
permission java.util.logging.LoggingPermission "control";
permission java.lang.RuntimePermission "loggerFinder";
permission java.io.FilePermission "${user.home}", "read,write,delete";
permission java.io.FilePermission "${user.home}/-", "read,write,delete";
};
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Need to wrap the showDocument() to check for security permission, but that does not help with the browser not found exception.
FREQUENCY : always