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

JShell throws NullPointerException while translating stack trace without source

XMLWordPrintable

    • x86
    • os_x

      ADDITIONAL SYSTEM INFORMATION :
      OS X Mojave, openjdk 11/12/13

      A DESCRIPTION OF THE PROBLEM :
      JShell Eval translateExceptionStack uses a dangerous string comparison: `r.getFileName().equals("<none>")`.
      StackTraceElement.getFileName javadoc states that it may return "...{@code null} if this information is unavailable."

      Therefore, it is important that the constant "none" is on the left side of the `equals` invocation.

      Additionally, it would be nice if the `JShellToolProvider.run` either re-throws the caught `ex`, or at least prints the stack trace. Most exceptions have helpful messages but it is often very helpful to have the stack trace as well. Consuming the exception with no opportunity to print the stack trace made diagnosing this issue more difficult.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      In JShell, throw an exception where at least one frame is a Proxy invocation (or other source-less frame)

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The `jshell` session prints the originally thrown exception and stack trace
      ACTUAL -
      java.lang.NullPointerException
      at jdk.jshell/jdk.jshell.Eval.translateExceptionStack(Eval.java:1098)
      at jdk.jshell/jdk.jshell.Eval.asEvalException(Eval.java:896)
      at jdk.jshell/jdk.jshell.Eval.declare(Eval.java:855)
      at jdk.jshell/jdk.jshell.Eval.eval(Eval.java:140)
      at jdk.jshell/jdk.jshell.JShell.eval(JShell.java:493)
      at jdk.jshell/jdk.internal.jshell.tool.JShellTool.processSource(JShellTool.java:3547)
      at jdk.jshell/jdk.internal.jshell.tool.JShellTool.processSourceCatchingReset(JShellTool.java:1301)
      at jdk.jshell/jdk.internal.jshell.tool.JShellTool.processInput(JShellTool.java:1203)
      at jdk.jshell/jdk.internal.jshell.tool.JShellTool.run(JShellTool.java:1176)
      at jdk.jshell/jdk.internal.jshell.tool.JShellTool.startUpRun(JShellTool.java:1143)
      at jdk.jshell/jdk.internal.jshell.tool.JShellTool.resetState(JShellTool.java:1099)
      at jdk.jshell/jdk.internal.jshell.tool.JShellTool.start(JShellTool.java:933)
      at jdk.jshell/jdk.internal.jshell.tool.JShellToolBuilder.start(JShellToolBuilder.java:254)
      at jdk.jshell/jdk.internal.jshell.tool.JShellToolProvider.run(JShellToolProvider.java:94)
      at JshellNpe.main(JshellNpe.java:20)

      ---------- BEGIN SOURCE ----------

      import java.lang.reflect.Proxy;
      import java.nio.file.Files;
      import java.util.ServiceLoader;
      import java.util.ServiceLoader.Provider;
      import javax.tools.Tool;

      public class JshellNpe {
          public static void main(String... args) throws Exception {
              final var shellStart = Files.createTempFile("init", "jsh");
              Files.writeString(shellStart, String.format("%s.init();", JshellNpe.class.getName()));
              shellStart.toFile().deleteOnExit();

              ServiceLoader.load(Tool.class).stream()
                  .map(Provider::get)
                  .filter(t -> t.name().equals("jshell"))
                  .findAny()
                  .orElseThrow()
                  .run(System.in, System.out, System.err, new String[] {
                          "--startup", shellStart.toString(),
                          "--class-path", System.getProperty("java.class.path")});
          }

          public static void init() {
              Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] {},
                      (p, m, a) -> { throw new IllegalStateException("This helpful exception message is lost"); })
                  .hashCode();
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Attach a debugger and breakpoint on exception to diagnose. Very unpleasant!

      FREQUENCY : always


            fmatte Fairoz Matte
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: