Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8264698

HostServices.showDocument() should throw exception if browser fails to launch

    XMLWordPrintable

    Details

    • Type: Enhancement
    • Status: Open
    • Priority: P4
    • Resolution: Unresolved
    • Affects Version/s: openjfx11
    • Fix Version/s: tbd
    • Component/s: javafx
    • Subcomponent:
    • CPU:
      x86_64
    • OS:
      linux

      Description

      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


        Attachments

        1. App.java
          1 kB
        2. demo.policy
          4 kB
        3. Capture.PNG
          Capture.PNG
          166 kB

          Activity

            People

            Assignee:
            Unassigned Unassigned
            Reporter:
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated: