From 7d76a34eeba734e736f1169983f02bce445eb755 Mon Sep 17 00:00:00 2001 From: Mariano Ruiz Date: Mon, 2 Mar 2020 17:04:42 -0300 Subject: [PATCH 1/3] Make the project compatible with multi-module projects, improve classpath logging - Add dependsOn 'classes' only if the task is registered, otherwise let the task without dependencies and warn that the project need to be compiled first (multi-modules projects may not have the :classes task available) - Takes classpath paths from project and subprojects if exist. Also use `JavaExec` instead of `JavaCompile` to scan not just the "implementation" dependencies (or "compile") but also scan the "runtimeOnly" dependencies (or "runtime") - Add some logging - Remove unused imports --- .../gradle/plugin/JShellGradlePlugin.groovy | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/main/groovy/net/java/openjdk/shinyafox/jshell/gradle/plugin/JShellGradlePlugin.groovy b/src/main/groovy/net/java/openjdk/shinyafox/jshell/gradle/plugin/JShellGradlePlugin.groovy index 3308414..0ceba68 100644 --- a/src/main/groovy/net/java/openjdk/shinyafox/jshell/gradle/plugin/JShellGradlePlugin.groovy +++ b/src/main/groovy/net/java/openjdk/shinyafox/jshell/gradle/plugin/JShellGradlePlugin.groovy @@ -1,32 +1,37 @@ package net.java.openjdk.shinyafox.jshell.gradle.plugin -import java.io.File import jdk.internal.jshell.tool.JShellToolProvider - import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.tasks.compile.JavaCompile - -import java.nio.file.Files -import java.nio.file.Paths +import org.gradle.api.tasks.JavaExec class JShellGradlePlugin implements Plugin { @Override void apply(Project project) { - project.tasks.create('jshell') - .dependsOn("classes") - .doLast { - def path - project.tasks.withType(JavaCompile) { - path = classpath.findAll{ it.exists() }.join( - System.properties['os.name'].toLowerCase().contains('windows') ? ';' : ':' - ) + def jshellTask = project.tasks.create('jshell') + def classesTask = project.tasks.find { it.name == "classes" } + if (classesTask) { + jshellTask.dependsOn classesTask + } + if (jshellTask.dependsOn.empty) { + // Some multi-module projects may not have the :classes task + jshellTask.logger.warn ":jshell task :classes not found, be sure to compile the project first" + } + jshellTask.doLast { + Set pathSet = [] + project.tasks.withType(JavaExec) { + pathSet.addAll(classpath.findAll{ it.exists() }) + } + project.subprojects.each { + it.tasks.withType(JavaExec) { + pathSet.addAll(classpath.findAll{ it.exists() }) + } } - Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader()) // promote class loader + def path = pathSet.join(System.properties['os.name'].toLowerCase().contains('windows') ? ';' : ':') + jshellTask.logger.debug(":jshell executing with --class-path \"{}\"", path) JShellToolProvider.main((String[])["--class-path", path].toArray()); } } - } From 7352b7ba34704539af4cb8cd4149729c8a1f3f79 Mon Sep 17 00:00:00 2001 From: Mariano Ruiz Date: Mon, 2 Mar 2020 17:20:29 -0300 Subject: [PATCH 2/3] Use `JavaShellToolBuilder` to create the jshell console instead of the internal class `JShellToolProvider` - The change allows to avoid the need to use special java options to run the task - Improvements in README doc --- README.md | 26 +++++++++++++++---- .../gradle/plugin/JShellGradlePlugin.groovy | 4 +-- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 40bebe9..3bd817d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,15 @@ # jshell-gradle-plugin -This gradle plugin helps you to explore your code and dependency in your gradle project with in jshell -- the official Java REPL tool. + +This gradle plugin helps you to explore your code and dependencies in your gradle project +with in [jshell](https://docs.oracle.com/javase/9/jshell/introduction-jshell.htm) -- the official Java REPL tool. Hosted on https://plugins.gradle.org/plugin/net.java.openjdk.shinyafox.jshell.gradle.plugin + ## Getting started + To use this plugin, add following to your `build.gradle`: + ``` buildscript { repositories { @@ -31,11 +36,22 @@ plugins { Task `jshell` is now enabled, which execute jshell with your classes and dependencies after compiling your code. -Currently we need to run the task with some hacks for JDK9. -Add a path for your jdk9 to `JAVA_HOME` and some options to JAVA_OPTS, and run task `jshell` with `--no-daemon --console plain` for gradle options. +You need to run the task `jshell` with the options `--no-daemon --console plain`. Following is an example with gradlew: + ``` -JAVA_HOME=/path/to/your/jdk9 \ -JAVA_OPTS="--add-exports jdk.jshell/jdk.internal.jshell.tool=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED"\ ./gradlew --no-daemon --console plain jshell ``` + +If you see this warning and the jshell console does not detect your classes: + +> :jshell task :classes not found, be sure to compile the project first + +Means the `classes` task needed to compile your project before launch `jshell` +does not exist, just append the task needed to compile the project, +some time is the same `classes` task but is not detected in multi-modules +projects, so you need to add it explicitly in the Gradle command: + +``` +./gradlew --no-daemon --console plain classes jshell +``` diff --git a/src/main/groovy/net/java/openjdk/shinyafox/jshell/gradle/plugin/JShellGradlePlugin.groovy b/src/main/groovy/net/java/openjdk/shinyafox/jshell/gradle/plugin/JShellGradlePlugin.groovy index 0ceba68..c35cd50 100644 --- a/src/main/groovy/net/java/openjdk/shinyafox/jshell/gradle/plugin/JShellGradlePlugin.groovy +++ b/src/main/groovy/net/java/openjdk/shinyafox/jshell/gradle/plugin/JShellGradlePlugin.groovy @@ -1,6 +1,6 @@ package net.java.openjdk.shinyafox.jshell.gradle.plugin -import jdk.internal.jshell.tool.JShellToolProvider +import jdk.jshell.tool.JavaShellToolBuilder import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.tasks.JavaExec @@ -31,7 +31,7 @@ class JShellGradlePlugin implements Plugin { Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader()) // promote class loader def path = pathSet.join(System.properties['os.name'].toLowerCase().contains('windows') ? ';' : ':') jshellTask.logger.debug(":jshell executing with --class-path \"{}\"", path) - JShellToolProvider.main((String[])["--class-path", path].toArray()); + JavaShellToolBuilder.builder().run((String[])["--class-path", path].toArray()) } } } From e83ec2a0d65197700ec8e93ff0c8d87dcd600db5 Mon Sep 17 00:00:00 2001 From: Mariano Ruiz Date: Mon, 2 Mar 2020 19:03:51 -0300 Subject: [PATCH 3/3] Minor if-else refactor --- .../shinyafox/jshell/gradle/plugin/JShellGradlePlugin.groovy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/groovy/net/java/openjdk/shinyafox/jshell/gradle/plugin/JShellGradlePlugin.groovy b/src/main/groovy/net/java/openjdk/shinyafox/jshell/gradle/plugin/JShellGradlePlugin.groovy index c35cd50..1aef91f 100644 --- a/src/main/groovy/net/java/openjdk/shinyafox/jshell/gradle/plugin/JShellGradlePlugin.groovy +++ b/src/main/groovy/net/java/openjdk/shinyafox/jshell/gradle/plugin/JShellGradlePlugin.groovy @@ -13,8 +13,7 @@ class JShellGradlePlugin implements Plugin { def classesTask = project.tasks.find { it.name == "classes" } if (classesTask) { jshellTask.dependsOn classesTask - } - if (jshellTask.dependsOn.empty) { + } else { // Some multi-module projects may not have the :classes task jshellTask.logger.warn ":jshell task :classes not found, be sure to compile the project first" }