Jshell Accumulo Feature
Date: 21 Apr 2021
Overview
First introduced in Java 9, JShell is an interactive Read-Evaluate-Print-Loop (REPL) Java tool that interprets user’s input and outputs the results. This tool provides a convenient way to test out and execute quick tasks with Accumulo in the terminal. This feature is a part of the upcoming Accumulo 2.1 release. If you’re a developer and want to get involved in testing, contact us or review our contributing guide.
Major Features
-
Default JShell script provides initial imports for interacting with Accumulo’s API and provided in Accumulo’s binary distribution tarball
-
On startup, JShell Accumulo will automatically import the
CLASSPATH
, load in a configured environment from user’sconf/accumulo-env.sh
, and invokeconf/jshell-init.jsh
to allow rapid Accumulo task executions -
JShell Accumulo can startup using default/custom JShell script and users can append any JShell command-line options to the startup command
Booting Up JShell Accumulo
1) Open up a terminal and navigate to Accumulo’s installation directory
2) To startup JShell with default script use this command:
$ bin/accumulo jshell
3) To startup JShell with custom script use this command:
$ bin/accumulo jshell --startup file/path/to/custom_script.jsh
Note: One can execute the jshell
command to startup JShell. However, doing so will require
manually importing the CLASSPATH
and the configured environment from conf/accumulo-env.sh
and manually specifying the startup file for conf/jshell-init.jsh
before any Accumulo tasks
can be performed. Using one of the startup commands above will automate that process
for convenience.
JShell Accumulo Default Script
The auto-generated jshell-init.jsh
is a customizable file located in Accumulo’s installation
conf/
directory. Inside, jshell-init.jsh
contains Accumulo Java APIs
formatted as import statements and AccumuloClient build implementation. On startup,
the script automatically loads in the APIs and attempts to construct a client. Should additional
APIs and/or code implementations be needed, simply append them to jshell-init.jsh
.
Alternatively, you can create a separate JShell script and specify the custom script’s file path
on startup.
To construct an AccumuloClient, the provided conf/jshell-init.jsh
script finds
and uses accumulo-client.properties
in Accumulo’s class path, and assigns the result
to a variable called client.
If accumulo-client.properties
is found, a similar result will be produced below:
Preparing JShell for Apache Accumulo
Building Accumulo client using 'jar:file:/home/accumulo/lib/accumulo-client.jar!/accumulo-client.properties'
Use 'client' to interact with Accumulo
| Welcome to JShell -- Version 11.0.10
| For an introduction type: /help intro
jshell>
If accumulo-client.properties
is not found, an AccumuloClient will not
auto-generate and will produce the following result below:
Preparing JShell for Apache Accumulo
'accumulo-client.properties' was not found on the classpath
| Welcome to JShell -- Version 11.0.10
| For an introduction type: /help intro
jshell>
JShell Accumulo Example
1) Booting up JShell Accumulo using default script
Preparing JShell for Apache Accumulo
Building Accumulo client using 'file:/home/accumulo/conf/accumulo-client.properties'
Use 'client' to interact with Accumulo
| Welcome to JShell -- Version 11.0.10
| For an introduction type: /help intro
jshell>
2) Providing JShell with an Accumulo task
// Create a table called "GothamPD".
client.tableOperations().create("GothamPD");
// Create a Mutation object to hold all changes to a row in a table.
// Each row has a unique row ID.
Mutation mutation = new Mutation("id0001");
// Create key/value pairs for Batman. Put them in the "hero" family.
mutation.put("hero", "alias", "Batman");
mutation.put("hero", "name", "Bruce Wayne");
mutation.put("hero", "wearsCape?", "true");
// Create a BatchWriter to the GothamPD table and add your mutation to it.
// Try w/ resources will close for us.
try (BatchWriter writer = client.createBatchWriter("GothamPD")) {
writer.addMutation(mutation);
}
// Read and print all rows of the "GothamPD" table.
// Try w/ resources will close for us.
try (ScannerBase scan = client.createScanner("GothamPD", Authorizations.EMPTY)) {
System.out.println("Gotham Police Department Persons of Interest:");
// A Scanner is an extension of java.lang.Iterable so behaves just like one.
scan.forEach((k, v) -> System.out.printf("Key : %-50s Value : %s\n", k, v));
}
Note: The fully-qualified class name for Accumulo Scanner or
org.apache.accumulo.core.client.Scanner
needs to be used due to conflicting issues with
Java’s built-in java.util.Scanner. However, to shorten the Accumulo Scanner’s declaration, assign
scan to ScannerBase
type instead.
3) Executing the Accumulo task above outputs:
mutation ==> org.apache.accumulo.core.data.Mutation@1
Gotham Police Department Persons of Interest:
Key : id0001 hero:alias [] 1618926204602 false Value : Batman
Key : id0001 hero:name [] 1618926204602 false Value : Bruce Wayne
Key : id0001 hero:wearsCape? [] 1618926204602 false Value : true
jshell>
View all posts in the news archive