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

Add TOOLING.jsh load file

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 21
    • tools
    • None
    • minimal
    • New load file added to JShell's built-in resources.
    • Other
    • JDK

      Summary

      Improve access to tools shipping with the JDK within a JShell session.

      Problem

      Users exploring features of Java and the Java Development Kit often want to use tools shipping with it.

      It is laborious to access JDK tools and run them without leaving the context of JShell session: users need to reach out to the single factory method in java.util.spi.ToolFinder, unpack its optional result, pass in streams for expected and error output, and finally create an array of arguments for the tool run.

      Solution

      Add TOOLING.jsh load file to JShell's built-in resources.

      This enables users to source JDK tooling support into the currently running JShell session by the /open command and also from the command line:

      jshell>/open TOOLING

      TOOLING.jsh contains the following accessors as JShell code snippets:

      • tools() Lists all available tools by their name
      • run(String name, String... args) Runs a tool specified by its name and passing a variadic array of arguments

      TOOLING.jsh also contains the following convenient delegating accessors as JShell code snippets:

      • jar(String... args) delegates to run("jar", args)
      • javac(String... args) delegates to run("javac", args)
      • javadoc(String... args) delegates to run("javadoc", args)
      • javap(String... args)delegates to run("javap", args)
      • javap(Class<?> type) delegates to run("javap", "-c", "-v", "-s", TYPE)
      • jdeps(String... args) delegates to run("jdeps", args)
      • jlink(String... args) delegates to run("jlink", args)
      • jmod(String... args) delegates to run("jmod", args)
      • jpackage(String... args) delegates to run("jpackage", args)

      Specification

      TOOLING.jsh

      void jar(String... args) { run("jar", args); }
      void javac(String... args) { run("javac", args); }
      void javadoc(String... args) { run("javadoc", args); }
      void javap(String... args) { run("javap", args); }
      void jdeps(String... args) { run("jdeps", args); }
      void jlink(String... args) { run("jlink", args); }
      void jmod(String... args) { run("jmod", args); }
      void jpackage(String... args) { run("jpackage", args); }
      
      void javap(Class<?> type) throws Exception {
          try {
              var name = type.getCanonicalName();
              if (name == null) throw new IllegalArgumentException("Type not supported: " + type);
              if (type == Class.forName(name, false, ClassLoader.getSystemClassLoader())) {
                  run("javap", "-c", "-v", "-s", name);
                  return;
              }
          } catch (ClassNotFoundException ignored) {
              // fall-through
          }
          var temp = java.nio.file.Files.createTempFile("TOOLING-", ".class");
          try {
              var name = type.getName().replace('.', '/') + ".class";
              try (var in = type.getClassLoader().getResourceAsStream(name);
                   var out = java.nio.file.Files.newOutputStream(temp)) {
                  if (in == null) throw new AssertionError("Resource not found: " + name);
                  in.transferTo(out);
              }
              run("javap", "-c", "-v", "-s", temp.toString());
          } finally {
              java.nio.file.Files.delete(temp);
          }
      }
      
      void run(String name, String... args) {
          var tool = java.util.spi.ToolProvider.findFirst(name);
          if (tool.isEmpty()) throw new RuntimeException("No such tool found: " + name);
          var code = tool.get().run(System.out, System.err, args);
          if (code == 0) return;
          System.err.println(name + " returned non-zero exit code: " + code);
      }
      
      void tools() {
        java.util.ServiceLoader.load(java.util.spi.ToolProvider.class).stream()
            .map(java.util.ServiceLoader.Provider::get)
            .map(java.util.spi.ToolProvider::name)
            .sorted()
            .forEach(System.out::println);
      }

            cstein Christian Stein
            cstein Christian Stein
            Jan Lahoda
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: