Execute Java Code Like Unix Shell Script

0 points

By now, most of you might have heard about JDK9 JShell. If you are not aware of it, please click here. In this article, I am going to use JShell to show you how to execute Java code like Unix script. 

Let me show you an example first and then go into details:

  • Open a file and save it with .txt by naming it as java_shell_code.txt

  • Write some Java code and execute the below command by passing the file name as an argument. You don’t need to declare a class. Just write statements or create methods and enjoy functional programming.               

 
 java ex.jshell.extension.JShellScriptExecutor ./java_shell_code.txt
 

 

java_shell.code.txt

 
// java_shell_code.txt contents.
 
 
 
/* If you observe it does not need a class declaration.
 
 Using the power of jshell,
 
 we can write functions and call functions with out creating class,
 
 just like functional programming */
 
 
 
 // You can also include comments like above, anywhere in the script
 
 
 
String var1 = "Hello";
 
System.out.println(var1);
 
 
 
public int getInt1(){
 
    return 2;
 
}
 
 
 
public int getInt2(){
 
    return 4;
 
}
 
 
 
getInt1() + getInt2();
 
 
 
public class MyClass{
 
    public void sayHelloWorld(){
 
        System.out.println("HelloWorld");
 
    }
 
}
 
 
 
new MyClass().sayHelloWorld()
 

 

 
Output of the above script:
 
 
 
"Hello"
 
Hello
 
6
 
HelloWorld
 

 

Let’s get into the details. In JDK 9, the Java team has introduced a new class called JShell.java under the jdk.jshell module. Using this class, we can evaluate Java code snippets, and create Java methods on the fly without declaring a class. If there are any errors in the Java code snippet it will provide a Snippet.status (either REJECTED or VALID). Source code analysiswill analyze the code till the semicolon and also resolves methods or class declarations, if there are any.

Here is the JShellScriptExecutor code. Please feel free to take and extend it as you want. You can also clone it from my GitHub page.

 
package ex.jshell.extension;
 
 
 
import jdk.jshell.JShell;
 
import jdk.jshell.Snippet;
 
import jdk.jshell.SnippetEvent;
 
import jdk.jshell.SourceCodeAnalysis;
 
 
 
import java.io.IOException;
 
import java.nio.file.Files;
 
import java.nio.file.Paths;
 
import java.util.Objects;
 
 
 
/**
 
 * This class can execute jshell expressions in sequence
 
 * We can write java commands like shell script and execute it.
 
 * Just write commands in a way that we give in jshell and save it in a file and execute it.
 
 *
 
 * @author Hemamabara Vamsi, Kotari
 
 * @since 5/27/2017.
 
 */
 
public class JShellScriptExecutor {
 
    public static void main(String[] args){
 
        new JShellScriptExecutor().evaluate(args[0]);
 
    }
 
 
 
    public void evaluate(String scriptFileName){
 
        try(JShell jshell = JShell.create()){
 
          // Handle snippet events. We can print value or take action if evaluation failed.
 
            jshell.onSnippetEvent(snippetEvent -> snippetEventHandler(snippetEvent));
 
 
 
            String scriptContent = new String(Files.readAllBytes(Paths.get(scriptFileName)));
 
            String s = scriptContent;
 
            while (true) {
 
                // Read source line by line till semicolon (;)
 
                SourceCodeAnalysis.CompletionInfo an = jshell.sourceCodeAnalysis().analyzeCompletion(s);
 
                if (!an.completeness().isComplete()) {
 
                    break;
 
                }
 
                // If there are any method declaration or class declaration 
 
                // in new lines, resolve it.
 
                jshell.eval(trimNewlines(an.source()));
 
                // EOF
 
                if (an.remaining().isEmpty()) {
 
                    break;
 
                }
 
                // If there is semicolon, execute next seq
 
                s = an.remaining();
 
            }
 
        } catch (IOException e) {
 
            e.printStackTrace();
 
        }
 
    }
 
 
 
    public void snippetEventHandler(SnippetEvent snippetEvent){
 
        String value = snippetEvent.value();
 
        if(!Objects.isNull(value) && value.trim().length() > 0) {
 
          // Prints output of code evaluation
 
            System.out.println(value);
 
        }
 
 
 
        // If there are any erros print and exit
 
        if(Snippet.Status.REJECTED.equals(snippetEvent.status())){
 
            System.out.println("Evaluation failed : "+snippetEvent.snippet().toString()
 
                                +"\nIgnoring execution of above script");
 
        }
 
    }
 
 
 
    private String trimNewlines(String s) {
 
        int b = 0;
 
        while (b < s.length() && s.charAt(b) == '\n') {
 
            ++b;
 
        }
 
        int e = s.length() -1;
 
        while (e >= 0 && s.charAt(e) == '\n') {
 
            --e;
 
        }
 
        return s.substring(b, e + 1);
 
    }
 
 
 
}
 

 

module-info.java

 
module ex.jshell.extension{   
 
  requires jdk.jshell;
 
}
 

Enjoy the power of JShell and this class and start writing Java code like a Unix script and execute it like the way we execute .sh. Hope you like it!

Submit reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Login

Sign in to alux.com or create an account

Lost password?

Signup

If you already have an account, please sign in

Forgot Password

Please enter your username or e-mail address to recover your password.

Hey there!

In order to submit a post to Alux.com you must be logged in.

Already have an account? Click here to sign in