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

System.setSecurityManager breaks javafx 9 application using java web start

    Details

    • Subcomponent:
    • CPU:
      x86
    • OS:
      generic

      Description

      FULL PRODUCT VERSION :
      java version "9"
      Java(TM) SE Runtime Environment (build 9+181)
      Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)

      A DESCRIPTION OF THE PROBLEM :
      We have a java web start application that's working on java 8, but when running on Java 9 it crashes. The application loads a new JavaFx scene that contains a webview which shows a web page that contains a menu, that menu contains different buttons, each button opens a new window which content uses thinlet. For security reasons, we're encrypting the jar. So when we run the application we replace the classloader with our own classloader that will first dencrypt the encrypted classes of the jar. On click any of the buttons we use our own classloader to call the encrypted class using reflection and make the default classloader of that class our own, so all the rest of the classes will be able to be launched after dencrypt it. That's working fine until java 8. However on running the application on java 9, the first time I click any of the buttons the application is properly launched but after that every time I click the buttons I'm getting the a java.lang.reflect.InvocationTargetException caused by a java.lang.NullPointerException at jdk classes.
      I've found that the problem is coming on set the security manager. If I comment that line, my simple program works. However, we have to replace the classloader in order to have some permissions.
      I've also posted at https://stackoverflow.com/questions/45693563/java-web-start-invocationtargetexception-with-java-9-ea

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create a class that extends a region, contains a WebView and includes a method used to launch classes(with reflection) using a new classloader that sets the security manager to null. On change the location at the WebView url launches a new Frame using the mentioned launch method. The first frame will be launched but the second and on will fail with java.lang.reflect.InvocationTargetException.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      java.lang.reflect.InvocationTargetException
          at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
          at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
          at java.base/java.lang.reflect.Method.invoke(Unknown Source)
          at com.glt.cryptoclass.DecryptingClassLoader$PrivilegedLaunch.run(DecryptingClassLoader.java:56)
          at java.base/java.security.AccessController.doPrivileged(Native Method)
          at com.glt.cryptoclass.DecryptingClassLoader.launch(DecryptingClassLoader.java:179)
          at com.glt.replace.Browser$1.call(Browser.java:58)
          at com.glt.replace.Browser$1.call(Browser.java:42)
          at javafx.graphics/javafx.concurrent.Task$TaskCallable.call(Unknown Source)
          at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
          at java.base/java.lang.Thread.run(Unknown Source)
      Caused by: java.lang.NullPointerException
          at java.desktop/java.awt.Window.addToWindowList(Unknown Source)
          at java.desktop/java.awt.Window.init(Unknown Source)
          at java.desktop/java.awt.Window.<init>(Unknown Source)
          at java.desktop/java.awt.Frame.<init>(Unknown Source)
          at com.thinlet.FrameLauncher.<init>(FrameLauncher.java:32)
          at com.glt.replace.start.miau(start.java:32)
          at com.glt.replace.start.main(start.java:22)
          ... 12 more
      ACTUAL -
      The first time the frame will be launch the second will fail

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.lang.reflect.InvocationTargetException
          at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
          at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
          at java.base/java.lang.reflect.Method.invoke(Unknown Source)
          at com.glt.cryptoclass.DecryptingClassLoader$PrivilegedLaunch.run(DecryptingClassLoader.java:56)
          at java.base/java.security.AccessController.doPrivileged(Native Method)
          at com.glt.cryptoclass.DecryptingClassLoader.launch(DecryptingClassLoader.java:179)
          at com.glt.replace.Browser$1.call(Browser.java:58)
          at com.glt.replace.Browser$1.call(Browser.java:42)
          at javafx.graphics/javafx.concurrent.Task$TaskCallable.call(Unknown Source)
          at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
          at java.base/java.lang.Thread.run(Unknown Source)
      Caused by: java.lang.NullPointerException
          at java.desktop/java.awt.Window.addToWindowList(Unknown Source)
          at java.desktop/java.awt.Window.init(Unknown Source)
          at java.desktop/java.awt.Window.<init>(Unknown Source)
          at java.desktop/java.awt.Frame.<init>(Unknown Source)
          at com.thinlet.FrameLauncher.<init>(FrameLauncher.java:32)
          at com.glt.replace.start.miau(start.java:32)
          at com.glt.replace.start.main(start.java:22)
          ... 12 more

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      Launch method:
      public void launch(final String className, final String[] args) {
              try {
                  initWebView();
                  //start new thread to the new window
                  javafx.concurrent.Task configTask = new javafx.concurrent.Task<Void>() {
                      @Override
                      protected Void call() {
                          //ModConfig.main(args) // ModBrowser.main(args);
                          try {
                              if (dcl == null) {
                                  KeyGetter key = new KeyGetter("https://www.telekey.nl/", "getReplaceKeyDetails.jsp");
      //
                                  key.fetchKeyDetails();
                                  System.out.println(".actionPerformed(): DEBUG. key details: "
                                          + key.getAlgorithm() + "\n"
                                          + key.getCypherDesc() + "\n"
                                          + key.getRawKey());
      // dcl = new DecryptingClassLoader(key);
                                  dcl = new MyClassloader(key);
                                  System.out.println(".call(). mioau!!!!!");
                              }
                              Class[] parTypes = {String[].class};
                              System.out.println(".call(). DEBUG: launching...");
                              dcl.launch(className, "main", args, parTypes, true);

                          } catch (Exception ex) {
                              System.out.println(".call(). ERRIR: " + ex.getLocalizedMessage());
                              ex.printStackTrace();
                          } catch (Throwable t){
                              System.out.println(".call(). Throwable ERROR: " + t.getLocalizedMessage() + "\n->" + t.getMessage());
                          } finally {
                              return null;
                          }
                      }
                  };
                  new Thread(configTask).start();
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          }
      Call to the launch method:
      public void processNewLocation(String newLocation){
              String []args = null;
              if(newLocation != null && !newLocation.equals("https://www.google.nl/")){
                  launch("com.glt.replace.start", args);
              }
          }
      My Classloader replacement:
      private void replaceClassLoaders() {
              try {
                  primitiveClassLoader = this.getClass().getClassLoader();
                  System.out.println("Starting Security Manager replacement. Current=" + System.getSecurityManager());
                  System.setSecurityManager(null);
                  System.out.println("Replacement finished. Current Security Manager=" + System.getSecurityManager());

              } catch (IllegalArgumentException ex) {
                  ex.printStackTrace();
              } catch (SecurityException ex) {
                  ex.printStackTrace();
              } catch (Throwable t) {
                  System.out.println("com.glt.replace.MyClassloader.replaceClassLoaders(). ERROR: " + t.getLocalizedMessage());
              }
          }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      If I run the application locally works, but if I run a remote jar using a jnlp file it fails.

        Attachments

          Activity

            People

            • Assignee:
              pardesha Pardeep Sharma
              Reporter:
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: