From 01166381a0eb8de20ef2213728011856d16cf729 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 14 Mar 2017 20:51:23 +0000 Subject: [PATCH] Provide separate documentation (API and reference) for Gradle plugin --- spring-boot-docs/pom.xml | 9 + .../src/main/asciidoc/build-tool-plugins.adoc | 515 +-------------- spring-boot-docs/src/main/asciidoc/howto.adoc | 105 +-- spring-boot-docs/src/main/asciidoc/index.adoc | 6 +- .../src/main/asciidoc/using-spring-boot.adoc | 74 +-- .../spring-boot-gradle-plugin/build.gradle | 13 +- .../spring-boot-gradle-plugin/pom.xml | 134 ++++ .../src/main/asciidoc/getting-started.adoc | 43 ++ .../src/main/asciidoc/index.adoc | 48 ++ .../asciidoc/integrating-with-actuator.adoc | 55 ++ .../main/asciidoc/managing-dependencies.adoc | 46 ++ .../src/main/asciidoc/packaging.adoc | 167 +++++ .../src/main/asciidoc/publishing.adoc | 43 ++ .../src/main/asciidoc/reacting.adoc | 78 +++ .../src/main/asciidoc/running.adoc | 49 ++ .../apply-plugin-milestone.gradle | 11 + .../apply-plugin-release.gradle | 3 + .../apply-plugin-snapshot.gradle | 11 + .../getting-started/typical-plugins.gradle | 17 + .../build-info-additional.gradle | 21 + .../build-info-basic.gradle | 14 + .../build-info-custom-values.gradle | 21 + .../custom-version.gradle | 32 + .../managing-dependencies/dependencies.gradle | 19 + .../application-plugin-main-class.gradle | 13 + .../boot-jar-custom-launch-script.gradle | 21 + .../boot-jar-include-launch-script.gradle | 20 + .../boot-jar-launch-script-properties.gradle | 21 + .../packaging/boot-jar-main-class.gradle | 14 + .../boot-jar-manifest-main-class.gradle | 16 + .../packaging/boot-jar-requires-unpack.gradle | 26 + .../boot-war-include-devtools.gradle | 19 + .../boot-war-properties-launcher.gradle | 20 + .../packaging/war-container-dependency.gradle | 19 + .../gradle/publishing/maven-publish.gradle | 31 + .../src/main/gradle/publishing/maven.gradle | 25 + .../application-plugin-main-class-name.gradle | 19 + .../main/gradle/running/boot-run-main.gradle | 20 + .../running/boot-run-source-resources.gradle | 20 + .../src/main/javadoc/spring-javadoc.css | 599 ++++++++++++++++++ .../GettingStartedDocumentationTests.java | 47 ++ ...gratingWithActuatorDocumentationTests.java | 90 +++ ...anagingDependenciesDocumentationTests.java | 50 ++ .../docs/PackagingDocumentationTests.java | 176 +++++ .../docs/PublishingDocumentationTests.java | 54 ++ .../docs/RunningDocumentationTests.java | 60 ++ .../boot/gradle/testkit/GradleBuild.java | 11 +- 47 files changed, 2247 insertions(+), 678 deletions(-) create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/getting-started.adoc create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/index.adoc create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/integrating-with-actuator.adoc create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/packaging.adoc create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/publishing.adoc create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/running.adoc create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-milestone.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-release.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-snapshot.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/typical-plugins.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-additional.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-basic.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/dependencies.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/application-plugin-main-class.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-custom-launch-script.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-include-launch-script.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-launch-script-properties.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-main-class.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-manifest-main-class.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-requires-unpack.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-include-devtools.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-properties-launcher.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/war-container-dependency.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven-publish.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/application-plugin-main-class-name.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-main.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-source-resources.gradle create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/javadoc/spring-javadoc.css create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/GettingStartedDocumentationTests.java create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/IntegratingWithActuatorDocumentationTests.java create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PublishingDocumentationTests.java create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/RunningDocumentationTests.java diff --git a/spring-boot-docs/pom.xml b/spring-boot-docs/pom.xml index 7c96c172e9..33788d4b04 100644 --- a/spring-boot-docs/pom.xml +++ b/spring-boot-docs/pom.xml @@ -853,6 +853,15 @@ META-INF/** + + org.springframework.boot + spring-boot-gradle-plugin + ${project.version} + docs + zip + ${project.build.directory}/contents/gradle-plugin + META-INF/** + diff --git a/spring-boot-docs/src/main/asciidoc/build-tool-plugins.adoc b/spring-boot-docs/src/main/asciidoc/build-tool-plugins.adoc index 1f914771ba..d0de570135 100644 --- a/spring-boot-docs/src/main/asciidoc/build-tool-plugins.adoc +++ b/spring-boot-docs/src/main/asciidoc/build-tool-plugins.adoc @@ -164,516 +164,11 @@ Advanced configuration options and examples are available in the [[build-tool-plugins-gradle-plugin]] == Spring Boot Gradle plugin -The Spring Boot Gradle Plugin provides Spring Boot support in Gradle, allowing you to -package executable jar or war archives, run Spring Boot applications and use the -dependency management provided by `spring-boot-dependencies`. - - - -[[build-tool-plugins-including-the-gradle-plugin]] -=== Including the plugin -ifeval::["{spring-boot-repo}" == "release"] -To use the Spring Boot Gradle Plugin configure it using the `plugins` block: -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - plugins { - id 'org.springframework.boot' version '{spring-boot-version}' - } ----- -endif::[] -ifeval::["{spring-boot-repo}" != "release"] -To use the Spring Boot Gradle Plugin simply include a `buildscript` dependency and apply -the `spring-boot` plugin: - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - buildscript { - repositories { - maven { url 'http://repo.spring.io/snapshot' } - maven { url 'http://repo.spring.io/milestone' } - } - dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}'' - } - } - apply plugin: 'org.springframework.boot' ----- -endif::[] - - - -[[build-tool-plugins-gradle-dependency-management]] -=== Gradle dependency management -The `spring-boot` plugin automatically applies the -{dependency-management-plugin}/[Dependency Management Plugin] and configures it to import -the `spring-boot-starter-parent` bom. This provides a similar dependency management -experience to the one that is enjoyed by Maven users. For example, it allows you to omit -version numbers when declaring dependencies that are managed in the bom. To make use of -this functionality, simply declare dependencies in the usual way, but leave the version -number empty: - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - dependencies { - compile("org.springframework.boot:spring-boot-starter-web") - compile("org.thymeleaf:thymeleaf-spring5") - compile("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect") - } ----- - -NOTE: The version of the `spring-boot` gradle plugin that you declare determines the -version of the `spring-boot-starter-parent` bom that is imported (this ensures that builds -are always repeatable). You should always set the version of the `spring-boot` gradle -plugin to the actual Spring Boot version that you wish to use. Details of the versions -that are provided can be found in the <>. - -To learn more about the capabilities of the Dependency Management Plugin, please refer to -its {dependency-management-plugin-documentation}[documentation]. - - - -[[build-tool-plugins-gradle-packaging]] -=== Packaging executable jar and war files -Once the `spring-boot` plugin has been applied to your project it will automatically -attempt to rewrite archives to make them executable using the -<>. You -should configure your project to build a jar or war (as appropriate) in the usual way. - -The main class that you want to launch can either be specified using a configuration -option, or by adding a `Main-Class` attribute to the manifest. If you don't specify a -main class the plugin will search for a class with a -`public static void main(String[] args)` method. - -TIP: Check <> for a full list of -configuration options. - -To build and run a project artifact, you can type the following: - -[indent=0] ----- - $ gradle build - $ java -jar build/libs/mymodule-0.0.1-SNAPSHOT.jar ----- - -To build a war file that is both executable and deployable into an external container, -you need to mark the embedded container dependencies as belonging to the war plugin's -`providedRuntime` configuration, e.g.: - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - ... - apply plugin: 'war' - - war { - baseName = 'myapp' - version = '0.5.0' - } - - repositories { - jcenter() - maven { url "http://repo.spring.io/libs-snapshot" } - } - - dependencies { - compile("org.springframework.boot:spring-boot-starter-web") - providedRuntime("org.springframework.boot:spring-boot-starter-tomcat") - ... - } ----- - -TIP: See the "`<>`" section for more details on -how to create a deployable war file. - - - -[[build-tool-plugins-gradle-running-applications]] -=== Running a project in-place -To run a project in place without building a jar first you can use the "`bootRun`" task: - -[indent=0] ----- - $ gradle bootRun ----- - -If <> has been added to your project -it will automatically monitor your application for changes. Alternatively, you can also -run the application so that your static classpath resources (i.e. in `src/main/resources` -by default) are reloadable in the live application, which can be helpful at development -time. - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - bootRun { - addResources = true - } ----- - -Making static classpath resources reloadable means that `bootRun` does not use the output -of the `processResources` task, i.e., when invoked using `bootRun`, your application will -use the resources in their unprocessed form. - - - -[[build-tool-plugins-gradle-global-configuration]] -=== Spring Boot plugin configuration -The gradle plugin automatically extends your build script DSL with a `springBoot` element -for global configuration of the Boot plugin. Set the appropriate properties as you would -with any other Gradle extension (see below for a list of configuration options): - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - springBoot { - backupSource = false - } ----- - - - -[[build-tool-plugins-gradle-repackage-configuration]] -=== Repackage configuration -The plugin adds a `bootRepackage` task which you can also configure directly, e.g.: - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - bootRepackage { - mainClass = 'demo.Application' - } ----- - -The following configuration options are available: - -[cols="2,4"] -|=== -|Name |Description - -|`enabled` -|Boolean flag to switch the repackager off (sometimes useful if you -want the other Boot features but not this one) - -|`mainClass` -|The main class that should be run. If not specified, and you have applied the application - plugin, the `mainClassName` project property will be used. If the application plugin has - not been applied or no `mainClassName` has been specified, the archive will be searched - for a suitable class. "Suitable" means a unique class with a well-formed `main()` method - (if more than one is found the build will fail). If you have applied the application - plugin, the main class can also be specified via its "run" task (`main` property) and/or - its "startScripts" task (`mainClassName` property) as an alternative to using the - "springBoot" configuration. - -|`classifier` -|A file name segment (before the extension) to add to the archive, so that the original is - preserved in its original location. Defaults to `null` in which case the archive is - repackaged in place. The default is convenient for many purposes, but if you want to use - the original jar as a dependency in another project you must use a classifier to define - the executable archive. - -|`withJarTask` -|The name or value of the `Jar` task (defaults to all tasks of type `Jar`) which is used - to locate the archive to repackage. - -|`customConfiguration` -|The name of the custom configuration which is used to populate the nested lib directory - (without specifying this you get all compile and runtime dependencies). - -|`executable` -|Boolean flag to indicate if jar files are fully executable on Unix like operating - systems. Defaults to `false`. - -|`embeddedLaunchScript` -|The embedded launch script to prepend to the front of the jar if it is fully executable. - If not specified the 'Spring Boot' default script will be used. - -|`embeddedLaunchScriptProperties` -|Additional properties that to be expanded in the launch script. The default script - supports a `mode` property which can contain the values `auto`, `service` or `run`. - -|`excludeDevtools` -|Boolean flag to indicate if the devtools jar should be excluded from the repackaged -archives. Defaults to `true`. -|=== - - - -[[build-tool-plugins-gradle-repackage-custom-configuration]] -=== Repackage with custom Gradle configuration -Sometimes it may be more appropriate to not package default dependencies resolved from -`compile`, `runtime` and `provided` scopes. If the created executable jar file -is intended to be run as it is, you need to have all dependencies nested inside it; -however, if the plan is to explode a jar file and run the main class manually, you may already -have some of the libraries available via `CLASSPATH`. This is a situation where -you can repackage your jar with a different set of dependencies. - -Using a custom -configuration will automatically disable dependency resolving from -`compile`, `runtime` and `provided` scopes. Custom configuration can be either -defined globally (inside the `springBoot` section) or per task. - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - task clientJar(type: Jar) { - appendix = 'client' - from sourceSets.main.output - exclude('**/*Something*') - } - - task clientBoot(type: BootRepackage, dependsOn: clientJar) { - withJarTask = clientJar - customConfiguration = "mycustomconfiguration" - } ----- - -In above example, we created a new `clientJar` Jar task to package a customized -file set from your compiled sources. Then we created a new `clientBoot` -BootRepackage task and instructed it to work with only `clientJar` task and -`mycustomconfiguration`. - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - configurations { - mycustomconfiguration.exclude group: 'log4j' - } - - dependencies { - mycustomconfiguration configurations.runtime - } ----- - -The configuration that we are referring to in `BootRepackage` is a normal -{gradle-dsl}/org.gradle.api.artifacts.Configuration.html[Gradle -configuration]. In the above example we created a new configuration named -`mycustomconfiguration` instructing it to derive from a `runtime` and exclude the `log4j` -group. If the `clientBoot` task is executed, the repackaged boot jar will have all -dependencies from `runtime` but no `log4j` jars. - - - -[[build-tool-plugins-gradle-configuration-options]] -==== Configuration options -The following configuration options are available: - -[cols="2,4"] -|=== -|Name |Description - -|`mainClass` -|The main class that should be run by the executable archive. - -|`providedConfiguration` -|The name of the provided configuration (defaults to `providedRuntime`). - -|`backupSource` -|If the original source archive should be backed-up before being repackaged (defaults - to `true`). - -|`customConfiguration` -|The name of the custom configuration. - -|`layout` -|The type of archive, corresponding to how the dependencies are laid out inside - (defaults to a guess based on the archive type). See - <>. - -|`layoutFactory` -|A layout factory that can be used if a custom layout is required. Alternative layouts -can be provided by 3rd parties. Layout factories are only used when `layout` is not -specified. - -|`requiresUnpack` -|A list of dependencies (in the form "`groupId:artifactId`" that must be unpacked from - fat jars in order to run. Items are still packaged into the fat jar, but they will be - automatically unpacked when it runs. -|=== - - - -[[build-tool-plugins-gradle-configuration-layouts]] -==== Available layouts - -The `layout` attribute configures the format of the archive and whether the bootstrap -loader should be included or not. The following layouts are available: - -[cols="2,4,1"] -|=== -|Name |Description |Executable - -|`JAR` -|Regular executable - <>. -|Yes - -|`WAR` -|Executable - <>. - `provided` dependencies are placed in `WEB-INF/lib-provided` to avoid any clash when - the `war` is deployed in a servlet container. -|Yes - -|`ZIP` (alias to `DIR`) -|Similar to `JAR` layout, using - <>. -| Yes - -|`MODULE` -|Bundle dependencies (excluding those with `provided` scope) and project resources. -|No - -|`NONE` -|Bundle all dependencies and project resources. -|No -|=== - - - -[[build-tool-plugins-gradle-configuration-custom-repackager]] -==== Using a custom layout -If you have custom requirements for how to arrange the dependencies and loader classes -inside the repackaged jar, you can use a custom layout. Any library which defines one -or more `LayoutFactory` implementations can be added to the build script dependencies -and then the layout factory becomes available in the `springBoot` configuration. -For example: - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath("org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}") - classpath("com.example:custom-layout:1.0.0") - } -} - -springBoot { - layoutFactory = new com.example.CustomLayoutFactory() -} ----- - -NOTE: If there is only one custom `LayoutFactory` on the build classpath and it is -listed in `META-INF/spring.factories` then it is unnecessary to explicitly set it in the -`springBoot` configuration. Layout factories are only used when no explicit `layout` is -specified. - - - -[[build-tool-plugins-understanding-the-gradle-plugin]] -=== Understanding how the Gradle plugin works -When `spring-boot` is applied to your Gradle project a default task named `bootRepackage` -is created automatically. The `bootRepackage` task depends on Gradle `assemble` task, and -when executed, it tries to find all jar artifacts whose qualifier is empty (i.e. tests and -sources jars are automatically skipped). - -Due to the fact that `bootRepackage` finds 'all' created jar artifacts, the order of -Gradle task execution is important. Most projects only create a single jar file, so -usually this is not an issue; however, if you are planning to create a more complex -project setup, with custom `Jar` and `BootRepackage` tasks, there are few tweaks to -consider. - -If you are 'just' creating custom jar files from your project you can simply disable -default `jar` and `bootRepackage` tasks: - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - jar.enabled = false - bootRepackage.enabled = false ----- - -Another option is to instruct the default `bootRepackage` task to only work with a -default `jar` task. - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - bootRepackage.withJarTask = jar ----- - -If you have a default project setup where the main jar file is created and repackaged, -'and' you still want to create additional custom jars, you can combine your custom -repackage tasks together and use `dependsOn` so that the `bootJars` task will run after -the default `bootRepackage` task is executed: - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - task bootJars - bootJars.dependsOn = [clientBoot1,clientBoot2,clientBoot3] - build.dependsOn(bootJars) ----- - -All the above tweaks are usually used to avoid situations where an already created boot -jar is repackaged again. Repackaging an existing boot jar will not break anything, but -you may find that it includes unnecessary dependencies. - - - -[[build-tool-plugins-gradle-publishing-artifacts-to-a-maven-repository]] -=== Publishing artifacts to a Maven repository using Gradle -If you are <> and you want to publish artifacts to a Maven repository -you will need to configure the Maven publication with details of Spring Boot's -dependency management. This can be achieved by configuring it to publish poms that -inherit from `spring-boot-starter-parent` or that import dependency management from -`spring-boot-dependencies`. The exact details of this configuration depend on how you're -using Gradle and how you're trying to publish the artifacts. - - - -[[build-tool-plugins-gradle-publishing-artifacts-to-a-maven-repository-inherit]] -==== Configuring Gradle to produce a pom that inherits dependency management -The following is an example of configuring Gradle to generate a pom that inherits -from `spring-boot-starter-parent`. Please refer to the -{gradle-user-guide}/userguide.html[Gradle User Guide] for further information. - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - uploadArchives { - repositories { - mavenDeployer { - pom { - project { - parent { - groupId "org.springframework.boot" - artifactId "spring-boot-starter-parent" - version "{spring-boot-version}" - } - } - } - } - } - } ----- - - - -[[build-tool-plugins-gradle-publishing-artifacts-to-a-maven-repository-import]] -==== Configuring Gradle to produce a pom that imports dependency management -The following is an example of configuring Gradle to generate a pom that imports -the dependency management provided by `spring-boot-dependencies`. Please refer to the -http://www.gradle.org/docs/current/userguide/userguide.html[Gradle User Guide] for -further information. - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - uploadArchives { - repositories { - mavenDeployer { - pom { - project { - dependencyManagement { - dependencies { - dependency { - groupId "org.springframework.boot" - artifactId "spring-boot-dependencies" - version "{spring-boot-version}" - type "pom" - scope "import" - } - } - } - } - } - } - } - } ----- +The {spring-boot-gradle-plugin}[Spring Boot Gradle Plugin] provides Spring Boot support +in Gradle, allowing you to package executable jar or war archives, run Spring Boot +applications and use the dependency management provided by `spring-boot-dependencies`. +It requires Gradle 3.4 or later. Please refer to the {spring-boot-gradle-plugin}[plugin's +documentation] to learn more. diff --git a/spring-boot-docs/src/main/asciidoc/howto.adoc b/spring-boot-docs/src/main/asciidoc/howto.adoc index e4fea6f590..368919a213 100644 --- a/spring-boot-docs/src/main/asciidoc/howto.adoc +++ b/spring-boot-docs/src/main/asciidoc/howto.adoc @@ -827,12 +827,12 @@ Example in Gradle: [source,groovy,indent=0,subs="verbatim,quotes,attributes"] ---- configurations { - compile.exclude module: "spring-boot-starter-tomcat" + compile.exclude module: 'spring-boot-starter-tomcat' } dependencies { - compile("org.springframework.boot:spring-boot-starter-web:{spring-boot-version}") - compile("org.springframework.boot:spring-boot-starter-jetty:{spring-boot-version}") + compile 'org.springframework.boot:spring-boot-starter-web' + compile 'org.springframework.boot:spring-boot-starter-jetty' // ... } ---- @@ -881,12 +881,12 @@ Example in Gradle: [source,groovy,indent=0,subs="verbatim,quotes,attributes"] ---- configurations { - compile.exclude module: "spring-boot-starter-tomcat" + compile.exclude module: 'spring-boot-starter-tomcat' } dependencies { - compile("org.springframework.boot:spring-boot-starter-web:{spring-boot-version}") - compile("org.springframework.boot:spring-boot-starter-undertow:{spring-boot-version}") + compile 'org.springframework.boot:spring-boot-starter-web' + compile 'org.springframework.boot:spring-boot-starter-undertow' // ... } ---- @@ -2355,9 +2355,11 @@ To configure IntelliJ IDEA correctly you can use the `idea` Gradle plugin: [source,groovy,indent=0,subs="verbatim,attributes"] ---- buildscript { - repositories { jcenter() } + repositories { + jcenter() + } dependencies { - classpath "org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}" + classpath 'org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}' classpath 'org.springframework:springloaded:1.2.6.RELEASE' } } @@ -2424,7 +2426,7 @@ And to do the same with Gradle: [source,groovy,indent=0,subs="verbatim,attributes"] ---- - springBoot { + springBoot { buildInfo() } ---- @@ -2502,16 +2504,7 @@ the artifact yourself instead of overriding the property. WARNING: Each Spring Boot release is designed and tested against a specific set of third-party dependencies. Overriding versions may cause compatibility issues. -To override dependency versions in Gradle, you can specify a version as shown below: -[source,groovy,indent=0] ----- - ext['slf4j.version'] = '1.7.5' ----- - -For additional information, please refer to the -https://github.com/spring-gradle-plugins/dependency-management-plugin[Gradle Dependency -Management Plugin documentation]. [[howto-create-an-executable-jar-with-maven]] === Create an executable JAR with Maven @@ -2593,15 +2586,6 @@ To configure a classifier of `exec` in Maven, the following configuration can be ---- -And when using Gradle, the following configuration can be used: - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - bootRepackage { - classifier = 'exec' - } ----- - [[howto-extract-specific-libraries-when-an-executable-jar-runs]] @@ -2637,15 +2621,6 @@ you would add the following configuration: ---- -And to do that same with Gradle: - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - springBoot { - requiresUnpack = ['org.jruby:jruby-complete'] - } ----- - [[howto-create-a-nonexecutable-jar]] @@ -2689,29 +2664,6 @@ jar must be the main artifact and you can add a classified jar for the library: ---- -In Gradle you can create a new JAR archive with standard task DSL features, and then have -the `bootRepackage` task depend on that one using its `withJarTask` property: - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - jar { - baseName = 'spring-boot-sample-profile' - version = '0.0.0' - excludes = ['**/application.yml'] - } - - task('execJar', type:Jar, dependsOn: 'jar') { - baseName = 'spring-boot-sample-profile' - version = '0.0.0' - classifier = 'exec' - from sourceSets.main.output - } - - bootRepackage { - withJarTask = tasks['execJar'] - } ----- - [[howto-remote-debug-maven-run]] @@ -2723,34 +2675,6 @@ Check {spring-boot-maven-plugin-site}/examples/run-debug.html[this example] for -[[howto-remote-debug-gradle-run]] -=== Remote debug a Spring Boot application started with Gradle -To attach a remote debugger to a Spring Boot application started with Gradle you can use -the `jvmArgs` property of `bootRun` task or `--debug-jvm` command line option. - -`build.gradle`: - -[source,groovy,indent=0,subs="verbatim,attributes"] ----- - bootRun { - jvmArgs "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005" - } ----- - - -Command line: - -[indent=0] ----- - $ gradle bootRun --debug-jvm ----- - - -Check {gradle-userguide}/application_plugin.html[Gradle Application Plugin] for more -details. - - - [[howto-build-an-executable-archive-with-ant]] === Build an executable archive from Ant without using spring-boot-antlib To build with Ant you need to grab dependencies, compile and then create a jar or war @@ -2894,10 +2818,9 @@ And if you're using Gradle: } ---- -NOTE: If you are using a version of Gradle that supports compile only dependencies (2.12 -or later), you should continue to use `providedRuntime`. Among other limitations, -`compileOnly` dependencies are not on the test classpath so any web-based integration -tests will fail. +NOTE: `providedRuntime` is prefered to Gradle's `compileOnly` configuration as, among other +limitations, `compileOnly` dependencies are not on the test classpath so any web-based +integration tests will fail. If you're using the <>, marking the embedded servlet container dependency as provided will produce an executable war diff --git a/spring-boot-docs/src/main/asciidoc/index.adoc b/spring-boot-docs/src/main/asciidoc/index.adoc index de0438ccfb..d79d7e60b5 100644 --- a/spring-boot-docs/src/main/asciidoc/index.adoc +++ b/spring-boot-docs/src/main/asciidoc/index.adoc @@ -34,7 +34,8 @@ Phillip Webb; Dave Syer; Josh Long; Stéphane Nicoll; Rob Winch; Andy Wilkinson; :dc-spring-boot-test-autoconfigure: {dc-root}/org/springframework/boot/test/autoconfigure :dependency-management-plugin: https://github.com/spring-gradle-plugins/dependency-management-plugin :dependency-management-plugin-documentation: {dependency-management-plugin}/blob/master/README.md -:spring-boot-maven-plugin-site: http://docs.spring.io/spring-boot/docs/{spring-boot-docs-version}/maven-plugin +:spring-boot-maven-plugin-site: http://docs.spring.io/spring-boot/docs/{spring-boot-docs-version}/maven-plugin/ +:spring-boot-gradle-plugin: http://docs.spring.io/spring-boot/docs/{spring-boot-docs-version}/gradle-plugin/ :spring-reference: http://docs.spring.io/spring/docs/{spring-docs-version}/spring-framework-reference/htmlsingle :spring-security-reference: http://docs.spring.io/spring-security/site/docs/{spring-security-docs-version}/reference/htmlsingle :spring-security-oauth2-reference: http://projects.spring.io/spring-security-oauth/docs/oauth2.html @@ -50,8 +51,7 @@ Phillip Webb; Dave Syer; Josh Long; Stéphane Nicoll; Rob Winch; Andy Wilkinson; :propdeps-plugin: https://github.com/spring-projects/gradle-plugins/tree/master/propdeps-plugin :ant-manual: http://ant.apache.org/manual :code-examples: ../java/org/springframework/boot -:gradle-user-guide: https://docs.gradle.org/2.14.1/userguide -:gradle-dsl: https://docs.gradle.org/2.14.1/dsl +:gradle-user-guide: https://docs.gradle.org/3.4.1/userguide // ====================================================================================== include::documentation-overview.adoc[] diff --git a/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc b/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc index 8b8ea14149..7ac1ddb557 100644 --- a/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc +++ b/spring-boot-docs/src/main/asciidoc/using-spring-boot.adoc @@ -41,8 +41,8 @@ feel that's necessary. The curated list contains all the spring modules that you can use with Spring Boot as well as a refined list of third party libraries. The list is available as a standard <> -and additional dedicated support for <> and -<> are available as well. +that can be used with both <> and +{spring-boot-gradle-plugin}[Gradle]. WARNING: Each release of Spring Boot is associated with a base version of the Spring Framework so we **highly** recommend you to not specify its version on your own. @@ -194,70 +194,8 @@ the parent. [[using-boot-gradle]] === Gradle -Gradle users can directly import '`starters`' in their `dependencies` section. Unlike -Maven, there is no "`super parent`" to import to share some configuration. - -[source,groovy,indent=0,subs="attributes"] ----- - repositories { -ifeval::["{spring-boot-repo}" != "release"] - maven { url "http://repo.spring.io/snapshot" } - maven { url "http://repo.spring.io/milestone" } -endif::[] -ifeval::["{spring-boot-repo}" == "release"] - jcenter() -endif::[] - } - - dependencies { - compile("org.springframework.boot:spring-boot-starter-web:{spring-boot-version}") - } ----- - -The <> is also available and provides tasks to create executable -jars and run projects from source. It also provides -<> that, among -other capabilities, allows you to omit the version number for any dependencies that are -managed by Spring Boot: - -[source,groovy,indent=0,subs="attributes"] ----- -ifeval::["{spring-boot-repo}" == "release"] - plugins { - id 'org.springframework.boot' version '{spring-boot-version}' - id 'java' - } -endif::[] -ifeval::["{spring-boot-repo}" != "release"] - buildscript { - repositories { - jcenter() - maven { url 'http://repo.spring.io/snapshot' } - maven { url 'http://repo.spring.io/milestone' } - } - dependencies { - classpath 'org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-version}' - } - } - - apply plugin: 'java' - apply plugin: 'org.springframework.boot' -endif::[] - - repositories { - jcenter() -ifeval::["{spring-boot-repo}" != "release"] - maven { url 'http://repo.spring.io/snapshot' } - maven { url 'http://repo.spring.io/milestone' } -endif::[] - } - - dependencies { - compile("org.springframework.boot:spring-boot-starter-web") - testCompile("org.springframework.boot:spring-boot-starter-test") - } ----- +To learn about using Spring Boot with Gradle, please refer to the +{spring-boot-gradle-plugin}[documentation for Spring Boot's Gradle plugin]. @@ -704,8 +642,8 @@ You might also want to use the useful operating system environment variable: [[using-boot-running-with-the-gradle-plugin]] === Using the Gradle plugin The Spring Boot Gradle plugin also includes a `bootRun` task which can be used to run -your application in an exploded form. The `bootRun` task is added whenever you import -the `spring-boot-gradle-plugin`: +your application in an exploded form. The `bootRun` task is added whenever you apply the +the `org.springframework.boot` and `java` plugins: [indent=0,subs="attributes"] ---- diff --git a/spring-boot-tools/spring-boot-gradle-plugin/build.gradle b/spring-boot-tools/spring-boot-gradle-plugin/build.gradle index 01b42fef76..cc3fcc4975 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/build.gradle +++ b/spring-boot-tools/spring-boot-gradle-plugin/build.gradle @@ -46,7 +46,6 @@ jar { } } - eclipseJdt { inputFile = rootProject.file('../../eclipse/org.eclipse.jdt.core.prefs') doLast { @@ -56,6 +55,18 @@ eclipseJdt { } } +javadoc { + options { + author() + stylesheetFile = file('src/main/javadoc/spring-javadoc.css') + links = [ + 'http://docs.oracle.com/javase/8/docs/api/', + 'https://docs.gradle.org/current/javadoc/' + ] + } + title = "${project.description} $version API" +} + task sourcesJar(type: Jar) { classifier = 'sources' from sourceSets.main.allSource diff --git a/spring-boot-tools/spring-boot-gradle-plugin/pom.xml b/spring-boot-tools/spring-boot-gradle-plugin/pom.xml index e289a5b380..a9e432ece7 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/pom.xml +++ b/spring-boot-tools/spring-boot-gradle-plugin/pom.xml @@ -58,6 +58,7 @@ clean build -Pversion=${project.version} + -Pdescription=${project.description} @@ -112,5 +113,138 @@ gradlew.bat + + full + + + + org.apache.maven.plugins + maven-antrun-plugin + + + ant-contrib + ant-contrib + 1.0b3 + + + ant + ant + + + + + org.apache.ant + ant-nodeps + 1.8.1 + + + org.tigris.antelope + antelopetasks + 3.2.10 + + + + + set-up-maven-properties + prepare-package + + run + + + true + + + + + + + + + + + + + + + package-docs-zip + package + + run + + + + + + + + + + + + + + org.asciidoctor + asciidoctor-maven-plugin + 1.5.3 + + + generate-html-documentation + prepare-package + + process-asciidoc + + + html + + + + generate-pdf-documentation + prepare-package + + process-asciidoc + + + pdf + + + + + + ${version-type} + ${project.version} + + + + + org.asciidoctor + asciidoctorj-pdf + 1.5.0-alpha.11 + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + attach-zip + + attach-artifact + + + + + ${project.build.directory}/${project.artifactId}-${project.version}-docs.zip + zip + docs + + + + + + + + + diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/getting-started.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/getting-started.adoc new file mode 100644 index 0000000000..0ec83436f4 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/getting-started.adoc @@ -0,0 +1,43 @@ +[[getting-started]] +== Getting started + +To get started with the plugin it needs to be applied to your project. + +ifeval::["{version-type}" == "RELEASE"] +The plugin is https://plugins.gradle.org/plugin/org.springframework.boot[published to +Gradle's plugin portal] and can be applied using the `plugins` block: +[source,groovy,indent=0,subs="verbatim,attributes"] +---- +include::../gradle/getting-started/apply-plugin-release.gradle[] +---- +endif::[] +ifeval::["{version-type}" == "MILESTONE"] +[source,groovy,indent=0,subs="verbatim,attributes"] +---- +include::../gradle/getting-started/apply-plugin-milestone.gradle[] +---- +endif::[] +ifeval::["{version-type}" == "SNAPSHOT"] +[source,groovy,indent=0,subs="verbatim,attributes"] +---- +include::../gradle/getting-started/apply-plugin-snapshot.gradle[] +---- +endif::[] + +Applied in isolation the plugin makes few changes to a project. Instead, the plugin +detects when certain other plugins are applied and reacts accordingly. For example, when +the `java` plugin is applied a task for building an executable jar is automatically +configured. + +A typical Spring Boot project will apply the {groovy-plugin}[`groovy`], +{java-plugin}java_plugin.html[`java`], or {kotlin-plugin}[`org.jetbrains.kotlin.jvm`] +plugin and the {dependency-management-plugin}[`io.spring.dependency-management`] plugin as +a minimum. For example: + +[source,groovy,indent=0,subs="verbatim,attributes"] +---- +include::../gradle/getting-started/typical-plugins.gradle[tags=apply] +---- + +To learn more about how the Spring Boot plugin behaves when other plugins are applied +please see the section on <>. \ No newline at end of file diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/index.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/index.adoc new file mode 100644 index 0000000000..17645f4e9f --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/index.adoc @@ -0,0 +1,48 @@ += Spring Boot Gradle Plugin Reference Guide +Andy Wilkinson +:doctype: book +:toc: left +:toclevels: 4 +:source-highlighter: prettify +:numbered: +:icons: font +:hide-uri-scheme: +:dependency-management-plugin: https://github.com/spring-gradle-plugins/dependency-management-plugin +:dependency-management-plugin-documentation: {dependency-management-plugin}/blob/master/README.md +:gradle-userguide: http://www.gradle.org/docs/current/userguide +:gradle-dsl: https://docs.gradle.org/current/dsl +:application-plugin: {gradle-userguide}/application_plugin.html +:groovy-plugin: {gradle-userguide}/groovy_plugin.html +:java-plugin: {gradle-userguide}/java_plugin.html +:war-plugin: {gradle-userguide}/war_plugin.html +:maven-plugin: {gradle-userguide}/maven_plugin.html +:maven-publish-plugin: {gradle-userguide}/maven_publish_plugin.html +:software-component: {gradle-userguide}/software_model_extend.html +:kotlin-plugin: https://kotlinlang.org/docs/reference/using-gradle.html +:spring-boot-docs: https://docs.spring.io/spring-boot/{version} +:api-documentation: {spring-boot-docs}/gradle-plugin/api +:spring-boot-reference: {spring-boot-docs}/reference/htmlsingle +:build-info-javadoc: {api-documentation}/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.html +:boot-jar-javadoc: {api-documentation}/org/springframework/boot/gradle/tasks/bundling/BootJar.html +:boot-war-javadoc: {api-documentation}/org/springframework/boot/gradle/tasks/bundling/BootWar.html +:boot-run-javadoc: {api-documentation}/org/springframework/boot/gradle/tasks/run/BootRun.html +:github-code: https://github.com/spring-projects/spring-boot/tree/{github-tag} + + + +[[introduction]] +== Introduction + +The Spring Boot Gradle Plugin provides Spring Boot support in https://gradle.org[Gradle], +allowing you to package executable jar or war archives, run Spring Boot applications, and +use the dependency management provided by `spring-boot-dependencies`. Spring Boot's +Gradle plugin requires Gradle 3.4 or later. + +In addition to this user guide, {api-documentation}[API documentation] is also available. + +include::getting-started.adoc[] +include::managing-dependencies.adoc[] +include::packaging.adoc[] +include::running.adoc[] +include::integrating-with-actuator.adoc[] +include::reacting.adoc[] \ No newline at end of file diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/integrating-with-actuator.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/integrating-with-actuator.adoc new file mode 100644 index 0000000000..0460273bbc --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/integrating-with-actuator.adoc @@ -0,0 +1,55 @@ +[[integrating-with-actuator]] +== Integrating with Actuator + + +[[integrating-with-actuator-build-info]] +=== Generating build information + +Spring Boot Actuator's `info` endpoint automatically publishes information about your +build in the presence of a `META-INF/build-info.properties` file. A +{build-info-javadoc}[`BuildInfo`] task is provided to generate this file. The easiest way +to use the task is via the plugin's DSL: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/integrating-with-actuator/build-info-basic.gradle[tags=build-info] +---- + +This will configure a {build-info-javadoc}[`BuildInfo`] task named `bootBuildInfo` and, if +it exists, make the Java plugin's `classes` task depend upon it. The task's desination +directory will be `META-INF` in the output directory of the main source set's resources +(typically `build/resources/main`). + +By default, the generated build information is derived from the project: + +|=== +| Property | Default value + +| `build.artifact` +| The base name of the `bootJar` or `bootWar` task, or `unspecified` if no such task + exists + +| `build.group` +| The group of the project + +| `build.name` +| The name of the project + +| `build.version` +| The version of the project + +|=== + +The properties can be customized using the DSL: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/integrating-with-actuator/build-info-custom-values.gradle[tags=custom-values] +---- + +Additional properties can also be added to the build information: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/integrating-with-actuator/build-info-additional.gradle[tags=additional] +---- diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc new file mode 100644 index 0000000000..31981561b3 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc @@ -0,0 +1,46 @@ +[[managing-dependencies]] +== Managing dependencies + +When you apply the {dependency-management-plugin}[`io.spring.dependency-management`] +plugin, Spring Boot's plugin will +automatically <> from the version of Spring Boot that you are using. +This provides a similar dependency management experience to the one that's enjoyed by +Maven users. For example, it allows you to omit version numbers when declaring +dependencies that are managed in the bom. To make use of this functionality, simply +declare dependencies in the usual way but omit the version number: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/managing-dependencies/dependencies.gradle[tags=dependencies] +---- + + + +[[managing-dependencies-customizing]] +=== Customizing managed versions + +The `spring-boot-dependencies` bom that is automatically imported when the dependency +management plugin is applied uses properties to control the versions of the dependencies +that it manages. Please refer to the {github-code}/spring-boot-dependencies/pom.xml[bom] +for a complete list of these properties. + +To customize a managed version you set its corresponding property. For example, to +customize the version of SLF4J which is controlled by the `slf4j.version` property: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/managing-dependencies/custom-version.gradle[tags=custom-version] +---- + +WARNING: Each Spring Boot release is designed and tested against a specific set of +third-party dependencies. Overriding versions may cause compatibility issues and should +be done with care. + + + +[[managing-dependencies-learning-more]] +=== Learning more + +To learn more about the capabilities of the dependency management plugin, please refer to +its {dependency-management-plugin-documentation}[documentation]. \ No newline at end of file diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/packaging.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/packaging.adoc new file mode 100644 index 0000000000..686f20a4ea --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/packaging.adoc @@ -0,0 +1,167 @@ +[[packaging-executable]] +== Packaging executable archives + +The plugin can create executable archives (jar files and war files) that contain all of +an application's dependencies and can then be run with `java -jar`. + + + +[[packaging-executable-jars]] +=== Packaging executable jars + +Executable jars can be built using the `bootJar` task. The task is automatically created +when the `java` plugin is applied and is an instance of {boot-jar-javadoc}[`BootJar`]. + + + +[[packaging-executable-wars]] +=== Packaging executable wars + +Executable wars can be built using the `bootWar` task. The task is automatically created +when the `war` plugin is applied and is an instance of {boot-war-javadoc}[`BootWar`]. + + + +[[packaging-executable-wars-deployable]] +==== Packaging executable and deployable wars + +A war file can be packaged such that it can be executed using `java -jar` and deployed +to an external container. To do so, the embedded servlet container dependencies should +be added to the `providedRuntime` configuration, for example: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/packaging/war-container-dependency.gradle[tags=dependencies] +---- + +This ensures that they are package in the war file's `WEB-INF/lib-provided` directory +from where they will not conflict with the external container's own classes. + +NOTE: `providedRuntime` is prefered to Gradle's `compileOnly` configuration as, among +other limitations, `compileOnly` dependencies are not on the test classpath so any +web-based integration tests will fail. + + + +[[packaging-executable-configuring]] +=== Configuring executable archive packaging + +The {boot-jar-javadoc}[`BootJar`] and {boot-war-javadoc}[`BootWar`] tasks are subclasses +of Gradle's `Jar` and `War` tasks respectively. As a result, all of the standard +configuration options that are available when packaging a jar or war are also available +when packaging an executable jar or war. A number of configuration options that are +specific to executable jars and wars are also provided. + + +[[packaging-executable-configuring-main-class]] +==== Configuring the main class + +By default, the executable archive's main class will be configured automatically by +looking for a class with a `public static void main(String[])` method in directories on +the task's classpath. + +The main class can also be configured explicity using the task's `mainClass` property: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/packaging/boot-jar-main-class.gradle[tags=main-class] +---- + +Alternatively, if the {application-plugin}[`application` plugin] has been applied +its `mainClassName` project property can be used: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/packaging/application-plugin-main-class.gradle[tags=main-class] +---- + +Lastly, the `Start-Class` attribute can be configured on the task's manifest: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/packaging/boot-jar-manifest-main-class.gradle[tags=main-class] +---- + + + +[[packaging-executable-configuring-excluding-devtools]] +==== Excluding Devtools + +By default, Spring Boot's Devtools module, +`org.springframework.boot:spring-boot-devtools`, will be excluded from an executable jar +or war. If you want to include Devtools in your archive set the `excludeDevtools` +property to `true`: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/packaging/boot-war-include-devtools.gradle[tags=include-devtools] +---- + + + +[[packaging-executable-configuring-unpacking]] +==== Configuring libraries that require unpacking + +Most libraries can be used directly when nested in an executable archive, however certain +libraries can have problems. For example, JRuby includes its own nested jar support which +assumes that `jruby-complete.jar` is always directly available on the file system. + +To deal with any problematic libraries, an executable archive can be configured to unpack +specific nested jars to a temporary folder when the executable archive is run. Libraries +can be identified as requiring unpacking using Ant-style patterns that match against +the absolute path of the source jar file: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/packaging/boot-jar-requires-unpack.gradle[tags=requires-unpack] +---- + +For more control a closure can also be used. The closure is passed a `FileTreeElement` +and should return a `boolean` indicating whether or not unpacking is required. + + + +[[packaging-executable-configuring-launch-script]] +==== Making an archive fully executable + +Spring Boot provides support for fully executable archives. An archive is made fully +executable by prepending a shell script that knows how to launch the application. On +Unix-like platforms, this launch script allows the archive to be run directly like any +other executable or to be installed as a service. + +To use this feature, the inclusion of the launch script must be enabled: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/packaging/boot-jar-include-launch-script.gradle[tags=include-launch-script] +---- + +This will add Spring Boot's default launch script to the archive. The default launch +script includes several properties with sensible default values. The values can be +customized using the `properties` property: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/packaging/boot-jar-launch-script-properties.gradle[tags=launch-script-properties] +---- + +If the default launch script does not meet your needs, the `script` property can be used +to provide a custom launch script: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/packaging/boot-jar-custom-launch-script.gradle[tags=custom-launch-script] +---- + + + +[[packaging-executable-configuring-properties-launcher]] +==== Using the `PropertiesLauncher` + +To use the `PropertiesLauncher` to launch an executable jar or war, configure the task's +manifest to set the `Main-Class` attribute: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/packaging/boot-war-properties-launcher.gradle[tags=properties-launcher] +---- \ No newline at end of file diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/publishing.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/publishing.adoc new file mode 100644 index 0000000000..69be4ed6ce --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/publishing.adoc @@ -0,0 +1,43 @@ +[[publishing-your-application]] +== Publishing your application + + + +[[publishing-your-application-maven]] +=== Publishing with the `maven` plugin + +When the {maven-plugin}[`maven` plugin] is applied, an `Upload` task for the +`bootArchives` configuration named `uploadBootArchives` is automatically created. By +default, the `bootArchives` configuration contains the archive produced by the `bootJar` +or `bootWar` task. The `uploadBootArchives` task can be configured to publish the archive +to a Maven repository: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/publishing/maven.gradle[tags=upload] +---- + +[[publishing-your-application-maven-publish]] +=== Publishing with the `maven-publish` plugin + +When the {java-plugin}[`java` plugin] is applied Spring Boot automatically creates a +{software-component}[software component] named `bootJava`. Similarly, when the `war` +plugin is applied, a software component named `bootWeb` is created. `bootJava` contains +the archive produced by the `bootJar` task and `bootWeb` contains the archive provided by +the `bootWar` task. The components can be used with the +{maven-publish-plugin}[`maven-publish` plugin] to publish the archive, for example: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/publishing/maven-publish.gradle[tags=publishing] +---- + + + +[[publishing-your-application-distrubution]] +=== Distributing with the `application` plugin + +When the {application-plugin}[`application` plugin] is applied a distribution named +`boot` is created. This distribution contains the archive produced by the `bootJar` or +`bootWar` task and scripts to launch it on Unix-like platforms and Windows. Zip and tar +distributions can be built by the `bootDistZip` and `bootDistTar` tasks respectively. diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc new file mode 100644 index 0000000000..4c5fa9a8c1 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc @@ -0,0 +1,78 @@ +[[reacting-to-other-plugins]] +== Reacting to other plugins + +When another plugin is applied the Spring Boot plugin reacts by making various changes +to the project's configuration. This section describes those changes. + +[[reacting-to-other-plugins-java]] +=== Reacting to the Java plugin + +When Gradle's {java-plugin}[`java` plugin] is applied to a project, the Spring Boot +plugin: + +1. Creates a {boot-jar-javadoc}[`BootJar`] task named `bootJar` that will create an + executable, fat jar for the project. The jar will contain everything on the runtime + classpath of the main source set; classes are packaged in `BOOT-INF/classes` and jars + are packaged in `BOOT-INF/lib` +2. Creates a {software-component}[software component] named `bootJava` that contains the + archive produced by the `bootJar` task. +3. Creates a {boot-run-javadoc}[`BootRun`] task named `bootRun` that can be used to run + your application. +4. Creates a configuration named `bootArchives` that contains the artifact produced by + the `bootJar` task. +5. Configures any `JavaCompile` tasks with no configured encoding to use `UTF-8`. + + + +[[reacting-to-other-plugins-war]] +=== Reacting to the war plugin + +When Gradle's {war-plugin}[`war` plugin] is applied to a project, the Spring Boot plugin: + +1. Creates a {boot-war-javadoc}[`BootWar`] task named `bootWar` that will create an + executable, fat war for the project. In addition to the standard packaging, everything + in the `providedRuntime` configuration will be packaged in `WEB-INF/lib-provided`. +2. Creates a {software-component}[software component] named `bootWeb` that contains the + archive produced by the `bootWar` task. +3. Configures the `bootArchives` configuration to contain the artifact produced by the + `bootWar` task. + + + +[[reacting-to-other-plugins-dependency-management]] +=== Reacting to the dependency management plugin + +When the {dependency-management-plugin}[`io.spring.dependency-management` plugin] is +applied to a project, the Spring Boot plugin will automatically import the +`spring-boot-dependencies` bom. + + + +[[reacting-to-other-plugins-application]] +=== Reacting to the application plugin + +When Gradle's {application-plugin}[`application` plugin] is applied to a project, the +Spring Boot plugin: + +1. Creates a `CreateStartScripts` task named `bootStartScripts` that will creates scripts + that launch the artifact in the `bootArchives` configuration using `java -jar`. +2. Creates a new distribution named `boot` and configures it to contain the artifact in + the `bootArchives` configuration in its `lib` directory and the start scripts in its + `bin` directory. +3. Configures the `bootRun` task to use the `mainClassName` property as a convention for + its `main` property. +4. Configures the `bootRun` task to use the `applicationDefaultJvmArgs` property as a + convention for its `jvmArgs` property. +5. Configures the `bootJar` task to use the `mainClassName` property as a convention for + the `Start-Class` entry in its manifest. +6. Configures the `bootWar` task to use the `mainClassName` property as a convention for + the `Start-Class` entry in its manifest. + + + +[[reacting-to-other-plugins-maven]] +=== Reacting to the Maven plugin + +When Gradle's {maven-plugin}[`maven` plugin] is applied to a project, the Spring Boot +plugin will configure the `uploadBootArchives` `Upload` task to ensure that no +dependencies are declared in the pom that it generates. diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/running.adoc b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/running.adoc new file mode 100644 index 0000000000..5a8f0cb1ec --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/running.adoc @@ -0,0 +1,49 @@ +[[running-your-application]] +== Running your application with Gradle + +To run your application without first building an archive use the `bootRun` task: + +[source,bash,indent=0,subs="verbatim"] +---- + $ ./gradlew bootRun +---- + +The `bootRun` task is an instance of +{boot-run-javadoc}[`BootRun`] which is a `JavaExec` subclass. As such, all of the +{gradle-dsl}/org.gradle.api.tasks.JavaExec.html[usual configuration options] for executing +a Java process in Gradle are available to you. The task is automatically configured to use +the runtime classpath of the main source set. + +By default, the main class will be configured automatically by looking for a class with a +`public static void main(String[])` method in directories on the task's classpath. + +The main class can also be configured explicity using the task's `main` property: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/running/boot-run-main.gradle[tags=main] +---- + +Alternatively, if the {application-plugin}[`application` plugin] has been applied +its `mainClassName` project property can be used: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/running/application-plugin-main-class-name.gradle[tags=main-class] +---- + + + +[[running-your-application-reloading-resources]] +=== Reloading resources +If devtools has been added to your project it will automatically monitor your +application for changes. Alternatively, you can configure `bootRun` such that your +application's static resources are loaded from their source location: + +[source,groovy,indent=0,subs="verbatim"] +---- +include::../gradle/running/boot-run-source-resources.gradle[tags=source-resources] +---- + +This makes them reloadable in the live application which can be helpful at development +time. diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-milestone.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-milestone.gradle new file mode 100644 index 0000000000..0302ec6f4d --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-milestone.gradle @@ -0,0 +1,11 @@ +buildscript { + repositories { + maven { url 'https://repo.spring.io/libs-milestone' } + } + + dependencies { + classpath 'org.springframework.boot:spring-boot-gradle-plugin:{version}' + } +} + +apply plugin: 'org.springframework.boot' diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-release.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-release.gradle new file mode 100644 index 0000000000..cf13509ffd --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-release.gradle @@ -0,0 +1,3 @@ +plugins { + id 'org.springframework.boot' version '{version}' +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-snapshot.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-snapshot.gradle new file mode 100644 index 0000000000..c775fa0925 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-snapshot.gradle @@ -0,0 +1,11 @@ +buildscript { + repositories { + maven { url 'https://repo.spring.io/libs-snapshot' } + } + + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/typical-plugins.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/typical-plugins.gradle new file mode 100644 index 0000000000..6549d2bd3e --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/typical-plugins.gradle @@ -0,0 +1,17 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +// tag::apply[] +apply plugin: 'java' +apply plugin: 'io.spring.dependency-management' +// end::apply[] + +task verify { + doLast { + plugins.getPlugin(org.gradle.api.plugins.JavaPlugin.class) + plugins.getPlugin(io.spring.gradle.dependencymanagement.DependencyManagementPlugin.class) + } +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-additional.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-additional.gradle new file mode 100644 index 0000000000..a70995ea38 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-additional.gradle @@ -0,0 +1,21 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' + +// tag::additional[] +springBoot { + buildInfo { + properties { + additional = [ + 'a': 'alpha', + 'b': 'bravo' + ] + } + } +} +// end::additional[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-basic.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-basic.gradle new file mode 100644 index 0000000000..43329cdd61 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-basic.gradle @@ -0,0 +1,14 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' + +// tag::build-info[] +springBoot { + buildInfo() +} +// end::build-info[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle new file mode 100644 index 0000000000..c8e8b0b416 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle @@ -0,0 +1,21 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' + +// tag::custom-values[] +springBoot { + buildInfo { + properties { + artifact = 'example-app' + version = '1.2.3' + group = 'com.example' + name = 'Example application' + } + } +} +// end::custom-values[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle new file mode 100644 index 0000000000..54009ee8c2 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/custom-version.gradle @@ -0,0 +1,32 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'io.spring.dependency-management' + +dependencyManagement { + resolutionStrategy { + eachDependency { + if (it.requested.group == 'org.springframework.boot') { + it.useVersion project.bootVersion + } + } + } +} + +// tag::custom-version[] +ext['slf4j.version'] = '1.7.20' +// end::custom-version[] + +repositories { + mavenLocal() +} + +task slf4jVersion { + doLast { + println dependencyManagement.managedVersions['org.slf4j:slf4j-api'] + } +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/dependencies.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/dependencies.gradle new file mode 100644 index 0000000000..ecbf6ffedc --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/dependencies.gradle @@ -0,0 +1,19 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +plugins { + id 'java' +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'io.spring.dependency-management' + +// tag::dependencies[] +dependencies { + compile 'org.springframework.boot:spring-boot-starter-web' + compile 'org.springframework.boot:spring-boot-starter-data-jpa' +} +// end::dependencies[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/application-plugin-main-class.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/application-plugin-main-class.gradle new file mode 100644 index 0000000000..b91321d8fd --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/application-plugin-main-class.gradle @@ -0,0 +1,13 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' +apply plugin: 'application' + +// tag::main-class[] +mainClassName = 'com.example.ExampleApplication' +// end::main-class[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-custom-launch-script.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-custom-launch-script.gradle new file mode 100644 index 0000000000..c813b9a134 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-custom-launch-script.gradle @@ -0,0 +1,21 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' + +bootJar { + mainClass 'com.example.ExampleApplication' +} + +// tag::custom-launch-script[] +bootJar { + launchScript { + included = true + script = file('src/custom.script') + } +} +// end::custom-launch-script[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-include-launch-script.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-include-launch-script.gradle new file mode 100644 index 0000000000..6df82aeb19 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-include-launch-script.gradle @@ -0,0 +1,20 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' + +bootJar { + mainClass 'com.example.ExampleApplication' +} + +// tag::include-launch-script[] +bootJar { + launchScript { + included = true + } +} +// end::include-launch-script[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-launch-script-properties.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-launch-script-properties.gradle new file mode 100644 index 0000000000..1de01e52b5 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-launch-script-properties.gradle @@ -0,0 +1,21 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' + +bootJar { + mainClass 'com.example.ExampleApplication' +} + +// tag::launch-script-properties[] +bootJar { + launchScript { + included = true + properties 'logFilename': 'example-app.log' + } +} +// end::launch-script-properties[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-main-class.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-main-class.gradle new file mode 100644 index 0000000000..b3ce53b9ec --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-main-class.gradle @@ -0,0 +1,14 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' + +// tag::main-class[] +bootJar { + mainClass = 'com.example.ExampleApplication' +} +// end::main-class[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-manifest-main-class.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-manifest-main-class.gradle new file mode 100644 index 0000000000..557242e3f1 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-manifest-main-class.gradle @@ -0,0 +1,16 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' + +// tag::main-class[] +bootJar { + manifest { + attributes 'Start-Class': 'com.example.ExampleApplication' + } +} +// end::main-class[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-requires-unpack.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-requires-unpack.gradle new file mode 100644 index 0000000000..e21da8d831 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-jar-requires-unpack.gradle @@ -0,0 +1,26 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' + +repositories { + mavenCentral() +} + +dependencies { + runtime 'org.jruby:jruby-complete:1.7.25' +} + +bootJar { + mainClass 'com.example.ExampleApplication' +} + +// tag::requires-unpack[] +bootJar { + requiresUnpack '**/jruby-complete-*.jar' +} +// end::requires-unpack[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-include-devtools.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-include-devtools.gradle new file mode 100644 index 0000000000..a739250d3b --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-include-devtools.gradle @@ -0,0 +1,19 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'war' + +bootWar { + mainClass 'com.example.ExampleApplication' + classpath file('spring-boot-devtools-1.2.3.RELEASE.jar') +} + +// tag::include-devtools[] +bootWar { + excludeDevtools = false +} +// end::include-devtools[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-properties-launcher.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-properties-launcher.gradle new file mode 100644 index 0000000000..a2d915d905 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/boot-war-properties-launcher.gradle @@ -0,0 +1,20 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'war' + +bootWar { + mainClass 'com.example.ExampleApplication' +} + +// tag::properties-launcher[] +bootWar { + manifest { + attributes 'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher' + } +} +// end::properties-launcher[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/war-container-dependency.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/war-container-dependency.gradle new file mode 100644 index 0000000000..9f8c91b64e --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/packaging/war-container-dependency.gradle @@ -0,0 +1,19 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +plugins { + id 'war' +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'io.spring.dependency-management' + +// tag::dependencies[] +dependencies { + compile 'org.springframework.boot:spring-boot-starter-web' + providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' +} +// end::dependencies[] diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven-publish.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven-publish.gradle new file mode 100644 index 0000000000..61ded0c357 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven-publish.gradle @@ -0,0 +1,31 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' +apply plugin: 'maven-publish' + +// tag::publishing[] +publishing { + publications { + bootJava(MavenPublication) { + from components.bootJava + } + } + repositories { + maven { + url 'https://repo.example.com' + } + } +} +// end::publishing[] + +task publishingConfiguration { + doLast { + println publishing.publications.bootJava + println publishing.repositories.maven.url + } +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven.gradle new file mode 100644 index 0000000000..8adefa0643 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/publishing/maven.gradle @@ -0,0 +1,25 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' +apply plugin: 'maven' + +// tag::upload[] +uploadBootArchives { + repositories { + mavenDeployer { + repository url: 'https://repo.example.com' + } + } +} +// end::upload[] + +task deployerRepository { + doLast { + println uploadBootArchives.repositories.mavenDeployer.repository.url + } +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/application-plugin-main-class-name.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/application-plugin-main-class-name.gradle new file mode 100644 index 0000000000..6e05ceaa3d --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/application-plugin-main-class-name.gradle @@ -0,0 +1,19 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' +apply plugin: 'application' + +// tag::main-class[] +mainClassName = 'com.example.ExampleApplication' +// end::main-class[] + +task configuredMainClass { + doLast { + println bootRun.main + } +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-main.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-main.gradle new file mode 100644 index 0000000000..82907a4c4e --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-main.gradle @@ -0,0 +1,20 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' + +// tag::main[] +bootRun { + main = 'com.example.ExampleApplication' +} +// end::main[] + +task configuredMainClass { + doLast { + println bootRun.main + } +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-source-resources.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-source-resources.gradle new file mode 100644 index 0000000000..19b016b526 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/running/boot-run-source-resources.gradle @@ -0,0 +1,20 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' +apply plugin: 'java' + +// tag::source-resources[] +bootRun { + sourceResources sourceSets.main +} +// end::source-resources[] + +task configuredClasspath { + doLast { + println bootRun.classpath.files + } +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/javadoc/spring-javadoc.css b/spring-boot-tools/spring-boot-gradle-plugin/src/main/javadoc/spring-javadoc.css new file mode 100644 index 0000000000..06ad42277c --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/javadoc/spring-javadoc.css @@ -0,0 +1,599 @@ +/* Javadoc style sheet */ +/* +Overall document style +*/ + +@import url('resources/fonts/dejavu.css'); + +body { + background-color:#ffffff; + color:#353833; + font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; + font-size:14px; + margin:0; +} +a:link, a:visited { + text-decoration:none; + color:#4A6782; +} +a:hover, a:focus { + text-decoration:none; + color:#bb7a2a; +} +a:active { + text-decoration:none; + color:#4A6782; +} +a[name] { + color:#353833; +} +a[name]:hover { + text-decoration:none; + color:#353833; +} +pre { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; +} +h1 { + font-size:20px; +} +h2 { + font-size:18px; +} +h3 { + font-size:16px; + font-style:italic; +} +h4 { + font-size:13px; +} +h5 { + font-size:12px; +} +h6 { + font-size:11px; +} +ul { + list-style-type:disc; +} +code, tt { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + padding-top:4px; + margin-top:8px; + line-height:1.4em; +} +dt code { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + padding-top:4px; +} +table tr td dt code { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + vertical-align:top; + padding-top:4px; +} +sup { + font-size:8px; +} +/* +Document title and Copyright styles +*/ +.clear { + clear:both; + height:0px; + overflow:hidden; +} +.aboutLanguage { + float:right; + padding:0px 21px; + font-size:11px; + z-index:200; + margin-top:-9px; +} +.legalCopy { + margin-left:.5em; +} +.bar a, .bar a:link, .bar a:visited, .bar a:active { + color:#FFFFFF; + text-decoration:none; +} +.bar a:hover, .bar a:focus { + color:#bb7a2a; +} +.tab { + background-color:#0066FF; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* +Navigation bar styles +*/ +.bar { + background-color:#4D7A97; + color:#FFFFFF; + padding:.8em .5em .4em .8em; + height:auto;/*height:1.8em;*/ + font-size:11px; + margin:0; +} +.topNav { + background-color:#4D7A97; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; + font-size:12px; +} +.bottomNav { + margin-top:10px; + background-color:#4D7A97; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + height:2.8em; + padding-top:10px; + overflow:hidden; + font-size:12px; +} +.subNav { + background-color:#dee3e9; + float:left; + width:100%; + overflow:hidden; + font-size:12px; +} +.subNav div { + clear:left; + float:left; + padding:0 0 5px 6px; + text-transform:uppercase; +} +ul.navList, ul.subNavList { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.navList li{ + list-style:none; + float:left; + padding: 5px 6px; + text-transform:uppercase; +} +ul.subNavList li{ + list-style:none; + float:left; +} +.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { + color:#FFFFFF; + text-decoration:none; + text-transform:uppercase; +} +.topNav a:hover, .bottomNav a:hover { + text-decoration:none; + color:#bb7a2a; + text-transform:uppercase; +} +.navBarCell1Rev { + background-color:#F8981D; + color:#253441; + margin: auto 5px; +} +.skipNav { + position:absolute; + top:auto; + left:-9999px; + overflow:hidden; +} +/* +Page header and footer styles +*/ +.header, .footer { + clear:both; + margin:0 20px; + padding:5px 0 0 0; +} +.indexHeader { + margin:10px; + position:relative; +} +.indexHeader span{ + margin-right:15px; +} +.indexHeader h1 { + font-size:13px; +} +.title { + color:#2c4557; + margin:10px 0; +} +.subTitle { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 15px 0; + padding:0; +} +.footer ul { + margin:20px 0 5px 0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:13px; +} +/* +Heading styles +*/ +div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { + background-color:#dee3e9; + border:1px solid #d0d9e0; + margin:0 0 6px -8px; + padding:7px 5px; +} +ul.blockList ul.blockList ul.blockList li.blockList h3 { + background-color:#dee3e9; + border:1px solid #d0d9e0; + margin:0 0 6px -8px; + padding:7px 5px; +} +ul.blockList ul.blockList li.blockList h3 { + padding:0; + margin:15px 0; +} +ul.blockList li.blockList h2 { + padding:0px 0 20px 0; +} +/* +Page layout container styles +*/ +.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { + clear:both; + padding:10px 20px; + position:relative; +} +.indexContainer { + margin:10px; + position:relative; + font-size:12px; +} +.indexContainer h2 { + font-size:13px; + padding:0 0 3px 0; +} +.indexContainer ul { + margin:0; + padding:0; +} +.indexContainer ul li { + list-style:none; + padding-top:2px; +} +.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { + font-size:12px; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { + margin:5px 0 10px 0px; + font-size:14px; + font-family:'DejaVu Sans Mono',monospace; +} +.serializedFormContainer dl.nameValue dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +.serializedFormContainer dl.nameValue dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* +List styles +*/ +ul.horizontal li { + display:inline; + font-size:0.9em; +} +ul.inheritance { + margin:0; + padding:0; +} +ul.inheritance li { + display:inline; + list-style:none; +} +ul.inheritance li ul.inheritance { + margin-left:15px; + padding-left:15px; + padding-top:1px; +} +ul.blockList, ul.blockListLast { + margin:10px 0 10px 0; + padding:0; +} +ul.blockList li.blockList, ul.blockListLast li.blockList { + list-style:none; + margin-bottom:15px; + line-height:1.4; +} +ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { + padding:0px 20px 5px 10px; + border:1px solid #ededed; + background-color:#f8f8f8; +} +ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { + padding:0 0 5px 8px; + background-color:#ffffff; + border:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { + margin-left:0; + padding-left:0; + padding-bottom:15px; + border:none; +} +ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { + list-style:none; + border-bottom:none; + padding-bottom:0; +} +table tr td dl, table tr td dl dt, table tr td dl dd { + margin-top:0; + margin-bottom:1px; +} +/* +Table styles +*/ +.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { + width:100%; + border-left:1px solid #EEE; + border-right:1px solid #EEE; + border-bottom:1px solid #EEE; +} +.overviewSummary, .memberSummary { + padding:0px; +} +.overviewSummary caption, .memberSummary caption, .typeSummary caption, +.useSummary caption, .constantsSummary caption, .deprecatedSummary caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#253441; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0px; + padding-top:10px; + padding-left:1px; + margin:0px; + white-space:pre; +} +.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, +.useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, +.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, +.useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, +.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, +.useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, +.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, +.useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { + color:#FFFFFF; +} +.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, +.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { + white-space:nowrap; + padding-top:5px; + padding-left:12px; + padding-right:12px; + padding-bottom:7px; + display:inline-block; + float:left; + background-color:#F8981D; + border: none; + height:16px; +} +.memberSummary caption span.activeTableTab span { + white-space:nowrap; + padding-top:5px; + padding-left:12px; + padding-right:12px; + margin-right:3px; + display:inline-block; + float:left; + background-color:#F8981D; + height:16px; +} +.memberSummary caption span.tableTab span { + white-space:nowrap; + padding-top:5px; + padding-left:12px; + padding-right:12px; + margin-right:3px; + display:inline-block; + float:left; + background-color:#4D7A97; + height:16px; +} +.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { + padding-top:0px; + padding-left:0px; + padding-right:0px; + background-image:none; + float:none; + display:inline; +} +.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, +.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { + display:none; + width:5px; + position:relative; + float:left; + background-color:#F8981D; +} +.memberSummary .activeTableTab .tabEnd { + display:none; + width:5px; + margin-right:3px; + position:relative; + float:left; + background-color:#F8981D; +} +.memberSummary .tableTab .tabEnd { + display:none; + width:5px; + margin-right:3px; + position:relative; + background-color:#4D7A97; + float:left; + +} +.overviewSummary td, .memberSummary td, .typeSummary td, +.useSummary td, .constantsSummary td, .deprecatedSummary td { + text-align:left; + padding:0px 0px 12px 10px; + width:100%; +} +th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, +td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ + vertical-align:top; + padding-right:0px; + padding-top:8px; + padding-bottom:3px; +} +th.colFirst, th.colLast, th.colOne, .constantsSummary th { + background:#dee3e9; + text-align:left; + padding:8px 3px 3px 7px; +} +td.colFirst, th.colFirst { + white-space:nowrap; + font-size:13px; +} +td.colLast, th.colLast { + font-size:13px; +} +td.colOne, th.colOne { + font-size:13px; +} +.overviewSummary td.colFirst, .overviewSummary th.colFirst, +.overviewSummary td.colOne, .overviewSummary th.colOne, +.memberSummary td.colFirst, .memberSummary th.colFirst, +.memberSummary td.colOne, .memberSummary th.colOne, +.typeSummary td.colFirst{ + width:25%; + vertical-align:top; +} +td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { + font-weight:bold; +} +.tableSubHeadingColor { + background-color:#EEEEFF; +} +.altColor { + background-color:#FFFFFF; +} +.rowColor { + background-color:#EEEEEF; +} +/* +Content styles +*/ +.description pre { + margin-top:0; +} +.deprecatedContent { + margin:0; + padding:10px 0; +} +.docSummary { + padding:0; +} + +ul.blockList ul.blockList ul.blockList li.blockList h3 { + font-style:normal; +} + +div.block { + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; +} + +td.colLast div { + padding-top:0px; +} + + +td.colLast a { + padding-bottom:3px; +} +/* +Formatting effect styles +*/ +.sourceLineNo { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:10px; +} +.block { + display:block; + margin:3px 10px 2px 0px; + color:#474747; +} +.deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, +.overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, +.seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { + font-weight:bold; +} +.deprecationComment, .emphasizedPhrase, .interfaceName { + font-style:italic; +} + +div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, +div.block div.block span.interfaceName { + font-style:normal; +} + +div.contentContainer ul.blockList li.blockList h2{ + padding-bottom:0px; +} + + + +/* +Spring +*/ + +pre.code { + background-color: #F8F8F8; + border: 1px solid #CCCCCC; + border-radius: 3px 3px 3px 3px; + overflow: auto; + padding: 10px; + margin: 4px 20px 2px 0px; +} + +pre.code code, pre.code code * { + font-size: 1em; +} + +pre.code code, pre.code code * { + padding: 0 !important; + margin: 0 !important; +} + diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/GettingStartedDocumentationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/GettingStartedDocumentationTests.java new file mode 100644 index 0000000000..4c05d9f646 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/GettingStartedDocumentationTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.gradle.docs; + +import org.junit.Rule; +import org.junit.Test; + +import org.springframework.boot.gradle.testkit.GradleBuild; + +/** + * Tests for the getting started documentation. + * + * @author Andy Wilkinson + */ +public class GettingStartedDocumentationTests { + + @Rule + public GradleBuild gradleBuild = new GradleBuild(); + + @Test + public void applyPluginSnapshotExampleEvaluatesSuccessfully() { + this.gradleBuild + .script("src/main/gradle/getting-started/apply-plugin-snapshot.gradle") + .build(); + } + + @Test + public void typicalPluginsAppliesExceptedPlugins() { + this.gradleBuild.script("src/main/gradle/getting-started/typical-plugins.gradle") + .build("verify"); + } + +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/IntegratingWithActuatorDocumentationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/IntegratingWithActuatorDocumentationTests.java new file mode 100644 index 0000000000..8ba0219bc2 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/IntegratingWithActuatorDocumentationTests.java @@ -0,0 +1,90 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.gradle.docs; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Properties; + +import org.junit.Rule; +import org.junit.Test; + +import org.springframework.boot.gradle.testkit.GradleBuild; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for the generating build info documentation. + * + * @author Andy Wilkinson + */ +public class IntegratingWithActuatorDocumentationTests { + + @Rule + public GradleBuild gradleBuild = new GradleBuild(); + + @Test + public void basicBuildInfo() throws IOException { + this.gradleBuild + .script("src/main/gradle/integrating-with-actuator/build-info-basic.gradle") + .build("bootBuildInfo"); + assertThat(new File(this.gradleBuild.getProjectDir(), + "build/resources/main/META-INF/build-info.properties")).isFile(); + } + + @Test + public void buildInfoCustomValues() throws IOException { + this.gradleBuild + .script("src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle") + .build("bootBuildInfo"); + File file = new File(this.gradleBuild.getProjectDir(), + "build/resources/main/META-INF/build-info.properties"); + assertThat(file).isFile(); + Properties properties = buildInfoProperties(file); + assertThat(properties).containsEntry("build.artifact", "example-app"); + assertThat(properties).containsEntry("build.version", "1.2.3"); + assertThat(properties).containsEntry("build.group", "com.example"); + assertThat(properties).containsEntry("build.name", "Example application"); + } + + @Test + public void buildInfoAdditional() throws IOException { + this.gradleBuild + .script("src/main/gradle/integrating-with-actuator/build-info-additional.gradle") + .build("bootBuildInfo"); + File file = new File(this.gradleBuild.getProjectDir(), + "build/resources/main/META-INF/build-info.properties"); + assertThat(file).isFile(); + Properties properties = buildInfoProperties(file); + assertThat(properties).containsEntry("build.a", "alpha"); + assertThat(properties).containsEntry("build.b", "bravo"); + } + + private Properties buildInfoProperties(File file) { + assertThat(file).isFile(); + Properties properties = new Properties(); + try (FileReader reader = new FileReader(file)) { + properties.load(reader); + return properties; + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } + +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java new file mode 100644 index 0000000000..0d69c8a0b6 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.gradle.docs; + +import org.junit.Rule; +import org.junit.Test; + +import org.springframework.boot.gradle.testkit.GradleBuild; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for the managing dependencies documentation. + * + * @author Andy Wilkinson + */ +public class ManagingDependenciesDocumentationTests { + + @Rule + public GradleBuild gradleBuild = new GradleBuild(); + + @Test + public void dependenciesExampleEvaluatesSuccessfully() { + this.gradleBuild + .script("src/main/gradle/managing-dependencies/dependencies.gradle") + .build(); + } + + @Test + public void customManagedVersions() { + assertThat(this.gradleBuild + .script("src/main/gradle/managing-dependencies/custom-version.gradle") + .build("slf4jVersion").getOutput()).contains("1.7.20"); + } + +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java new file mode 100644 index 0000000000..03afebb19c --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java @@ -0,0 +1,176 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.gradle.docs; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.junit.Rule; +import org.junit.Test; + +import org.springframework.boot.gradle.testkit.GradleBuild; +import org.springframework.util.FileCopyUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for the packaging documentation. + * + * @author Andy Wilkinson + */ +public class PackagingDocumentationTests { + + @Rule + public GradleBuild gradleBuild = new GradleBuild(); + + @Test + public void warContainerDependencyEvaluatesSuccessfully() { + this.gradleBuild + .script("src/main/gradle/packaging/war-container-dependency.gradle") + .build(); + } + + @Test + public void bootJarMainClass() throws IOException { + this.gradleBuild.script("src/main/gradle/packaging/boot-jar-main-class.gradle") + .build("bootJar"); + File file = new File(this.gradleBuild.getProjectDir(), + "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); + assertThat(file).isFile(); + try (JarFile jar = new JarFile(file)) { + assertThat(jar.getManifest().getMainAttributes().getValue("Start-Class")) + .isEqualTo("com.example.ExampleApplication"); + } + } + + @Test + public void bootJarManifestMainClass() throws IOException { + this.gradleBuild + .script("src/main/gradle/packaging/boot-jar-manifest-main-class.gradle") + .build("bootJar"); + File file = new File(this.gradleBuild.getProjectDir(), + "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); + assertThat(file).isFile(); + try (JarFile jar = new JarFile(file)) { + assertThat(jar.getManifest().getMainAttributes().getValue("Start-Class")) + .isEqualTo("com.example.ExampleApplication"); + } + } + + @Test + public void applicationPluginMainClass() throws IOException { + this.gradleBuild + .script("src/main/gradle/packaging/application-plugin-main-class.gradle") + .build("bootJar"); + File file = new File(this.gradleBuild.getProjectDir(), + "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); + assertThat(file).isFile(); + try (JarFile jar = new JarFile(file)) { + assertThat(jar.getManifest().getMainAttributes().getValue("Start-Class")) + .isEqualTo("com.example.ExampleApplication"); + } + } + + @Test + public void bootWarIncludeDevtools() throws IOException { + new File(this.gradleBuild.getProjectDir(), + "spring-boot-devtools-1.2.3.RELEASE.jar").createNewFile(); + this.gradleBuild + .script("src/main/gradle/packaging/boot-war-include-devtools.gradle") + .build("bootWar"); + File file = new File(this.gradleBuild.getProjectDir(), + "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".war"); + assertThat(file).isFile(); + try (JarFile jar = new JarFile(file)) { + assertThat(jar.getEntry("WEB-INF/lib/spring-boot-devtools-1.2.3.RELEASE.jar")) + .isNotNull(); + } + } + + @Test + public void bootJarRequiresUnpack() throws IOException { + this.gradleBuild + .script("src/main/gradle/packaging/boot-jar-requires-unpack.gradle") + .build("bootJar"); + File file = new File(this.gradleBuild.getProjectDir(), + "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); + assertThat(file).isFile(); + try (JarFile jar = new JarFile(file)) { + JarEntry entry = jar.getJarEntry("BOOT-INF/lib/jruby-complete-1.7.25.jar"); + assertThat(entry).isNotNull(); + assertThat(entry.getComment()).startsWith("UNPACK:"); + } + } + + @Test + public void bootJarIncludeLaunchScript() throws IOException { + this.gradleBuild + .script("src/main/gradle/packaging/boot-jar-include-launch-script.gradle") + .build("bootJar"); + File file = new File(this.gradleBuild.getProjectDir(), + "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); + assertThat(file).isFile(); + assertThat(FileCopyUtils.copyToString(new FileReader(file))) + .startsWith("#!/bin/bash"); + } + + @Test + public void bootJarLaunchScriptProperties() throws IOException { + this.gradleBuild + .script("src/main/gradle/packaging/boot-jar-launch-script-properties.gradle") + .build("bootJar"); + File file = new File(this.gradleBuild.getProjectDir(), + "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); + assertThat(file).isFile(); + assertThat(FileCopyUtils.copyToString(new FileReader(file))) + .contains("example-app.log"); + } + + @Test + public void bootJarCustomLaunchScript() throws IOException { + File customScriptFile = new File(this.gradleBuild.getProjectDir(), + "src/custom.script"); + customScriptFile.getParentFile().mkdirs(); + FileCopyUtils.copy("custom", new FileWriter(customScriptFile)); + this.gradleBuild + .script("src/main/gradle/packaging/boot-jar-custom-launch-script.gradle") + .build("bootJar"); + File file = new File(this.gradleBuild.getProjectDir(), + "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar"); + assertThat(file).isFile(); + assertThat(FileCopyUtils.copyToString(new FileReader(file))).startsWith("custom"); + } + + @Test + public void bootWarPropertiesLauncher() throws IOException { + this.gradleBuild + .script("src/main/gradle/packaging/boot-war-properties-launcher.gradle") + .build("bootWar"); + File file = new File(this.gradleBuild.getProjectDir(), + "build/libs/" + this.gradleBuild.getProjectDir().getName() + ".war"); + assertThat(file).isFile(); + try (JarFile jar = new JarFile(file)) { + assertThat(jar.getManifest().getMainAttributes().getValue("Main-Class")) + .isEqualTo("org.springframework.boot.loader.PropertiesLauncher"); + } + } + +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PublishingDocumentationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PublishingDocumentationTests.java new file mode 100644 index 0000000000..b57a0ab60e --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PublishingDocumentationTests.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.gradle.docs; + +import java.io.IOException; + +import org.junit.Rule; +import org.junit.Test; + +import org.springframework.boot.gradle.testkit.GradleBuild; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for the publishing documentation. + * + * @author Andy Wilkinson + */ +public class PublishingDocumentationTests { + + @Rule + public GradleBuild gradleBuild = new GradleBuild(); + + @Test + public void mavenUpload() throws IOException { + assertThat(this.gradleBuild.script("src/main/gradle/publishing/maven.gradle") + .build("deployerRepository").getOutput()) + .contains("https://repo.example.com"); + } + + @Test + public void mavenPublish() throws IOException { + assertThat( + this.gradleBuild.script("src/main/gradle/publishing/maven-publish.gradle") + .build("publishingConfiguration").getOutput()) + .contains("MavenPublication") + .contains("https://repo.example.com"); + } + +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/RunningDocumentationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/RunningDocumentationTests.java new file mode 100644 index 0000000000..742ed2b9f1 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/RunningDocumentationTests.java @@ -0,0 +1,60 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.gradle.docs; + +import java.io.IOException; + +import org.junit.Rule; +import org.junit.Test; + +import org.springframework.boot.gradle.testkit.GradleBuild; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for the integrating with Actuator documentation. + * + * @author Andy Wilkinson + */ +public class RunningDocumentationTests { + + @Rule + public GradleBuild gradleBuild = new GradleBuild(); + + @Test + public void bootRunMain() throws IOException { + assertThat(this.gradleBuild.script("src/main/gradle/running/boot-run-main.gradle") + .build("configuredMainClass").getOutput()) + .contains("com.example.ExampleApplication"); + } + + @Test + public void applicationPluginMainClassName() throws IOException { + assertThat(this.gradleBuild + .script("src/main/gradle/running/application-plugin-main-class-name.gradle") + .build("configuredMainClass").getOutput()) + .contains("com.example.ExampleApplication"); + } + + @Test + public void bootRunSourceResources() throws IOException { + assertThat(this.gradleBuild + .script("src/main/gradle/running/boot-run-source-resources.gradle") + .build("configuredClasspath").getOutput()).contains("src/main/resources"); + } + +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java index cc8b8cb389..6dfde693bc 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java @@ -18,10 +18,9 @@ package org.springframework.boot.gradle.testkit; import java.io.File; import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import java.net.URL; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -41,6 +40,7 @@ import org.xml.sax.InputSource; import org.springframework.asm.ClassVisitor; import org.springframework.boot.loader.tools.LaunchScript; +import org.springframework.util.FileCopyUtils; /** * A {@link TestRule} for running a Gradle build using {@link GradleRunner}. @@ -143,9 +143,10 @@ public class GradleBuild implements TestRule { } public GradleRunner prepareRunner(String... arguments) throws IOException { - Files.copy(new File(this.script).toPath(), - new File(this.projectDir, "build.gradle").toPath(), - StandardCopyOption.REPLACE_EXISTING); + String scriptContent = FileCopyUtils.copyToString(new FileReader(this.script)) + .replace("{version}", getBootVersion()); + FileCopyUtils.copy(scriptContent, + new FileWriter(new File(this.projectDir, "build.gradle"))); GradleRunner gradleRunner = GradleRunner.create().withProjectDir(this.projectDir) .forwardOutput(); List allArguments = new ArrayList();