jeval - command line Java code evaluator. It is similar to JShell except it provides you additional functionality.
jeval allows you to execute Java code straight from the command line (same as you would do with perl -e, bash -c):
In JShell to achieve that you need to use additional command like echo for example:
Additionally with jeval you can execute complete Java shell scripts and see compilation errors if any:
With JShell you would have to use "/exit" in the end (otherwise it will start interactive mode):
And JShell will not print you any errors:
Another nice feature of jeval is that you can use pipes to pass data to your Java code (it binds all standard streams to support lazy reading from stdin predefined variable which is described later):
For JShell there is no default support of that.
With jeval you can pass arguments to your Java scripts and handle them in same way as you do it in Java (through global args variable similar as in main() function):
jeval does not require you to write class body with main method and all boilerplate code (but you still can do it if you want). You just write Java as you would do it with JShell.
You can download jeval from here
Java 11
Run following command if you use bash:
Or in case you use zsh:
Open cmd and execute following command:
jeval [ <JAVA_SCRIPT> | -e <JAVA_SNIPPET> | -i ] [ARGS]
Where:
Options:
To add new JAR files into class path use CLASSPATH env variable:
To pass arguments to the JVM use JAVA_ARGS env variable:
jeval provides you with some additional commands which you can put to your Java script files. All of them can be called from Java comments only (it helps to keep Java code in your scripts clean an easily compilable later with javac, or within any IDEs)
This command allows you to include dependencies to any artifacts from Maven repository into the Java script files. Without need to create pom.xml or build.gradle for that.
Format of this command is:
//dependency ARTIFACT_NAME
Where ARTIFACT_NAME is a full name of the artifact in the format: <groupId>:<artifactId>[:<extension>[:<classifier>]]:<version>
Here is an example of simple script yaml.java which declares dependency on snakeyaml library and uses it:
//dependency org.yaml:snakeyaml:1.21 import org.yaml.snakeyaml.*; Yaml yaml = new Yaml(); String document = "\n- Hesperiidae\n- Papilionidae\n- Apatelodidae\n- Epiplemidae"; Listlist = (List ) yaml.load(document); System.out.println(list);
To run:
[Hesperiidae, Papilionidae, Apatelodidae, Epiplemidae]
To provide this functionality jeval integrates with depresolve tool which depends on maven-resolver library
jeval supports "//open" command similar to "/open" command which JShell provides. For example using that command you can extract some common logic into separate script file so jeval will read that.
For example here we keep parsing functions in script called parsers.java:
String parseToHex(int num) { return Integer.toHexString(num); }
And use them from script called script.java:
//open parsers.java printf(parseToHex(123) + "\n");
Now run:
7b
Here in script.java we include parsers.java and then call parseToHex method defined there.
jeval by default imports following packages and static methods to the global space so you don't need to worry to import them each time manually:
java.util.stream.IntStream.* java.util.stream.Collectors.* java.lang.System.* java.nio.file.Files.* java.lang.Math.* java.util.Arrays.* javax.script.* java.lang.String.* jdk.nashorn.api.scripting.* java.util.* java.util.stream.* java.util.concurrent.* java.util.function.* java.util.regex.* java.io.* java.nio.* java.nio.file.* javax.xml.parsers.* javax.xml.xpath.* java.net.* java.net.http.* java.net.http.HttpResponse.* org.w3c.dom.* org.xml.sax.* java.time.* java.time.format.*
jeval comes with xfunction library and exports most of it classes and methods to global space as well.
String[] args
Arguments (if any) passed to the Java script
BufferedReader stdin
This is an instance of java.io.BufferedReader connected to System.in which allows you to operate with System.in as with stream of lines which is often useful when writing scripts (see Snippets section).
Optional<Path> scriptPath
Contains path to currently executing script. It is empty when used in Java snippets (jeval with -e option)
In addition to them jeval exports following variables from xfunction library:
void sleep(long msec)
Standard way to sleep in Java is pretty verbose because it throws checked exception which you need to handle:
try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); }
When you write scripts in Java you probably want it to fit in one line and wrap any thrown exception to unchecked. With this function now you can sleep like that:
sleep(1000);
void error(String msg)
Throws RuntimeException with a given message
void assertTrue(boolean expr)
If expr is false throw RuntimeException
void assertTrue(boolean expr, String message)
If expr is false throw RuntimeException with message
Stream<String> findMatches(String regexp, String str)
Search string for substrings which satisfy the regexp and return them in a stream
Implements netcat operations:
static void listen(int port)
static void connect(String host, int port)
All input/output goes through stdin/stdout.
jeval supports "#!" interpreter directive which is available in Unix-like operating systems.
It allows instead of calling jeval each time to execute Java script:
To run it directly as ordinary executable file:
For that to work you need to put following line as a first line of script.java:
#!/usr/bin/env jeval
And make file executable:
Here are some examples of calling Java standard classes with jeval right from the command line.
Here is an example which creates 20 files with random names doing this in parallel on different threads:
With -e option jeval evaluates the expression and prints its result. In this case method PrintStream::format returns reference to PrintStream so that is why it is printed.
To overcome this you can use printf method defined by jeval.
Those are generated by JShell. Most likely you run multiple threads and some of them try to execute unresolved snippets. Wait until jeval finishes then search for its diagnostics in stderr.