Introduction to jshell/REPL and how to launch inline command in jshell from shell

Introduction to jshell/REPL and how to launch inline command in jshell from shell

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","++")'

Fork on github to download full source code

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.