Pellucid tutorial using java modules, REPL(READ EVALUATE Print Loop) jshell and how to launch jshell inline command from shell
Jdk-9 is one of the major shift for java developers, it has so many powerful tools and jshell is one of them. Jshell shall be used to run small commands, utilities, expressions, tough it helps to avoid developing many standalone utilities but it shouldn’t be used to run java classes directly.
1. Call java static method from bash in jshell-
echo 'String.format("%06d", 19)'|jshell output: | Welcome to JShell -- Version 9 | For an introduction type: /help intro jshell\> String.format("%06d", 19) $1 ==\> "000019"
Run jshell in concise feedback mode to skip Command and Declaration details and filter result.
echo 'String.format("%06d", 19)' | jshell --feedback concise \ | sed -n '2p' |sed -En 's/[^\>]\*\>(.+)/\1/gp'
2. We can call stanalone java utilities from jshell, below example uses java module and jshell to run custom utilities.
Create below directory structure and java classes
tree common-utils/src common-utils/src └── com.ts.util ├── com │ └── ts │ └── util │ └── Utils.java └── module-info.java
Utils.java
package com.ts.util; import java.util.regex.Pattern; public class Utils { /\*\* \* Regex Replace example using pattern \* @param input source string \* @param regex regex to search pattern \* @param replacement replacement string \* @return \*/ public static String regexReplace(String input, String regex, String replacement){ validateArg(input,"input"); validateArg(input,"regex"); validateArg(input,"replacement"); return Pattern.compile(regex).matcher(input).replaceAll(replacement); } private static void validateArg(String input,String type) { if(input == null || input.isEmpty()){ System.err.println(String.format("%s is blank",type)); System.exit(1); } } }
module-info.java
module com.ts.util {}
Compile module and classes
javac -d mods --module-source-path src $(find src -name '\*.java')
Test
java -p mods -m com.ts.util/com.ts.util.Utils
Create package/jar
jar --create --file=mods/com.ts.util@1.0.jar --module-version=1.0 -C mods/com.ts.util . jar --create --file=mods/com.ts.util.jar --main-class com.ts.util.Utils -C mods/com.ts.util .
View content
tree mods mods ├── com.ts.util │ ├── com │ │ └── ts │ │ └── util │ │ └── Utils.class │ └── module-info.class ├── com.ts.util.jar └── com.ts.util@1.0.jar
All set to test on jshell-
rauls-MacBook-Pro:common-utils rahul$ jshell --class-path 'mods/com.ts.util@1.0.jar' | Welcome to JShell -- Version 9 | For an introduction type: /help intro jshell\> com.ts.util.Utils.regexReplace("jshell hello world","\\s","++") $1 ==\> "jshell++hello++world"
Run from bash
echo 'com.ts.util.Utils.regexReplace("jshell hello world","\\s","++")' | jshell --class-path 'mods/com.ts.util@1.0.jar' --feedback concise |sed -n '2p' | sed -En 's/[^>]*>(.+)/\1/gp'
You can also create one more script that will take argument as java command and run on jshell
echo "$1" | jshell --class-path '/Users/rahul/Documents/jshell-example/common-utils/mods/com.ts.util@1.0.jar' \ --feedback concise |sed -n '2p' | sed -En 's/[^\>]\*\>(.+)/\1/gp'
Execute command using another script
./common-utils/bin/run-jshell.sh 'com.ts.util.Utils.regexReplace("jshell hello world","\\s","++")'