50. Using the CLI

Once you have installed the CLI you can run it by typing spring. If you run spring without any arguments, a simple help screen is displayed:

$ spring
usage: spring [--help] [--version]
       <command> [<args>]

Available commands are:

  run [options] <files> [--] [args]
    Run a spring groovy script

  ... more command help is shown here

You can use help to get more details about any of the supported commands. For example:

$ spring help run
spring run - Run a spring groovy script

usage: spring run [options] <files> [--] [args]

Option                     Description
------                     -----------
--autoconfigure [Boolean]  Add autoconfigure compiler
                             transformations (default: true)
--classpath, -cp           Additional classpath entries
-e, --edit                 Open the file with the default system
                             editor
--no-guess-dependencies    Do not attempt to guess dependencies
--no-guess-imports         Do not attempt to guess imports
-q, --quiet                Quiet logging
-v, --verbose              Verbose logging of dependency
                             resolution
--watch                    Watch the specified file for changes

The version command provides a quick way to check which version of Spring Boot you are using.

$ spring version
Spring CLI v1.1.12.RELEASE

50.1 Running applications using the CLI

You can compile and run Groovy source code using the run command. The Spring Boot CLI is completely self-contained so you don’t need any external Groovy installation.

Here is an example “hello world” web application written in Groovy:

@RestController
class WebApplication {

    @RequestMapping("/")
    String home() {
        "Hello World!"
    }

}

50.1.1 Deduced “grab” dependencies

Standard Groovy includes a @Grab annotation which allows you to declare dependencies on a third-party libraries. This useful technique allows Groovy to download jars in the same way as Maven or Gradle would; but without requiring you to use a build tool.

Spring Boot extends this technique further, and will attempt to deduce which libraries to “grab” based on your code. For example, since the WebApplication code above uses @RestController annotations, “Tomcat” and “Spring MVC” will be grabbed.

The following items are used as “grab hints”:

ItemsGrabs

JdbcTemplate, NamedParameterJdbcTemplate, DataSource

JDBC Application.

@EnableJmsMessaging

JMS Application.

@Test

JUnit.

@EnableRabbitMessaging

RabbitMQ.

@EnableReactor

Project Reactor.

extends Specification

Spock test.

@EnableBatchProcessing

Spring Batch.

@MessageEndpoint @EnableIntegrationPatterns

Spring Integration.

@EnableDeviceResolver

Spring Mobile.

@Controller @RestController @EnableWebMvc

Spring MVC + Embedded Tomcat.

@EnableWebSecurity

Spring Security.

@EnableTransactionManagement

Spring Transaction Management.

[Tip]Tip

See subclasses of CompilerAutoConfiguration in the Spring Boot CLI source code to understand exactly how customizations are applied.

50.1.2 Deduced “grab” coordinates

Spring Boot extends Groovy’s standard @Grab support by allowing you to specify a dependency without a group or version, for example @Grab('freemarker'). This will consult Spring Boot’s default dependency metadata to deduce the artifact’s group and version. Note that the default metadata is tied to the version of the CLI that you’re using – it will only change when you move to a new version of the CLI, putting you in control of when the versions of your dependencies may change. A table showing the dependencies and their versions that are included in the default metadata can be found in the appendix.

Custom “grab” metadata

Spring Boot provides a new annotation, @GrabMetadata that can be used to provide custom dependency metadata that overrides Spring Boot’s defaults. This metadata is specified by using this annotation to provide the coordinates of one or more properties files (deployed to a Maven repository with a "type" identifier: "properties"). For example @GrabMetadata(['com.example:versions-one:1.0.0', 'com.example.versions-two:1.0.0']) will pick up files in a Maven repository in "com/example/versions-/1.0.0/versions--1.0.0.properties". The properties files are applied in the order that they’re specified. In the example above, this means that properties in versions-two will override properties in versions-one. Each entry in each properties file must be in the form group:module=version. You can use @GrabMetadata anywhere that you can use @Grab, however, to ensure consistent ordering of the metadata, you can only use @GrabMetadata at most once in your application. A useful source of dependency metadata (a superset of Spring Boot) is the Spring IO Platform, e.g. @GrabMetadata('io.spring.platform:platform-versions:1.0.0.RELEASE').

50.1.3 Default import statements

To help reduce the size of your Groovy code, several import statements are automatically included. Notice how the example above refers to @Component, @RestController and @RequestMapping without needing to use fully-qualified names or import statements.

[Tip]Tip

Many Spring annotations will work without using import statements. Try running your application to see what fails before adding imports.

50.1.4 Automatic main method

Unlike the equivalent Java application, you do not need to include a public static void main(String[] args) method with your Groovy scripts. A SpringApplication is automatically created, with your compiled code acting as the source.

50.2 Testing your code

The test command allows you to compile and run tests for your application. Typical usage looks like this:

$ spring test app.groovy tests.groovy
Total: 1, Success: 1, : Failures: 0
Passed? true

In this example, tests.groovy contains JUnit @Test methods or Spock Specification classes. All the common framework annotations and static methods should be available to you without having to import them.

Here is the tests.groovy file that we used above (with a JUnit test):

class ApplicationTests {

    @Test
    void homeSaysHello() {
        assertEquals("Hello World!", new WebApplication().home())
    }

}
[Tip]Tip

If you have more than one test source files, you might prefer to organize them into a test directory.

50.3 Applications with multiple source files

You can use “shell globbing” with all commands that accept file input. This allows you to easily use multiple files from a single directory, e.g.

$ spring run *.groovy

This technique can also be useful if you want to segregate your “test” or “spec” code from the main application code:

$ spring test app/*.groovy test/*.groovy

50.4 Packaging your application

You can use the jar command to package your application into a self-contained executable jar file. For example:

$ spring jar my-app.jar *.groovy

The resulting jar will contain the classes produced by compiling the application and all of the application’s dependencies so that it can then be run using java -jar. The jar file will also contain entries from the application’s classpath. You can add explicit paths to the jar using --include and --exclude (both are comma-separated, and both accept prefixes to the values “+” and “-” to signify that they should be removed from the defaults). The default includes are

public/**, resources/**, static/**, templates/**, META-INF/**, *

and the default excludes are

.*, repository/**, build/**, target/**, **/*.jar, **/*.groovy

See the output of spring help jar for more information.

50.5 Using the embedded shell

Spring Boot includes command-line completion scripts for BASH and zsh shells. If you don’t use either of these shells (perhaps you are a Windows user) then you can use the shell command to launch an integrated shell.

$ spring shell
Spring Boot (v1.1.12.RELEASE)
Hit TAB to complete. Type \'help' and hit RETURN for help, and \'exit' to quit.

From inside the embedded shell you can run other commands directly:

$ version
Spring CLI v1.1.12.RELEASE

The embedded shell supports ANSI color output as well as tab completion. If you need to run a native command you can use the $ prefix. Hitting ctrl-c will exit the embedded shell.