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.
- Call java static method from bash in jshell-
You can use it to execute Java code directly from your shell shown in this example:
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"
If you prefer a more concise feedback mode to skip command and declaration details and filter the result, you can use the following command:
echo 'String.format("%06d", 19)' | jshell --feedback concise \
| sed -n '2p' |sed -En 's/[^\>]\*\>(.+)/\1/gp'
- Java modules provide a structured way to organize your code. They allow you to encapsulate code and manage dependencies effectively. You can leverage JShell to work with Java modules seamlessly. Here’s how you can create a simple utility class within a Java module and run it with JShell.
Create the directory structure and Java classes:
tree common-utils/src common-utils/src
└── com.ts.util
├── com
│ └── ts
│ └── util
│ └── Utils.java
└── module-info.java
- Define a utility class in Utils.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')
- finally, lets test the implementation
java -p mods -m com.ts.util/com.ts.util.Utils
To streamline your JShell experience further, consider creating packages or JAR files for your modules. Here’s how you can create a package or 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-
rahul$ jshell --class-path 'mods/com.ts.util@1.0.jar'
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
Java 9 has brought about significant changes and powerful tools like JShell and modules. Understanding how to use these tools effectively can boost your Java development productivity and make your coding experience more interactive and streamlined.