RSS

Tag Archives: spring

Spring Shell with Spring Boot

Spring Shell is a spring project that exposes a shell for interaction with a spring application.
I found this useful in cases where I dont need a full blown web app bur still want to use the features such as the spring packages, spring data, property management and dependecy injection to develop an application.
The spring shell set up described in documentation is clear enough but it does not cover using spring shell with spring boot. Spring boot really speeds up bootstrapping a spring application.

With a few references and digging around the method in spring shell that is called from the spring application’s main method, I found the following solution.

Spring shell assumes there will be an xml config that it reads sort of like this:


new ClassPathXmlApplicationContext("classpath*:/META-INF/spring/spring-shell-plugin.xml";);

To run the spring shell application, the spring application should call the main method in spring sell’s Bootstrap class.

 public static void main(String[] args) throws IOException {
Bootstrap.main(args);

}

Then the commands that should be available in the shell are defined as spring components like this:

@Component
public class HelloWorldCommands implements CommandMarker {

// use any Spring annotations for Dependency Injection or other Spring
// interfaces as required.

// methods with @Cli annotations go here

}

So to change this set up so that spring shell reads a context set up by spring boot, the code below does the following:

  1. sets up a spring boot app
  2. retreives and runs the shell from the context retreived from spring boot
  3. It contains the rest of the code copied from the spring shell Bootstrap class’ main method, since under the spring boot setup, we wont be calling Boostrap.main
@SpringBootApplication
@ComponentScan({"org.springframework.shell.commands",/* your packages here*/;"})
public class MyshellApplication {

private static ApplicationContext ctx;
private static CommandLine commandLine;
private static StopWatch sw = new StopWatch("Spring Shell";

@Bean
public JLineShellComponent jLineShellComponent(){
return new JLineShellComponent();
}
@Bean
public CommandLine commandLine(){
return new CommandLine(null,3000,null);
}

public static void main(String[] args) {
sw.start();
ctx = SpringApplication.run(MyshellApplication.class);
commandLine = SimpleShellCommandLineOptions.parseCommandLine(args);
MyshellApplication application = new MyshellApplication();

application.runShell();

}

private ExitShellRequest runShell(){

String[] commandsToExecuteAndThenQuit = commandLine.getShellCommandsToExecute();
// The shell is used
JLineShellComponent shell = ctx.getBean( JLineShellComponent.class);
ExitShellRequest exitShellRequest;

if (null != commandsToExecuteAndThenQuit) {
boolean successful = false;
exitShellRequest = ExitShellRequest.FATAL_EXIT;

for (String cmd : commandsToExecuteAndThenQuit) {
successful = shell.executeCommand(cmd).isSuccess();
if (!successful)
break;
}

// if all commands were successful, set the normal exit status
if (successful) {
exitShellRequest = ExitShellRequest.NORMAL_EXIT;
}
}
else {
shell.start();
shell.promptLoop();
exitShellRequest = shell.getExitShellRequest();
if (exitShellRequest == null) {
// shouldn't really happen, but we'll fallback to this anyway
exitShellRequest = ExitShellRequest.NORMAL_EXIT;
}
shell.waitForComplete();
}

((ConfigurableApplicationContext) ctx).close();
sw.stop();
if (shell.isDevelopmentMode()) {
System.out.println("Total execution time: "+ sw.getLastTaskTimeMillis() + "ms");
}
return exitShellRequest;
}
}

So now when I run the spring boot application , I get my command shell

 java -jar <application>.jar 

Capture

Capture2

 
5 Comments

Posted by on October 30, 2015 in java, programming, software engineering

 

Tags: , , , ,