Java : JShell with Examples
JShell (Java SE 18 & JDK 18) API Examples.
You will find code examples on most JShell methods.
Summary
try (final var js = JShell.create()) {
js.eval("int x = 2;");
js.eval("int y = 3;");
js.eval("int z = x * y;");
js.variables().forEach(varSnippet -> {
System.out.printf("source [ %s ] : value [ %s ]%n",
varSnippet.source(), js.varValue(varSnippet));
});
}
// Result
// ↓
//source [ int x = 2; ] : value [ 2 ]
//source [ int y = 3; ] : value [ 3 ]
//source [ int z = x * y; ] : value [ 6 ]
See also : Introduction to JShell (Java SE 18)
Methods
void addToClasspath (String path)
// --- PowerShell ---
//PS R:\java-work> cat .\aaa\Sample.java
//package aaa;
//
//public class Sample {
//
// public int sum(int x, int y) {
// return x + y;
// }
//}
//
//PS R:\java-work> javac .\aaa\Sample.java
//
//PS R:\java-work> ls -Name aaa
//Sample.class
//Sample.java
try (final var js = JShell.create()) {
final var path = Path.of("R:", "java-work");
System.out.println(path); // R:\java-work
js.addToClasspath(path.toString());
js.eval("import aaa.Sample;");
js.eval("var sample = new Sample();");
js.eval("var a = sample.sum(2, 3);");
js.eval("System.out.println(a);"); // 5
}
static JShell.Builder builder ()
final var os = new ByteArrayOutputStream();
try (final var ps = new PrintStream(os)) {
final var builder = JShell.builder();
try (final var js = builder.out(ps).build()) {
js.eval("""
System.out.println("abcd");
""");
}
}
System.out.println(os); // "abcd"
void close ()
An example with try-with-resources.
try (final var js = JShell.create()) {
js.eval("System.out.println(\"abcd\");"); // "abcd"
}
An example without try-with-resources.
final var js = JShell.create();
try {
js.eval("System.out.println(\"abcd\");"); // "abcd"
} finally {
js.close();
}
static JShell create ()
try (final var js = JShell.create()) {
js.eval("int x = 2;");
js.eval("int y = 3;");
js.eval("int z = x * y;");
js.variables().forEach(varSnippet -> {
System.out.printf("source [ %s ] : value [ %s ]%n",
varSnippet.source(), js.varValue(varSnippet));
});
}
// Result
// ↓
//source [ int x = 2; ] : value [ 2 ]
//source [ int y = 3; ] : value [ 3 ]
//source [ int z = x * y; ] : value [ 6 ]
Stream<Diag> diagnostics (Snippet snippet)
try (final var js = JShell.create()) {
// This input code is intentionally missing.
final var events = js.eval("int x = ");
events.forEach(event -> {
System.out.println(event.status()); // REJECTED
js.diagnostics(event.snippet()).forEach(diag -> {
System.out.println(diag.isError()); // true
System.out.println(diag.getCode()); // compiler.err.premature.eof
// "reached end of file while parsing"
System.out.println(diag.getMessage(Locale.getDefault()));
});
});
}
List<SnippetEvent> drop (Snippet snippet)
try (final var js = JShell.create()) {
final var events1 = js.eval("int x = 1;");
events1.forEach(event -> {
System.out.println(event.status()); // VALID
});
final var events2 = js.eval("System.out.println(x);"); // 1
events2.forEach(event -> {
System.out.println(event.status()); // VALID
});
// Drop the variable x.
events1.forEach(event -> {
js.drop(event.snippet());
});
final var events3 = js.eval("System.out.println(x);");
events3.forEach(event -> {
System.out.println(event.status()); // REJECTED
js.diagnostics(event.snippet()).forEach(diag -> {
//cannot find symbol
// symbol: variable x
// location: class
System.out.println(diag.getMessage(Locale.getDefault()));
});
});
}
List<SnippetEvent> eval (String input)
try (final var js = JShell.create()) {
js.eval("int x = 2;");
js.eval("int y = 3;");
js.eval("int z = x * y;");
js.variables().forEach(varSnippet -> {
System.out.printf("source [ %s ] : value [ %s ]%n",
varSnippet.source(), js.varValue(varSnippet));
});
}
// Result
// ↓
//source [ int x = 2; ] : value [ 2 ]
//source [ int y = 3; ] : value [ 3 ]
//source [ int z = x * y; ] : value [ 6 ]
try (final var js = JShell.create()) {
js.eval("""
class A {
String getMessage() {
return "abcd";
}
}
""");
js.eval("var a = new A();");
js.eval("var message = a.getMessage();");
js.eval("System.out.println(message);"); // "abcd"
}
Stream<ImportSnippet> imports ()
try (final var js = JShell.create()) {
js.eval("import java.nio.file.Path;");
js.eval("import java.time.LocalDate;");
final var imports = js.imports();
imports.forEach(importSnippet -> {
System.out.println(importSnippet);
});
// Result
// ↓
//Snippet:ImportKey(Path,SINGLE_TYPE_IMPORT_SUBKIND)#1-import java.nio.file.Path;
//Snippet:ImportKey(LocalDate,SINGLE_TYPE_IMPORT_SUBKIND)#2-import java.time.LocalDate;
}
Stream<MethodSnippet> methods ()
try (final var js = JShell.create()) {
js.eval("int sum(int x, int y) { return x + y; }");
js.eval("int a = sum(2, 3);");
js.eval("System.out.println(a);"); // 5
js.eval("int sub(int x, int y) { return x - y; }");
js.eval("int b = sub(10, 2);");
js.eval("System.out.println(b);"); // 8
final var methods = js.methods();
System.out.println("-- methods --");
methods.forEach(methodSnippet -> {
System.out.println(methodSnippet);
});
// Result
// ↓
//-- methods --
//MethodSnippet:sum/(int,int)int-int sum(int x, int y) { return x + y; }
//MethodSnippet:sub/(int,int)int-int sub(int x, int y) { return x - y; }
}
JShell.Subscription onShutdown (Consumer<JShell> listener)
final var listener = new Consumer<JShell>() {
@Override
public void accept(JShell jShell) {
System.out.println("shutdown!");
}
};
System.out.println("-- start --");
try (final var js = JShell.create()) {
js.onShutdown(listener);
js.eval("int a = 2 + 3;");
js.eval("System.out.println(a);");
}
System.out.println("-- end --");
// Result
// ↓
//-- start --
//5
//shutdown!
//-- end --
JShell.Subscription onSnippetEvent (Consumer<SnippetEvent> listener)
final var listener = new Consumer<SnippetEvent>() {
@Override
public void accept(SnippetEvent event) {
System.out.println(" -- onSnippetEvent start --");
System.out.println(" event : " + event.status());
final var snippet = event.snippet();
System.out.println(" snippet kind : " + snippet.kind());
System.out.println(" snippet source : " + snippet.source());
System.out.println(" -- onSnippetEvent end --");
}
};
System.out.println("-- start --");
try (final var js = JShell.create()) {
js.onSnippetEvent(listener);
js.eval("int a = 2 + 3;");
js.eval("System.out.println(\"a = \" + a);");
}
System.out.println("-- end --");
// Result
// ↓
//-- start --
// -- onSnippetEvent start --
// event : VALID
// snippet kind : VAR
// snippet source : int a = 2 + 3;
// -- onSnippetEvent end --
//a = 5
// -- onSnippetEvent start --
// event : VALID
// snippet kind : STATEMENT
// snippet source : System.out.println("a = " + a);
// -- onSnippetEvent end --
//-- end --
Stream<Snippet> snippets ()
try (final var js = JShell.create()) {
js.eval("int x = 2;");
js.eval("int y = 3;");
js.eval("int a = x + y;");
js.eval("System.out.println(a);"); // 5
final var snippets = js.snippets();
System.out.println("-- snippets --");
snippets.forEach(snippet -> {
System.out.println(snippet);
});
// Result
// ↓
//-- snippets --
//Snippet:VariableKey(x)#1-int x = 2;
//Snippet:VariableKey(y)#2-int y = 3;
//Snippet:VariableKey(a)#3-int a = x + y;
//Snippet:StatementKey#4-System.out.println(a);
}
SourceCodeAnalysis sourceCodeAnalysis ()
try (final var js = JShell.create()) {
final var analysis = js.sourceCodeAnalysis();
final var input = """
int sum(int x, int y) { return x + y; }
System.out.println(sum(2, 3));
""";
// The input string with more than one snippet will fail.
js.eval(input).forEach(event -> {
System.out.println(event.status()); // REJECTED
});
final var completion = analysis.analyzeCompletion(input);
final var source = completion.source();
System.out.println(source); // int sum(int x, int y) { return x + y; }
js.eval(source).forEach(event -> {
System.out.println(event.status()); // VALID
});
final var remaining = completion.remaining();
System.out.println(remaining); // System.out.println(sum(2, 3));
js.eval(remaining); // 5
}
Snippet.Status status (Snippet snippet)
try (final var js = JShell.create()) {
js.eval("int x = 2;");
js.eval("int y = 3;");
// This input code is intentionally missing.
js.eval("int z = x * ");
System.out.println("-- status --");
js.snippets().forEach(snippet -> {
final var status = js.status(snippet);
System.out.println(status);
});
// Result
// ↓
//-- status --
//VALID
//VALID
//REJECTED
}
void stop ()
final var scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
try (final var js = JShell.create()) {
scheduledExecutorService.schedule(() -> {
System.out.println("-- JShell stop! --");
js.stop();
}, 2, TimeUnit.SECONDS);
final var start = System.nanoTime();
System.out.println("sleep start");
js.eval("Thread.sleep(5000);");
System.out.println("sleep end : " + (System.nanoTime() - start) / 1000000000.0 + " sec.");
} finally {
scheduledExecutorService.shutdown();
}
final var ret = scheduledExecutorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("term : " + ret);
// Result
// ↓
//sleep start
//-- JShell stop! --
//sleep end : 2.0477107 sec.
//term : true
Stream<TypeDeclSnippet> types ()
try (final var js = JShell.create()) {
js.eval("""
class A {
String getMessage() {
return "abcd";
}
}
""");
js.eval("var a = new A();");
js.eval("System.out.println(a.getMessage());"); // "abcd"
js.eval("""
class B {
}
""");
final var types = js.types();
System.out.println("-- types --");
types.forEach(type -> {
System.out.println(type);
});
// Result
// ↓
//-- types --
//Snippet:ClassKey(A)#1-class A {
// String getMessage() {
// return "abcd";
// }
//}
//
//Snippet:ClassKey(B)#4-class B {
//}
}
Stream<String> unresolvedDependencies (DeclarationSnippet snippet)
try (final var js = JShell.create()) {
final var events = js.eval("int calc(int x) { return x * AAA; } ");
events.forEach(event -> {
System.out.println(event.status()); // RECOVERABLE_DEFINED
if (event.snippet() instanceof DeclarationSnippet snippet) {
final var stream = js.unresolvedDependencies(snippet);
stream.forEach(s -> {
// "variable AAA"
System.out.println(s);
});
}
});
js.eval("var AAA = 3;");
js.eval("System.out.println(calc(10));"); // 30
}
void unsubscribe (JShell.Subscription token)
try (final var js = JShell.create()) {
js.onShutdown(j -> {
System.out.println("shutdown!");
});
js.eval("System.out.println(\"abcd\");"); // "abcd"
}
// Result
// ↓
//abcd
//shutdown!
try (final var js = JShell.create()) {
final var token = js.onShutdown(j -> {
System.out.println("shutdown!");
});
js.eval("System.out.println(\"abcd\");"); // "abcd"
js.unsubscribe(token);
}
// Result
// ↓
//abcd
Stream<VarSnippet> variables ()
Please see eval(String input).
String varValue (VarSnippet snippet)
Please see eval(String input).