Spring Shell Technology For Java development

Posted on In Programming, Tutorial

This post is about the Spring Shell technology and its use in java. Experts of java development India have shared their best knowledge in this post for Spring Shell with the community people. If you have anything to ask, do it at the end.

Technology: It is command line tool for Java applications to interact with java applications using spring shell framework. Spring Shell is the framework which provides command line feature for spring based applications. We can write our own commands and we can execute the commands on top of spring remote shell.

We can write some commands which will do our work easier, like triggering the job easily using shell commands.

Requirements:
Spring Shell requires JDK 6.0 or later and Spring 3.0 or later.

Creating Spring Shell Applications:
(1)Using spring starter

We can open http://start.spring.io in any browser and we can specify the Group, artifact and spring boot version on which we want to develop. And select “Remote Shell” as the dependency, and we can also select the build tool either maven or gradle.

(2) We can create a maven project and add below dependency.

<dependency>
    <groupId>org.springframework.shell</groupId>
    <artifactId>spring-shell</artifactId>
    <version>1.2.0.RELEASE</version>
</dependency>

Or if we are using gradle as build tool, we can add the below dependency.

org.springframework.shell:spring-shell:1.2.0.RELEASE

Developing Plugins for Spring Shell:

Spring Shell is the framework internally uses JLine(java console input library) for shell applications. It is the core library for reading and editing the user input from console. It provides support for tab-completion, password masking, custom key binding, it also provides the chain of commands feature. JLine also support all operating systems like usual java applications, JLine is mostly developed in Java, but JLine uses Jansi to support Windows OS.

Spring Shell is the framework built on top spring framework, it will use spring default converters for converting commandline arguments to java objects. Spring shell core framework comes with default commands like exit command to exit from shell, help commands to show the all commands with description.

Architecture of Spring Shell Framework:

Core Shell is the main component of the framework uses JLine, we can develop our own plugins on top of core shell.by default spring shell uses spring-shell-plugin.xml which is present in META-INF/spring folder.

We need to specify the commands package in component-scan so that all commands will be auto detected spring shell application.

Example: sample spring-shell-plugin.xml.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.example.commands" />
</beans>

If we want to use any custom converters we can specify in xml file so that it will uses this converter for converting to/from console to java objects.

Creating Custom Commands using Spring Shell:

CommandMarker is key interface used for creating commands, we need to implement this interface for creating commands.

Annotations used in creating commands:

(1) @CliCommand : if we annotate any public method with this annotation then whenever we execute the command this method will execute. It must be unique within the application.
Example: @CliCommand(value=”echo”, help=”print welcome message”)
value attribute is command name what we want specify, and help attribute help message to understand about command.
(2) @CliOption :it is refer to named arguments passed to commands, if the argument value and method argument value is of the different types then we converters will convert to required type, we can also specify the argument is mandatory or optional.
@CliOption(mandatory=true, help=”Enter your Name”, key = { “name” }) final String name
(3) @CliAvailabilityIndicator :It is will be placed on methods which return primitive boolean value, and it indicate whether command will be available to shell or not based on the command history. If the method return true means it will available otherwise not.
@CliAvailabilityIndicator(value=”echo”)
Here value must be command name.

Customizing the Spring Shell user interface:

We can customize the banner for our spring shell application using BannerProvider interface, we can implement this interface and we can customize the banner how we want to look the banner.
We can also customize the shell name using PromptProvider interface provided by spring shell, we can implement this interface we can provide the shell name.
We can also store the commands history in a file, using HistoryFileNameProvider interface we can specify where we want to store history file.
All the above classes must be marked as spring components and we need to specify higher order so that our beans will take precedence over default beans.

Example for custom command:

@Component
public class EchoCommand implements CommandMarker{

    @CliAvailabilityIndicator(value="echo")
    public boolean isPrintCommandAvailable()
    {
        return Boolean.TRUE;
    }

    @CliCommand(value="echo",help="print welcome message")
    public String printMessage(@CliOption(mandatory=true,help="Enter your Name", key = { "name" }) final String name,
                              @CliOption(key = { "time" }, mandatory = false, specifiedDefaultValue="now", help = "When you are saying") final String time)
    {
        return "Welcome "+name+" !"+" at "+time;
    }
}
Example for sample Banner Provider:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class EchoBannerProvider implements BannerProvider {

    @Override
    public String getProviderName() {
        return "Welcome to Echo Banner";
    }

    @Override
    public String getBanner() {
        StringBuffer buf = new StringBuffer();
        buf.append("=======================================" + OsUtils.LINE_SEPARATOR);
        buf.append("*                                     *" + OsUtils.LINE_SEPARATOR);
        buf.append("*            ECHO Messages            *" +OsUtils.LINE_SEPARATOR);
        buf.append("*                                     *" + OsUtils.LINE_SEPARATOR);
        buf.append("=======================================" + OsUtils.LINE_SEPARATOR);
        buf.append("Version:" + this.getVersion());
        return buf.toString();
    }

    @Override
    public String getVersion() {
        return "1.0";
    }

    @Override
    public String getWelcomeMessage() {
        return "Welcome to Echo Messages";
    }

}
Example for history file name provider: 
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class EchoHistoryFileNameProvider implements HistoryFileNameProvider {

    @Override
    public String getProviderName() {
        return "Echo History File Provider";
    }

    @Override
    public String getHistoryFileName() {
        return "echo.log";
    }

}
Example for custom shell name provider:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class EchoPromptProvider implements PromptProvider {

    @Override
    public String getProviderName() {
        return "Echo Prompt Provider";
    }
    @Override
    public String getPrompt() {
        return "print>";
    }

Executing spring shell Modules:
If we are using Maven as our build tool,
We need to add the below maven assembler plugin for creating executable file.

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.8.1</version>
<executions>
<execution>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
<configuration>
<programs>
<program>
<mainClass>org.springframework.shell.Bootstrap</mainClass>
<id>echo</id>
</program>
</programs>
</configuration>
< /plugin>

And run mvn package then appassembler\bin folder contains the executable files.
If we are using gradle as build tool then we need to add the below lines build.gradle file:
mainClassName = “org.springframework.shell.Bootstrap”
defaultTasks ‘installApp’

We can run the executable file and we can execute our commands.

We can press TAB to list out all possible commands.

help command will display the description of the commands.

When we enter echo and press TAB it will automatically append the argument of the mandatory arguments. And then if you press TAB it will show the description of the argument.

Conclusion: Spring shell is the framework for command line user interface to create our own commands, we can also customize the spring shell banner, commands history file name, shell name. Using build tools like maven, gradle we can generate the executable files to launch the shell.

Sample Code:
You can download the source code from github repository:
https://github.com/sravan4rmhyd/Spring-shell-Print

As you know that Spring Shell is a command line tool designed by officials for java apps. In this post, experts of java development team have explained the use of Spring Shell technology in java. If there is anything they skipped, you can tell in comments.

Johnnymorgan

Johnny is a technical writer with more than 6 years of experience. I write articles especially for Java, Python and Asp.Net. Currently I work for TrustedHints and I have also got well response to write articles on CRM, Hadoop and QA.

Leave a Reply

Your email address will not be published. Required fields are marked *