Port the build to Gradle

Closes gh-19609
Closes gh-19608
This commit is contained in:
Andy Wilkinson
2020-01-10 13:48:43 +00:00
parent abe95fa8a7
commit ce99db1902
974 changed files with 17108 additions and 26596 deletions

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-build</artifactId>
<version>${revision}</version>
</parent>
<artifactId>spring-boot-project</artifactId>
<packaging>pom</packaging>
<name>Spring Boot Project</name>
<description>Spring Boot Project</description>
<properties>
<main.basedir>${basedir}/..</main.basedir>
</properties>
<modules>
<module>spring-boot-dependencies</module>
<module>spring-boot-parent</module>
<module>spring-boot</module>
<module>spring-boot-actuator</module>
<module>spring-boot-actuator-autoconfigure</module>
<module>spring-boot-autoconfigure</module>
<module>spring-boot-devtools</module>
<module>spring-boot-properties-migrator</module>
<module>spring-boot-test</module>
<module>spring-boot-test-autoconfigure</module>
<module>spring-boot-tools</module>
<module>spring-boot-starters</module>
<module>spring-boot-cli</module>
<module>spring-boot-docs</module>
</modules>
</project>

View File

@@ -0,0 +1,185 @@
plugins {
id 'java-library'
id 'org.asciidoctor.jvm.convert'
id 'org.asciidoctor.jvm.pdf'
id 'org.springframework.boot.auto-configuration'
id 'org.springframework.boot.conventions'
id 'org.springframework.boot.deployed'
id 'org.springframework.boot.optional-dependencies'
}
description = 'Spring Boot Actuator AutoConfigure'
configurations {
asciidoctorExtensions
documentation
}
dependencies {
asciidoctorExtensions enforcedPlatform(project(':spring-boot-project:spring-boot-dependencies'))
asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor'
api project(':spring-boot-project:spring-boot-actuator')
implementation enforcedPlatform(project(':spring-boot-project:spring-boot-dependencies'))
implementation project(':spring-boot-project:spring-boot')
implementation project(':spring-boot-project:spring-boot-autoconfigure')
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
implementation 'org.springframework:spring-core'
implementation 'org.springframework:spring-context'
optional enforcedPlatform(project(':spring-boot-project:spring-boot-dependencies'))
optional 'ch.qos.logback:logback-classic'
optional 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml'
optional 'com.github.ben-manes.caffeine:caffeine'
optional 'com.hazelcast:hazelcast'
optional 'com.hazelcast:hazelcast-spring'
optional 'com.sun.mail:jakarta.mail'
optional 'com.zaxxer:HikariCP'
optional 'io.dropwizard.metrics:metrics-jmx'
optional 'io.lettuce:lettuce-core'
optional 'io.micrometer:micrometer-core'
optional 'io.micrometer:micrometer-jersey2'
optional 'io.micrometer:micrometer-registry-appoptics'
optional 'io.micrometer:micrometer-registry-atlas'
optional 'io.micrometer:micrometer-registry-datadog'
optional 'io.micrometer:micrometer-registry-dynatrace'
optional 'io.micrometer:micrometer-registry-elastic'
optional 'io.micrometer:micrometer-registry-ganglia'
optional 'io.micrometer:micrometer-registry-graphite'
optional 'io.micrometer:micrometer-registry-humio'
optional 'io.micrometer:micrometer-registry-influx'
optional 'io.micrometer:micrometer-registry-jmx'
optional 'io.micrometer:micrometer-registry-kairos'
optional 'io.micrometer:micrometer-registry-new-relic'
optional 'io.micrometer:micrometer-registry-prometheus'
optional 'io.micrometer:micrometer-registry-stackdriver'
optional 'io.prometheus:simpleclient_pushgateway'
optional 'io.micrometer:micrometer-registry-signalfx'
optional 'io.micrometer:micrometer-registry-statsd'
optional 'io.micrometer:micrometer-registry-wavefront'
optional 'io.projectreactor.netty:reactor-netty'
optional 'io.searchbox:jest'
optional 'jakarta.jms:jakarta.jms-api'
optional 'jakarta.servlet:jakarta.servlet-api'
optional 'javax.cache:cache-api'
optional 'net.sf.ehcache:ehcache'
optional 'org.apache.activemq:activemq-broker'
optional 'org.apache.commons:commons-dbcp2'
optional 'org.apache.kafka:kafka-clients'
optional 'org.apache.tomcat.embed:tomcat-embed-core'
optional 'org.apache.tomcat.embed:tomcat-embed-el'
optional 'org.apache.tomcat:tomcat-jdbc'
optional 'org.aspectj:aspectjweaver'
optional 'org.eclipse.jetty:jetty-server'
optional 'org.elasticsearch:elasticsearch'
optional 'org.elasticsearch.client:elasticsearch-rest-client'
optional 'org.flywaydb:flyway-core'
optional 'org.glassfish.jersey.core:jersey-server'
optional 'org.glassfish.jersey.containers:jersey-container-servlet-core'
optional 'org.hibernate:hibernate-core'
optional 'org.hibernate.validator:hibernate-validator'
optional 'org.influxdb:influxdb-java'
optional 'org.jolokia:jolokia-core'
optional 'org.infinispan:infinispan-spring4-embedded'
optional 'org.liquibase:liquibase-core'
optional 'org.mongodb:mongodb-driver-async'
optional 'org.mongodb:mongodb-driver-reactivestreams'
optional 'org.springframework:spring-jdbc'
optional 'org.springframework:spring-jms'
optional 'org.springframework:spring-messaging'
optional 'org.springframework:spring-webflux'
optional 'org.springframework:spring-webmvc'
optional 'org.springframework.amqp:spring-rabbit'
optional 'org.springframework.data:spring-data-cassandra'
optional 'org.springframework.data:spring-data-couchbase'
optional 'org.springframework.data:spring-data-ldap'
optional 'org.springframework.data:spring-data-mongodb'
optional 'org.springframework.data:spring-data-neo4j'
optional 'org.springframework.data:spring-data-redis'
optional 'org.springframework.data:spring-data-solr'
optional 'org.springframework.integration:spring-integration-core'
optional 'org.springframework.security:spring-security-config'
optional 'org.springframework.security:spring-security-web'
optional 'org.springframework.session:spring-session-core'
optional 'redis.clients:jedis'
testImplementation project(':spring-boot-project:spring-boot-test')
testImplementation project(':spring-boot-project:spring-boot-tools:spring-boot-test-support')
testImplementation 'io.projectreactor:reactor-test'
testImplementation 'com.squareup.okhttp3:mockwebserver'
testImplementation 'com.jayway.jsonpath:json-path'
testImplementation 'io.undertow:undertow-core'
testImplementation ('io.undertow:undertow-servlet') {
exclude group: 'org.jboss.spec.javax.annotation', module: 'jboss-annotations-api_1.2_spec'
exclude group: 'org.jboss.spec.javax.servlet', module: 'jboss-servlet-api_4.0_spec'
}
testImplementation 'javax.xml.bind:jaxb-api'
testImplementation 'org.apache.logging.log4j:log4j-to-slf4j'
testImplementation 'org.aspectj:aspectjrt'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.eclipse.jetty:jetty-webapp'
testImplementation 'org.glassfish.jersey.ext:jersey-spring4'
testImplementation 'org.glassfish.jersey.media:jersey-media-json-jackson'
testImplementation 'org.hamcrest:hamcrest'
testImplementation 'org.hsqldb:hsqldb'
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.mockito:mockito-core'
testImplementation 'org.skyscreamer:jsonassert'
testImplementation 'org.springframework:spring-orm'
testImplementation 'org.springframework.data:spring-data-elasticsearch'
testImplementation 'org.springframework.data:spring-data-rest-webmvc'
testImplementation 'org.springframework.integration:spring-integration-jmx'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
testImplementation 'org.springframework.restdocs:spring-restdocs-webtestclient'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.yaml:snakeyaml'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testRuntimeOnly 'org.springframework.security:spring-security-oauth2-jose'
testRuntimeOnly 'org.springframework.security:spring-security-oauth2-resource-server'
}
compileJava {
options.compilerArgs << '-parameters'
}
compileTestJava {
options.compilerArgs << '-parameters'
}
test {
outputs.dir("$buildDir/generated-snippets")
}
asciidoctor {
configurations 'asciidoctorExtensions'
dependsOn test
sources {
include 'index.adoc'
}
}
asciidoctorPdf {
configurations 'asciidoctorExtensions'
dependsOn test
sources {
include 'index.adoc'
}
}
task zip(type: Zip) {
dependsOn asciidoctor, asciidoctorPdf
duplicatesStrategy 'fail'
from(asciidoctorPdf.outputDir) {
into 'pdf'
}
from(asciidoctor.outputDir) {
into 'html'
}
}
artifacts {
documentation zip
}

View File

@@ -1,863 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>${revision}</version>
<relativePath>../spring-boot-parent</relativePath>
</parent>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<name>Spring Boot Actuator AutoConfigure</name>
<description>Spring Boot Actuator AutoConfigure</description>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
<refdocs.build.directory>${project.build.directory}/refdocs/</refdocs.build.directory>
</properties>
<scm>
<url>${git.url}</url>
<connection>${git.connection}</connection>
<developerConnection>${git.developerConnection}</developerConnection>
</scm>
<dependencies>
<!-- Compile -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<!-- Optional -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-spring</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-jmx</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-jersey2</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-appoptics</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-atlas</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-datadog</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-dynatrace</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-elastic</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-ganglia</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-graphite</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-humio</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-influx</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-jmx</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-kairos</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-new-relic</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_pushgateway</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-signalfx</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-stackdriver</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-statsd</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-wavefront</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>jakarta.jms</groupId>
<artifactId>jakarta.jms-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<artifactId>geronimo-jms_1.1_spec</artifactId>
<groupId>org.apache.geronimo.specs</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-spring5-embedded</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-async</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-reactivestreams</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-cassandra</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-couchbase</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-ldap</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-solr</artifactId>
<optional>true</optional>
<exclusions>
<!-- the version of solr here is incompatible with jackson-xml because
of an old woodstox -->
<exclusion>
<artifactId>wstx-asl</artifactId>
<groupId>org.codehaus.woodstox</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
<optional>true</optional>
</dependency>
<!-- Runtime -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Annotation processing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test-support</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-servlet</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.1_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jmx</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-webtestclient</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-resource-server</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<profiles>
<profile>
<id>full</id>
<activation>
<property>
<name>full</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<executions>
<execution>
<id>unpack-doc-resources</id>
<phase>generate-resources</phase>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>${spring-doc-resources.url}</url>
<unpack>true</unpack>
<outputDirectory>${refdocs.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b3</version>
<exclusions>
<exclusion>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.8.1</version>
</dependency>
<dependency>
<groupId>org.tigris.antelope</groupId>
<artifactId>antelopetasks</artifactId>
<version>3.2.10</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>set-up-maven-properties</id>
<phase>prepare-package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<exportAntProperties>true</exportAntProperties>
<target>
<taskdef
resource="net/sf/antcontrib/antcontrib.properties" />
<taskdef name="stringutil"
classname="ise.antelope.tasks.StringUtilTask" />
<var name="version-type" value="${project.version}" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp=".*\.(.*)"
replace="\1" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp="(M)\d+"
replace="MILESTONE" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp="(RC)\d+"
replace="MILESTONE" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp="BUILD-(.*)"
replace="SNAPSHOT" />
<var name="github-tag" value="v${project.version}" />
<propertyregex property="github-tag"
override="true" input="${github-tag}" regexp=".*SNAPSHOT"
replace="master" />
</target>
</configuration>
</execution>
<execution>
<id>package-docs-zip</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<zip
destfile="${project.build.directory}/${project.artifactId}-${project.version}-docs.zip">
<zipfileset
dir="${project.build.directory}/generated-docs/reference/html"
prefix="html" />
<mappedresources>
<fileset
dir="${project.build.directory}/generated-docs/reference/pdf"
includes="index.pdf" />
<globmapper from="index.pdf"
to="pdf/spring-boot-actuator-web-api.pdf" />
</mappedresources>
</zip>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-html-documentation</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html5</backend>
<outputDirectory>${project.build.directory}/generated-docs/reference/html</outputDirectory>
<sourceHighlighter>highlight.js</sourceHighlighter>
<doctype>book</doctype>
<attributes>
<highlightjsdir>js/highlight</highlightjsdir>
<highlightjs-theme>github</highlightjs-theme>
<linkcss>true</linkcss>
<imagesdir>./images</imagesdir>
<icons>font</icons>
<stylesdir>css/</stylesdir>
<stylesheet>spring.css</stylesheet>
<attribute-missing>warn</attribute-missing>
</attributes>
<logHandler>
<outputToConsole>true</outputToConsole>
<failIf>
<severity>DEBUG</severity>
</failIf>
</logHandler>
</configuration>
</execution>
<execution>
<id>generate-pdf-documentation</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>pdf</backend>
<outputDirectory>${project.build.directory}/generated-docs/reference/pdf</outputDirectory>
</configuration>
</execution>
</executions>
<configuration>
<sourceDirectory>${refdocs.build.directory}</sourceDirectory>
<sourceDocumentName>index.adoc</sourceDocumentName>
<attributes>
<version-type>${version-type}</version-type>
<version>${project.version}</version>
<snippets>${project.build.directory}/generated-snippets/</snippets>
</attributes>
</configuration>
<dependencies>
<dependency>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctorj-pdf</artifactId>
<version>1.5.0-alpha.18</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-asciidoc-resources</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${refdocs.build.directory}</outputDirectory>
<resources>
<resource>
<directory>src/main/asciidoc</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-zip</id>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.artifactId}-${project.version}-docs.zip</file>
<type>zip</type>
<classifier>docs</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -10,12 +10,12 @@ The `auditevents` endpoint provides information about the application's audit ev
To retrieve the audit events, make a `GET` request to `/actuator/auditevents`, as shown in the following curl-based example:
include::{snippets}auditevents/filtered/curl-request.adoc[]
include::{snippets}/auditevents/filtered/curl-request.adoc[]
The preceding example retrieves `logout` events for the principal, `alice`, that occurred after 09:37 on 7 November 2017 in the UTC timezone.
The resulting response is similar to the following:
include::{snippets}auditevents/filtered/http-response.adoc[]
include::{snippets}/auditevents/filtered/http-response.adoc[]
@@ -26,7 +26,7 @@ The endpoint uses query parameters to limit the events that it returns.
The following table shows the supported query parameters:
[cols="2,4"]
include::{snippets}auditevents/filtered/request-parameters.adoc[]
include::{snippets}/auditevents/filtered/request-parameters.adoc[]
@@ -37,4 +37,4 @@ The response contains details of all of the audit events that matched the query.
The following table describes the structure of the response:
[cols="2,1,3"]
include::{snippets}auditevents/all/response-fields.adoc[]
include::{snippets}/auditevents/all/response-fields.adoc[]

View File

@@ -10,11 +10,11 @@ The `beans` endpoint provides information about the application's beans.
To retrieve the beans, make a `GET` request to `/actuator/beans`, as shown in the following curl-based example:
include::{snippets}beans/curl-request.adoc[]
include::{snippets}/beans/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}beans/http-response.adoc[]
include::{snippets}/beans/http-response.adoc[]
@@ -25,4 +25,4 @@ The response contains details of the application's beans.
The following table describes the structure of the response:
[cols="2,1,3"]
include::{snippets}beans/response-fields.adoc[]
include::{snippets}/beans/response-fields.adoc[]

View File

@@ -9,11 +9,11 @@ The `caches` endpoint provides access to the application's caches.
== Retrieving All Caches
To retrieve the application's caches, make a `GET` request to `/actuator/caches`, as shown in the following curl-based example:
include::{snippets}caches/all/curl-request.adoc[]
include::{snippets}/caches/all/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}caches/all/http-response.adoc[]
include::{snippets}/caches/all/http-response.adoc[]
@@ -23,7 +23,7 @@ The response contains details of the application's caches.
The following table describes the structure of the response:
[cols="3,1,3"]
include::{snippets}caches/all/response-fields.adoc[]
include::{snippets}/caches/all/response-fields.adoc[]
@@ -31,12 +31,12 @@ include::{snippets}caches/all/response-fields.adoc[]
== Retrieving Caches by Name
To retrieve a cache by name, make a `GET` request to `/actuator/caches/\{name}`, as shown in the following curl-based example:
include::{snippets}caches/named/curl-request.adoc[]
include::{snippets}/caches/named/curl-request.adoc[]
The preceding example retrieves information about the cache named `cities`.
The resulting response is similar to the following:
include::{snippets}caches/named/http-response.adoc[]
include::{snippets}/caches/named/http-response.adoc[]
@@ -47,7 +47,7 @@ Otherwise, the `cacheManager` must be specified.
The following table shows the supported query parameters:
[cols="2,4"]
include::{snippets}caches/named/request-parameters.adoc[]
include::{snippets}/caches/named/request-parameters.adoc[]
@@ -57,7 +57,7 @@ The response contains details of the requested cache.
The following table describes the structure of the response:
[cols="3,1,3"]
include::{snippets}caches/named/response-fields.adoc[]
include::{snippets}/caches/named/response-fields.adoc[]
@@ -65,7 +65,7 @@ include::{snippets}caches/named/response-fields.adoc[]
== Evict All Caches
To clear all available caches, make a `DELETE` request to `/actuator/caches` as shown in the following curl-based example:
include::{snippets}caches/evict-all/curl-request.adoc[]
include::{snippets}/caches/evict-all/curl-request.adoc[]
@@ -73,7 +73,7 @@ include::{snippets}caches/evict-all/curl-request.adoc[]
== Evict a Cache by Name
To evict a particular cache, make a `DELETE` request to `/actuator/caches/\{name}` as shown in the following curl-based example:
include::{snippets}caches/evict-named/curl-request.adoc[]
include::{snippets}/caches/evict-named/curl-request.adoc[]
NOTE: As there are two caches named `countries`, the `cacheManager` has to be provided to specify which `Cache` should be cleared.
@@ -86,4 +86,4 @@ Otherwise, the `cacheManager` must be specified.
The following table shows the supported query parameters:
[cols="2,4"]
include::{snippets}caches/evict-named/request-parameters.adoc[]
include::{snippets}/caches/evict-named/request-parameters.adoc[]

View File

@@ -10,11 +10,11 @@ The `conditions` endpoint provides information about the evaluation of condition
To retrieve the report, make a `GET` request to `/actuator/conditions`, as shown in the following curl-based example:
include::{snippets}conditions/curl-request.adoc[]
include::{snippets}/conditions/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}conditions/http-response.adoc[]
include::{snippets}/conditions/http-response.adoc[]
@@ -25,4 +25,4 @@ The response contains details of the application's condition evaluation.
The following table describes the structure of the response:
[cols="3,1,3"]
include::{snippets}conditions/response-fields.adoc[]
include::{snippets}/conditions/response-fields.adoc[]

View File

@@ -10,11 +10,11 @@ The `configprops` endpoint provides information about the application's `@Config
To retrieve the `@ConfigurationProperties` beans, make a `GET` request to `/actuator/configprops`, as shown in the following curl-based example:
include::{snippets}configprops/curl-request.adoc[]
include::{snippets}/configprops/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}configprops/http-response.adoc[]
include::{snippets}/configprops/http-response.adoc[]
@@ -25,4 +25,4 @@ The response contains details of the application's `@ConfigurationProperties` be
The following table describes the structure of the response:
[cols="2,1,3"]
include::{snippets}configprops/response-fields.adoc[]
include::{snippets}/configprops/response-fields.adoc[]

View File

@@ -10,11 +10,11 @@ The `env` endpoint provides information about the application's `Environment`.
To retrieve the entire environment, make a `GET` request to `/actuator/env`, as shown in the following curl-based example:
include::{snippets}env/all/curl-request.adoc[]
include::{snippets}/env/all/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}env/all/http-response.adoc[]
include::{snippets}/env/all/http-response.adoc[]
@@ -25,7 +25,7 @@ The response contains details of the application's `Environment`.
The following table describes the structure of the response:
[cols="3,1,3"]
include::{snippets}env/all/response-fields.adoc[]
include::{snippets}/env/all/response-fields.adoc[]
@@ -34,12 +34,12 @@ include::{snippets}env/all/response-fields.adoc[]
To retrieve a single property, make a `GET` request to `/actuator/env/{property.name}`, as shown in the following curl-based example:
include::{snippets}env/single/curl-request.adoc[]
include::{snippets}/env/single/curl-request.adoc[]
The preceding example retrieves information about the property named `com.example.cache.max-size`.
The resulting response is similar to the following:
include::{snippets}env/single/http-response.adoc[]
include::{snippets}/env/single/http-response.adoc[]
@@ -50,4 +50,4 @@ The response contains details of the requested property.
The following table describes the structure of the response:
[cols="3,1,3"]
include::{snippets}env/single/response-fields.adoc[]
include::{snippets}/env/single/response-fields.adoc[]

View File

@@ -10,11 +10,11 @@ The `flyway` endpoint provides information about database migrations performed b
To retrieve the migrations, make a `GET` request to `/actuator/flyway`, as shown in the following curl-based example:
include::{snippets}flyway/curl-request.adoc[]
include::{snippets}/flyway/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}flyway/http-response.adoc[]
include::{snippets}/flyway/http-response.adoc[]
@@ -25,4 +25,4 @@ The response contains details of the application's Flyway migrations.
The following table describes the structure of the response:
[cols="2,1,3"]
include::{snippets}flyway/response-fields.adoc[]
include::{snippets}/flyway/response-fields.adoc[]

View File

@@ -8,11 +8,11 @@ The `health` endpoint provides detailed information about the health of the appl
== Retrieving the Health of the application
To retrieve the health of the application, make a `GET` request to `/actuator/health`, as shown in the following curl-based example:
include::{snippets}health/curl-request.adoc[]
include::{snippets}/health/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}health/http-response.adoc[]
include::{snippets}/health/http-response.adoc[]
@@ -22,7 +22,7 @@ The response contains details of the health of the application.
The following table describes the structure of the response:
[cols="2,1,3"]
include::{snippets}health/response-fields.adoc[]
include::{snippets}/health/response-fields.adoc[]
NOTE: The response fields above are for the V3 API.
If you need to return V2 JSON you should use an accept header or `application/vnd.spring-boot.actuator.v2+json`
@@ -33,11 +33,11 @@ If you need to return V2 JSON you should use an accept header or `application/vn
== Retrieving the Health of a component
To retrieve the health of a particular component of the application's health, make a `GET` request to `/actuator/health/\{component}`, as shown in the following curl-based example:
include::{snippets}health/component/curl-request.adoc[]
include::{snippets}/health/component/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}health/component/http-response.adoc[]
include::{snippets}/health/component/http-response.adoc[]
@@ -47,7 +47,7 @@ The response contains details of the health of a particular component of the app
The following table describes the structure of the response:
[cols="2,1,3"]
include::{snippets}health/component/response-fields.adoc[]
include::{snippets}/health/component/response-fields.adoc[]
@@ -55,11 +55,11 @@ include::{snippets}health/component/response-fields.adoc[]
== Retrieving the Health of a nested component
If a particular component contains other nested components (as the `broker` indicator in the example above), the health of such a nested component can be retrieved by issuing a `GET` request to `/actuator/health/\{component}/\{subcomponent}`, as shown in the following curl-based example:
include::{snippets}health/instance/curl-request.adoc[]
include::{snippets}/health/instance/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}health/instance/http-response.adoc[]
include::{snippets}/health/instance/http-response.adoc[]
Components of an application's health may be nested arbitrarily deep depending on the application's health indicators and how they have been grouped.
The health endpoint supports any number of `/\{component}` identifiers in the URL to allow the health of a component at any depth to be retrieved.
@@ -72,4 +72,4 @@ The response contains details of the health of an instance of a particular compo
The following table describes the structure of the response:
[cols="2,1,3"]
include::{snippets}health/instance/response-fields.adoc[]
include::{snippets}/health/instance/response-fields.adoc[]

View File

@@ -13,6 +13,6 @@ The response is binary data in https://docs.oracle.com/javase/8/docs/technotes/s
Typically, you should save the response to disk for subsequent analysis.
When using curl, this can be achieved by using the `-O` option, as shown in the following example:
include::{snippets}heapdump/curl-request.adoc[]
include::{snippets}/heapdump/curl-request.adoc[]
The preceding example results in a file named `heapdump` being written to the current working directory.

View File

@@ -10,11 +10,11 @@ The `httptrace` endpoint provides information about HTTP request-response exchan
To retrieve the traces, make a `GET` request to `/actuator/httptrace`, as shown in the following curl-based example:
include::{snippets}httptrace/curl-request.adoc[]
include::{snippets}/httptrace/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}httptrace/http-response.adoc[]
include::{snippets}/httptrace/http-response.adoc[]
@@ -25,4 +25,4 @@ The response contains details of the traced HTTP request-response exchanges.
The following table describes the structure of the response:
[cols="2,1,3"]
include::{snippets}httptrace/response-fields.adoc[]
include::{snippets}/httptrace/response-fields.adoc[]

View File

@@ -10,11 +10,11 @@ The `info` endpoint provides general information about the application.
To retrieve the information about the application, make a `GET` request to `/actuator/info`, as shown in the following curl-based example:
include::{snippets}info/curl-request.adoc[]
include::{snippets}/info/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}info/http-response.adoc[]
include::{snippets}/info/http-response.adoc[]
@@ -33,7 +33,7 @@ Spring Boot provides `build` and `git` contributions.
The following table describe the structure of the `build` section of the response:
[cols="2,1,3"]
include::{snippets}info/response-fields-beneath-build.adoc[]
include::{snippets}/info/response-fields-beneath-build.adoc[]
@@ -43,4 +43,4 @@ include::{snippets}info/response-fields-beneath-build.adoc[]
The following table describes the structure of the `git` section of the response:
[cols="2,1,3"]
include::{snippets}info/response-fields-beneath-git.adoc[]
include::{snippets}/info/response-fields-beneath-git.adoc[]

View File

@@ -9,11 +9,11 @@ The `integrationgraph` endpoint exposes a graph containing all Spring Integratio
== Retrieving the Spring Integration graph
To retrieve the information about the application, make a `GET` request to `/actuator/integrationgraph`, as shown in the following curl-based example:
include::{snippets}integrationgraph/graph/curl-request.adoc[]
include::{snippets}/integrationgraph/graph/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}integrationgraph/graph/http-response.adoc[]
include::{snippets}/integrationgraph/graph/http-response.adoc[]
@@ -28,8 +28,8 @@ More information about the structure can be found in the https://docs.spring.io/
== Rebuilding the Spring Integration graph
To rebuild the exposed graph, make a `POST` request to `/actuator/integrationgraph`, as shown in the following curl-based example:
include::{snippets}integrationgraph/rebuild/curl-request.adoc[]
include::{snippets}/integrationgraph/rebuild/curl-request.adoc[]
This will result in a `204 - No Content` response:
include::{snippets}integrationgraph/rebuild/http-response.adoc[]
include::{snippets}/integrationgraph/rebuild/http-response.adoc[]

View File

@@ -10,11 +10,11 @@ The `liquibase` endpoint provides information about database change sets applied
To retrieve the changes, make a `GET` request to `/actuator/liquibase`, as shown in the following curl-based example:
include::{snippets}liquibase/curl-request.adoc[]
include::{snippets}/liquibase/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}liquibase/http-response.adoc[]
include::{snippets}/liquibase/http-response.adoc[]
@@ -25,4 +25,4 @@ The response contains details of the application's Liquibase change sets.
The following table describes the structure of the response:
[cols="2,1,3"]
include::{snippets}liquibase/response-fields.adoc[]
include::{snippets}/liquibase/response-fields.adoc[]

View File

@@ -10,11 +10,11 @@ The `logfile` endpoint provides access to the contents of the application's log
To retrieve the log file, make a `GET` request to `/actuator/logfile`, as shown in the following curl-based example:
include::{snippets}logfile/entire/curl-request.adoc[]
include::{snippets}/logfile/entire/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}logfile/entire/http-response.adoc[]
include::{snippets}/logfile/entire/http-response.adoc[]
@@ -25,9 +25,9 @@ NOTE: Retrieving part of the log file is not supported when using Jersey.
To retrieve part of the log file, make a `GET` request to `/actuator/logfile` by using the `Range` header, as shown in the following curl-based example:
include::{snippets}logfile/range/curl-request.adoc[]
include::{snippets}/logfile/range/curl-request.adoc[]
The preceding example retrieves the first 1024 bytes of the log file.
The resulting response is similar to the following:
include::{snippets}logfile/range/http-response.adoc[]
include::{snippets}/logfile/range/http-response.adoc[]

View File

@@ -10,11 +10,11 @@ The `loggers` endpoint provides access to the application's loggers and the conf
To retrieve the application's loggers, make a `GET` request to `/actuator/loggers`, as shown in the following curl-based example:
include::{snippets}loggers/all/curl-request.adoc[]
include::{snippets}/loggers/all/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}loggers/all/http-response.adoc[]
include::{snippets}/loggers/all/http-response.adoc[]
@@ -25,7 +25,7 @@ The response contains details of the application's loggers.
The following table describes the structure of the response:
[cols="3,1,3"]
include::{snippets}loggers/all/response-fields.adoc[]
include::{snippets}/loggers/all/response-fields.adoc[]
@@ -34,12 +34,12 @@ include::{snippets}loggers/all/response-fields.adoc[]
To retrieve a single logger, make a `GET` request to `/actuator/loggers/{logger.name}`, as shown in the following curl-based example:
include::{snippets}loggers/single/curl-request.adoc[]
include::{snippets}/loggers/single/curl-request.adoc[]
The preceding example retrieves information about the logger named `com.example`.
The resulting response is similar to the following:
include::{snippets}loggers/single/http-response.adoc[]
include::{snippets}/loggers/single/http-response.adoc[]
@@ -50,7 +50,7 @@ The response contains details of the requested logger.
The following table describes the structure of the response:
[cols="3,1,3"]
include::{snippets}loggers/single/response-fields.adoc[]
include::{snippets}/loggers/single/response-fields.adoc[]
@@ -60,12 +60,12 @@ include::{snippets}loggers/single/response-fields.adoc[]
To retrieve a single group, make a `GET` request to `/actuator/loggers/{group.name}`,
as shown in the following curl-based example:
include::{snippets}loggers/group/curl-request.adoc[]
include::{snippets}/loggers/group/curl-request.adoc[]
The preceding example retrieves information about the logger group named `test`.
The resulting response is similar to the following:
include::{snippets}loggers/group/http-response.adoc[]
include::{snippets}/loggers/group/http-response.adoc[]
@@ -76,7 +76,7 @@ The response contains details of the requested group.
The following table describes the structure of the response:
[cols="3,1,3"]
include::{snippets}loggers/group/response-fields.adoc[]
include::{snippets}/loggers/group/response-fields.adoc[]
@@ -85,7 +85,7 @@ include::{snippets}loggers/group/response-fields.adoc[]
To set the level of a logger, make a `POST` request to `/actuator/loggers/{logger.name}` with a JSON body that specifies the configured level for the logger, as shown in the following curl-based example:
include::{snippets}loggers/set/curl-request.adoc[]
include::{snippets}/loggers/set/curl-request.adoc[]
The preceding example sets the `configuredLevel` of the `com.example` logger to `DEBUG`.
@@ -98,7 +98,7 @@ The request specifies the desired level of the logger.
The following table describes the structure of the request:
[cols="3,1,3"]
include::{snippets}loggers/set/request-fields.adoc[]
include::{snippets}/loggers/set/request-fields.adoc[]
@@ -107,7 +107,7 @@ include::{snippets}loggers/set/request-fields.adoc[]
To set the level of a logger, make a `POST` request to `/actuator/loggers/{group.name}` with a JSON body that specifies the configured level for the logger group, as shown in the following curl-based example:
include::{snippets}loggers/setGroup/curl-request.adoc[]
include::{snippets}/loggers/setGroup/curl-request.adoc[]
The preceding example sets the `configuredLevel` of the `test` logger group to `DEBUG`.
@@ -120,7 +120,7 @@ The request specifies the desired level of the logger group.
The following table describes the structure of the request:
[cols="3,1,3"]
include::{snippets}loggers/set/request-fields.adoc[]
include::{snippets}/loggers/set/request-fields.adoc[]
@@ -129,6 +129,6 @@ include::{snippets}loggers/set/request-fields.adoc[]
To clear the level of a logger, make a `POST` request to `/actuator/loggers/{logger.name}` with a JSON body containing an empty object, as shown in the following curl-based example:
include::{snippets}loggers/clear/curl-request.adoc[]
include::{snippets}/loggers/clear/curl-request.adoc[]
The preceding example clears the configured level of the `com.example` logger.

View File

@@ -10,11 +10,11 @@ The `mappings` endpoint provides information about the application's request map
To retrieve the mappings, make a `GET` request to `/actuator/mappings`, as shown in the following curl-based example:
include::{snippets}mappings/curl-request.adoc[]
include::{snippets}/mappings/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}mappings/http-response.adoc[]
include::{snippets}/mappings/http-response.adoc[]
@@ -26,7 +26,7 @@ The items found in the response depend on the type of web application (reactive
The following table describes the structure of the common elements of the response:
[cols="2,1,3"]
include::{snippets}mappings/response-fields.adoc[]
include::{snippets}/mappings/response-fields.adoc[]
The entries that may be found in `contexts.*.mappings` are described in the following sections.
@@ -38,7 +38,7 @@ When using Spring MVC, the response contains details of any `DispatcherServlet`
The following table describes the structure of this section of the response:
[cols="4,1,2"]
include::{snippets}mappings/response-fields-dispatcher-servlets.adoc[]
include::{snippets}/mappings/response-fields-dispatcher-servlets.adoc[]
@@ -49,7 +49,7 @@ When using the Servlet stack, the response contains details of any `Servlet` map
The following table describes the structure of this section of the response:
[cols="2,1,3"]
include::{snippets}mappings/response-fields-servlets.adoc[]
include::{snippets}/mappings/response-fields-servlets.adoc[]
@@ -60,7 +60,7 @@ When using the Servlet stack, the response contains details of any `Filter` mapp
The following table describes the structure of this section of the response:
[cols="2,1,3"]
include::{snippets}mappings/response-fields-servlet-filters.adoc[]
include::{snippets}/mappings/response-fields-servlet-filters.adoc[]
@@ -71,4 +71,4 @@ When using Spring WebFlux, the response contains details of any `DispatcherHandl
The following table describes the structure of this section of the response:
[cols="4,1,2"]
include::{snippets}mappings/response-fields-dispatcher-handlers.adoc[]
include::{snippets}/mappings/response-fields-dispatcher-handlers.adoc[]

View File

@@ -10,11 +10,11 @@ The `metrics` endpoint provides access to application metrics.
To retrieve the names of the available metrics, make a `GET` request to `/actuator/metrics`, as shown in the following curl-based example:
include::{snippets}metrics/names/curl-request.adoc[]
include::{snippets}/metrics/names/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}metrics/names/http-response.adoc[]
include::{snippets}/metrics/names/http-response.adoc[]
@@ -25,7 +25,7 @@ The response contains details of the metric names.
The following table describes the structure of the response:
[cols="3,1,2"]
include::{snippets}metrics/names/response-fields.adoc[]
include::{snippets}/metrics/names/response-fields.adoc[]
@@ -34,12 +34,12 @@ include::{snippets}metrics/names/response-fields.adoc[]
To retrieve a metric, make a `GET` request to `/actuator/metrics/{metric.name}`, as shown in the following curl-based example:
include::{snippets}metrics/metric/curl-request.adoc[]
include::{snippets}/metrics/metric/curl-request.adoc[]
The preceding example retrieves information about the metric named `jvm.memory.max`.
The resulting response is similar to the following:
include::{snippets}metrics/metric/http-response.adoc[]
include::{snippets}/metrics/metric/http-response.adoc[]
@@ -50,7 +50,7 @@ The endpoint uses query parameters to <<metrics-drilling-down,drill down>> into
The following table shows the single supported query parameter:
[cols="2,4"]
include::{snippets}metrics/metric-with-tags/request-parameters.adoc[]
include::{snippets}/metrics/metric-with-tags/request-parameters.adoc[]
@@ -60,7 +60,7 @@ include::{snippets}metrics/metric-with-tags/request-parameters.adoc[]
The response contains details of the metric.
The following table describes the structure of the response:
include::{snippets}metrics/metric/response-fields.adoc[]
include::{snippets}/metrics/metric/response-fields.adoc[]
[[metrics-drilling-down]]
@@ -68,9 +68,9 @@ include::{snippets}metrics/metric/response-fields.adoc[]
To drill down into a metric, make a `GET` request to `/actuator/metrics/{metric.name}` using the `tag` query parameter, as shown in the following curl-based example:
include::{snippets}metrics/metric-with-tags/curl-request.adoc[]
include::{snippets}/metrics/metric-with-tags/curl-request.adoc[]
The preceding example retrieves the `jvm.memory.max` metric, where the `area` tag has a value of `nonheap` and the `id` attribute has a value of `Compressed Class Space`.
The resulting response is similar to the following:
include::{snippets}metrics/metric-with-tags/http-response.adoc[]
include::{snippets}/metrics/metric-with-tags/http-response.adoc[]

View File

@@ -10,8 +10,8 @@ The `prometheus` endpoint provides Spring Boot application's metrics in the form
To retrieve the metrics, make a `GET` request to `/actuator/prometheus`, as shown in the following curl-based example:
include::{snippets}prometheus/curl-request.adoc[]
include::{snippets}/prometheus/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}prometheus/http-response.adoc[]
include::{snippets}/prometheus/http-response.adoc[]

View File

@@ -10,11 +10,11 @@ The `scheduledtasks` endpoint provides information about the application's sched
To retrieve the scheduled tasks, make a `GET` request to `/actuator/scheduledtasks`, as shown in the following curl-based example:
include::{snippets}scheduled-tasks/curl-request.adoc[]
include::{snippets}/scheduled-tasks/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}scheduled-tasks/http-response.adoc[]
include::{snippets}/scheduled-tasks/http-response.adoc[]
@@ -25,4 +25,4 @@ The response contains details of the application's scheduled tasks.
The following table describes the structure of the response:
[cols="2,1,3"]
include::{snippets}scheduled-tasks/response-fields.adoc[]
include::{snippets}/scheduled-tasks/response-fields.adoc[]

View File

@@ -10,12 +10,12 @@ The `sessions` endpoint provides information about the application's HTTP sessio
To retrieve the sessions, make a `GET` request to `/actuator/sessions`, as shown in the following curl-based example:
include::{snippets}sessions/username/curl-request.adoc[]
include::{snippets}/sessions/username/curl-request.adoc[]
The preceding examples retrieves all of the sessions for the user whose username is `alice`.
The resulting response is similar to the following:
include::{snippets}sessions/username/http-response.adoc[]
include::{snippets}/sessions/username/http-response.adoc[]
@@ -26,7 +26,7 @@ The endpoint uses query parameters to limit the sessions that it returns.
The following table shows the single required query parameter:
[cols="2,4"]
include::{snippets}sessions/username/request-parameters.adoc[]
include::{snippets}/sessions/username/request-parameters.adoc[]
@@ -37,7 +37,7 @@ The response contains details of the matching sessions.
The following table describes the structure of the response:
[cols="3,1,3"]
include::{snippets}sessions/username/response-fields.adoc[]
include::{snippets}/sessions/username/response-fields.adoc[]
@@ -46,12 +46,12 @@ include::{snippets}sessions/username/response-fields.adoc[]
To retrieve a single session, make a `GET` request to `/actuator/sessions/\{id}`, as shown in the following curl-based example:
include::{snippets}sessions/id/curl-request.adoc[]
include::{snippets}/sessions/id/curl-request.adoc[]
The preceding example retrieves the session with the `id` of `4db5efcc-99cb-4d05-a52c-b49acfbb7ea9`.
The resulting response is similar to the following:
include::{snippets}sessions/id/http-response.adoc[]
include::{snippets}/sessions/id/http-response.adoc[]
@@ -62,7 +62,7 @@ The response contains details of the requested session.
The following table describes the structure of the response:
[cols="3,1,3"]
include::{snippets}sessions/id/response-fields.adoc[]
include::{snippets}/sessions/id/response-fields.adoc[]
@@ -71,6 +71,6 @@ include::{snippets}sessions/id/response-fields.adoc[]
To delete a session, make a `DELETE` request to `/actuator/sessions/\{id}`, as shown in the following curl-based example:
include::{snippets}sessions/delete/curl-request.adoc[]
include::{snippets}/sessions/delete/curl-request.adoc[]
The preceding example deletes the session with the `id` of `4db5efcc-99cb-4d05-a52c-b49acfbb7ea9`.

View File

@@ -10,11 +10,11 @@ The `shutdown` endpoint is used to shut down the application.
To shut down the application, make a `POST` request to `/actuator/shutdown`, as shown in the following curl-based example:
include::{snippets}shutdown/curl-request.adoc[]
include::{snippets}/shutdown/curl-request.adoc[]
A response similar to the following is produced:
include::{snippets}shutdown/http-response.adoc[]
include::{snippets}/shutdown/http-response.adoc[]
@@ -25,4 +25,4 @@ The response contains details of the result of the shutdown request.
The following table describes the structure of the response:
[cols="3,1,3"]
include::{snippets}shutdown/response-fields.adoc[]
include::{snippets}/shutdown/response-fields.adoc[]

View File

@@ -10,11 +10,11 @@ The `threaddump` endpoint provides a thread dump from the application's JVM.
To retrieve the thread dump as JSON, make a `GET` request to `/actuator/threaddump` with an appropriate `Accept` header, as shown in the following curl-based example:
include::{snippets}threaddump/json/curl-request.adoc[]
include::{snippets}/threaddump/json/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}threaddump/json/http-response.adoc[]
include::{snippets}/threaddump/json/http-response.adoc[]
@@ -25,7 +25,7 @@ The response contains details of the JVM's threads.
The following table describes the structure of the response:
[cols="3,1,2"]
include::{snippets}threaddump/json/response-fields.adoc[]
include::{snippets}/threaddump/json/response-fields.adoc[]
@@ -35,8 +35,8 @@ include::{snippets}threaddump/json/response-fields.adoc[]
To retrieve the thread dump as text, make a `GET` request to `/actuator/threaddump` that
accepts `text/plain`, as shown in the following curl-based example:
include::{snippets}threaddump/text/curl-request.adoc[]
include::{snippets}/threaddump/text/curl-request.adoc[]
The resulting response is similar to the following:
include::{snippets}threaddump/text/http-response.adoc[]
include::{snippets}/threaddump/text/http-response.adoc[]

View File

@@ -0,0 +1,96 @@
plugins {
id 'java-library'
id 'org.springframework.boot.conventions'
id 'org.springframework.boot.configuration-properties'
id 'org.springframework.boot.optional-dependencies'
id 'org.springframework.boot.deployed'
}
description = 'Spring Boot Actuator'
dependencies {
implementation enforcedPlatform(project(':spring-boot-project:spring-boot-dependencies'))
implementation project(':spring-boot-project:spring-boot')
optional enforcedPlatform(project(':spring-boot-project:spring-boot-dependencies'))
optional 'com.fasterxml.jackson.core:jackson-databind'
optional 'com.hazelcast:hazelcast'
optional 'com.hazelcast:hazelcast-spring'
optional 'com.sun.mail:jakarta.mail'
optional 'com.zaxxer:HikariCP'
optional 'io.lettuce:lettuce-core'
optional 'io.micrometer:micrometer-core'
optional 'io.micrometer:micrometer-registry-prometheus'
optional 'io.prometheus:simpleclient_pushgateway'
optional 'io.reactivex:rxjava-reactive-streams'
optional 'io.searchbox:jest'
optional 'org.elasticsearch.client:elasticsearch-rest-client'
optional ('io.undertow:undertow-servlet') {
exclude group: 'org.jboss.spec.javax.annotation', module: 'jboss-annotations-api_1.2_spec'
exclude group: 'org.jboss.spec.javax.servlet', module: 'jboss-servlet-api_4.0_spec'
}
optional 'javax.cache:cache-api'
optional 'javax.jms:javax.jms-api'
optional 'net.sf.ehcache:ehcache'
optional 'org.apache.tomcat.embed:tomcat-embed-core'
optional 'org.aspectj:aspectjweaver'
optional 'org.eclipse.jetty:jetty-server'
optional 'org.elasticsearch:elasticsearch'
optional 'org.flywaydb:flyway-core'
optional 'org.glassfish.jersey.core:jersey-server'
optional 'org.glassfish.jersey.containers:jersey-container-servlet-core'
optional 'org.hibernate.validator:hibernate-validator'
optional 'org.infinispan:infinispan-spring4-embedded'
optional 'org.influxdb:influxdb-java'
optional 'org.liquibase:liquibase-core'
optional 'org.mongodb:mongodb-driver-async'
optional 'org.mongodb:mongodb-driver-reactivestreams'
optional 'org.springframework:spring-jdbc'
optional 'org.springframework:spring-messaging'
optional 'org.springframework:spring-webflux'
optional 'org.springframework:spring-web'
optional 'org.springframework:spring-webmvc'
optional 'org.springframework.amqp:spring-rabbit'
optional 'org.springframework.data:spring-data-cassandra'
optional 'org.springframework.data:spring-data-couchbase'
optional 'org.springframework.data:spring-data-ldap'
optional 'org.springframework.data:spring-data-mongodb'
optional 'org.springframework.data:spring-data-neo4j'
optional 'org.springframework.data:spring-data-redis'
optional 'org.springframework.data:spring-data-rest-webmvc'
optional 'org.springframework.data:spring-data-solr'
optional 'org.springframework.integration:spring-integration-core'
optional 'org.springframework.security:spring-security-core'
optional 'org.springframework.security:spring-security-web'
optional 'org.springframework.session:spring-session-core'
testImplementation project(':spring-boot-project:spring-boot-test')
testImplementation project(':spring-boot-project:spring-boot-tools:spring-boot-test-support')
testImplementation project(':spring-boot-project:spring-boot-autoconfigure')
testImplementation 'org.assertj:assertj-core'
testImplementation 'com.jayway.jsonpath:json-path'
testImplementation 'io.projectreactor:reactor-test'
testImplementation 'org.apache.logging.log4j:log4j-to-slf4j'
testImplementation 'org.awaitility:awaitility'
testImplementation 'org.glassfish.jersey.media:jersey-media-json-jackson'
testImplementation 'org.hamcrest:hamcrest'
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.mockito:mockito-core'
testImplementation 'org.mockito:mockito-junit-jupiter'
testImplementation 'org.skyscreamer:jsonassert'
testImplementation 'org.springframework:spring-test'
testRuntimeOnly 'io.projectreactor.netty:reactor-netty'
testRuntimeOnly 'javax.xml.bind:jaxb-api'
testRuntimeOnly 'org.apache.tomcat.embed:tomcat-embed-el'
testRuntimeOnly 'org.glassfish.jersey.ext:jersey-spring4'
testRuntimeOnly 'org.hsqldb:hsqldb'
}
compileJava {
options.compilerArgs << '-parameters'
}
compileTestJava {
options.compilerArgs << '-parameters'
}

View File

@@ -1,401 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>${revision}</version>
<relativePath>../spring-boot-parent</relativePath>
</parent>
<artifactId>spring-boot-actuator</artifactId>
<name>Spring Boot Actuator</name>
<description>Spring Boot Actuator</description>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<scm>
<url>${git.url}</url>
<connection>${git.connection}</connection>
<developerConnection>${git.developerConnection}</developerConnection>
</scm>
<dependencies>
<!-- Compile -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<!-- Optional -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-spring</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_pushgateway</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava-reactive-streams</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-servlet</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.1_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>jakarta.jms</groupId>
<artifactId>jakarta.jms-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-spring5-embedded</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-async</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-reactivestreams</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-cassandra</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-couchbase</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-ldap</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-solr</artifactId>
<optional>true</optional>
<exclusions>
<!-- the version of solr here is incompatible with jackson-xml because
of an old woodstox -->
<exclusion>
<artifactId>wstx-asl</artifactId>
<groupId>org.codehaus.woodstox</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
<optional>true</optional>
</dependency>
<!-- Annotation processing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test-support</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring5</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -66,6 +66,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.util.ClassUtils;
@@ -192,7 +193,13 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory(
"http://localhost:" + determinePort());
uriBuilderFactory.setEncodingMode(EncodingMode.NONE);
return WebTestClient.bindToServer().uriBuilderFactory(uriBuilderFactory).responseTimeout(TIMEOUT).build();
return WebTestClient.bindToServer().uriBuilderFactory(uriBuilderFactory).responseTimeout(TIMEOUT)
.filter((request, next) -> {
if (HttpMethod.GET == request.method()) {
return next.exchange(request).retry(10);
}
return next.exchange(request);
}).build();
}
private int determinePort() {

View File

@@ -0,0 +1,185 @@
plugins {
id 'java-library'
id 'org.jetbrains.kotlin.jvm'
id 'org.springframework.boot.auto-configuration'
id 'org.springframework.boot.conventions'
id 'org.springframework.boot.deployed'
id 'org.springframework.boot.optional-dependencies'
}
description = 'Spring Boot AutoConfigure'
dependencies {
api project(':spring-boot-project:spring-boot')
implementation enforcedPlatform(project(':spring-boot-project:spring-boot-dependencies'))
optional enforcedPlatform(project(':spring-boot-project:spring-boot-dependencies'))
optional 'com.atomikos:transactions-jdbc'
optional 'com.atomikos:transactions-jta'
optional 'com.couchbase.client:couchbase-spring-cache'
optional 'com.fasterxml.jackson.core:jackson-databind'
optional 'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor'
optional 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml'
optional 'com.fasterxml.jackson.datatype:jackson-datatype-joda'
optional 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
optional 'com.fasterxml.jackson.module:jackson-module-parameter-names'
optional 'com.google.code.gson:gson'
optional 'com.hazelcast:hazelcast'
optional 'com.hazelcast:hazelcast-client'
optional 'com.hazelcast:hazelcast-spring'
optional 'com.h2database:h2'
optional 'com.samskivert:jmustache'
optional 'com.sun.mail:jakarta.mail'
optional 'de.flapdoodle.embed:de.flapdoodle.embed.mongo'
optional 'io.lettuce:lettuce-core'
optional 'io.projectreactor.netty:reactor-netty'
optional 'io.searchbox:jest'
optional 'io.rsocket:rsocket-core'
optional 'io.rsocket:rsocket-transport-netty'
optional ('io.undertow:undertow-servlet') {
exclude group: 'org.jboss.spec.javax.annotation', module: 'jboss-annotations-api_1.2_spec'
exclude group: 'org.jboss.spec.javax.servlet', module: 'jboss-servlet-api_4.0_spec'
}
optional ('io.undertow:undertow-websockets-jsr') {
exclude group: 'org.jboss.spec.javax.annotation', module: 'jboss-annotations-api_1.2_spec'
exclude group: 'org.jboss.spec.javax.servlet', module: 'jboss-servlet-api_4.0_spec'
}
optional 'jakarta.jms:jakarta.jms-api'
optional 'jakarta.mail:jakarta.mail-api'
optional 'jakarta.json.bind:jakarta.json.bind-api'
optional 'jakarta.persistence:jakarta.persistence-api'
optional 'jakarta.validation:jakarta.validation-api'
optional 'jakarta.ws.rs:jakarta.ws.rs-api'
optional 'javax.cache:cache-api'
optional 'javax.money:money-api'
optional 'net.sf.ehcache:ehcache'
optional 'org.apache.activemq:activemq-broker'
optional 'org.apache.activemq:artemis-jms-client'
optional 'org.apache.activemq:artemis-jms-server'
optional 'org.apache.commons:commons-dbcp2'
optional 'org.apache.kafka:kafka-streams'
optional 'org.apache.solr:solr-solrj'
optional 'org.apache.tomcat.embed:tomcat-embed-core'
optional 'org.apache.tomcat.embed:tomcat-embed-el'
optional 'org.apache.tomcat.embed:tomcat-embed-websocket'
optional 'org.apache.tomcat:tomcat-jdbc'
optional 'org.codehaus.btm:btm'
optional 'org.codehaus.groovy:groovy-templates'
optional 'com.github.ben-manes.caffeine:caffeine'
optional 'com.github.mxab.thymeleaf.extras:thymeleaf-extras-data-attribute'
optional 'com.sendgrid:sendgrid-java'
optional 'com.unboundid:unboundid-ldapsdk'
optional 'com.zaxxer:HikariCP'
optional 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
optional 'org.aspectj:aspectjweaver'
optional 'org.eclipse.jetty:jetty-webapp'
optional 'org.eclipse.jetty:jetty-reactive-httpclient'
optional 'org.eclipse.jetty.websocket:javax-websocket-server-impl'
optional 'org.ehcache:ehcache'
optional 'org.elasticsearch.client:elasticsearch-rest-client'
optional 'org.elasticsearch.client:elasticsearch-rest-high-level-client'
optional 'org.flywaydb:flyway-core'
optional 'org.freemarker:freemarker'
optional 'org.glassfish.jersey.core:jersey-server'
optional 'org.glassfish.jersey.containers:jersey-container-servlet-core'
optional 'org.glassfish.jersey.containers:jersey-container-servlet'
optional 'org.glassfish.jersey.ext:jersey-spring5'
optional 'org.glassfish.jersey.media:jersey-media-json-jackson'
optional 'org.hibernate:hibernate-core'
optional 'org.hibernate:hibernate-jcache'
optional 'org.hibernate.validator:hibernate-validator'
optional 'org.infinispan:infinispan-jcache'
optional 'org.infinispan:infinispan-spring5-embedded'
optional 'org.influxdb:influxdb-java'
optional 'org.jboss:jboss-transaction-spi'
optional 'org.jooq:jooq'
optional 'org.liquibase:liquibase-core'
optional 'org.messaginghub:pooled-jms'
optional 'org.mongodb:mongodb-driver-async'
optional 'org.mongodb:mongodb-driver-reactivestreams'
optional 'org.quartz-scheduler:quartz'
optional 'org.springframework:spring-jdbc'
optional 'org.springframework.integration:spring-integration-core'
optional 'org.springframework.integration:spring-integration-jdbc'
optional 'org.springframework.integration:spring-integration-jmx'
optional 'org.springframework:spring-jms'
optional 'org.springframework:spring-orm'
optional 'org.springframework:spring-tx'
optional 'org.springframework:spring-web'
optional 'org.springframework:spring-websocket'
optional 'org.springframework:spring-webflux'
optional 'org.springframework:spring-webmvc'
optional 'org.springframework.batch:spring-batch-core'
optional 'org.springframework.data:spring-data-couchbase'
optional 'org.springframework.data:spring-data-jpa'
optional 'org.springframework.data:spring-data-rest-webmvc'
optional 'org.springframework.data:spring-data-cassandra'
optional 'org.springframework.data:spring-data-elasticsearch'
optional 'org.springframework.data:spring-data-jdbc'
optional 'org.springframework.data:spring-data-ldap'
optional 'org.springframework.data:spring-data-mongodb'
optional 'org.springframework.data:spring-data-neo4j'
optional 'org.springframework.data:spring-data-redis'
optional 'org.springframework.data:spring-data-solr'
optional 'org.springframework.hateoas:spring-hateoas'
optional 'org.springframework.security:spring-security-acl'
optional 'org.springframework.security:spring-security-config'
optional 'org.springframework.security:spring-security-data'
optional 'org.springframework.security:spring-security-oauth2-client'
optional 'org.springframework.security:spring-security-oauth2-jose'
optional 'org.springframework.security:spring-security-oauth2-resource-server'
optional 'org.springframework.security:spring-security-rsocket'
optional 'org.springframework.security:spring-security-saml2-service-provider'
optional 'org.springframework.security:spring-security-web'
optional 'org.springframework.session:spring-session-core'
optional 'org.springframework.session:spring-session-data-mongodb'
optional 'org.springframework.session:spring-session-data-redis'
optional 'org.springframework.session:spring-session-hazelcast'
optional 'org.springframework.session:spring-session-jdbc'
optional 'org.springframework.amqp:spring-rabbit'
optional 'org.springframework.kafka:spring-kafka'
optional 'org.springframework.cloud:spring-cloud-spring-service-connector'
optional 'org.springframework.ws:spring-ws-core'
optional 'org.thymeleaf:thymeleaf'
optional 'org.thymeleaf:thymeleaf-spring5'
optional 'org.thymeleaf.extras:thymeleaf-extras-java8time'
optional 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
optional 'redis.clients:jedis'
testImplementation enforcedPlatform(project(':spring-boot-project:spring-boot-parent'))
testImplementation project(':spring-boot-project:spring-boot-tools:spring-boot-test-support')
testImplementation project(':spring-boot-project:spring-boot-test')
testImplementation 'ch.qos.logback:logback-classic'
testImplementation 'commons-fileupload:commons-fileupload'
testImplementation 'com.atomikos:transactions-jms'
testImplementation 'com.jayway.jsonpath:json-path'
testImplementation 'com.squareup.okhttp3:mockwebserver'
testImplementation 'com.sun.xml.messaging.saaj:saaj-impl'
testImplementation 'jakarta.json:jakarta.json-api'
testImplementation 'jakarta.xml.ws:jakarta.xml.ws-api'
testImplementation 'mysql:mysql-connector-java'
testImplementation 'org.apache.johnzon:johnzon-jsonb'
testImplementation 'org.apache.logging.log4j:log4j-to-slf4j'
testImplementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.awaitility:awaitility'
testImplementation 'org.hsqldb:hsqldb'
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.neo4j:neo4j-ogm-bolt-native-types'
testImplementation 'org.neo4j:neo4j-ogm-http-driver'
testImplementation 'org.neo4j:neo4j-ogm-embedded-driver'
testImplementation 'org.springframework:spring-test'
testImplementation 'org.springframework.kafka:spring-kafka-test'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.testcontainers:cassandra'
testImplementation 'org.testcontainers:couchbase'
testImplementation 'org.testcontainers:elasticsearch'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:testcontainers'
testImplementation 'org.yaml:snakeyaml'
testRuntimeOnly 'org.jetbrains.kotlin:kotlin-reflect'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

File diff suppressed because it is too large Load Diff

View File

@@ -74,10 +74,11 @@ public class ReactiveRestClientAutoConfigurationTests {
@Test
void restClientCanQueryElasticsearchNode() {
this.contextRunner
.withPropertyValues("spring.data.elasticsearch.client.reactive.endpoints="
+ elasticsearch.getContainerIpAddress() + ":" + elasticsearch.getFirstMappedPort())
.run((context) -> {
this.contextRunner.withPropertyValues(
"spring.data.elasticsearch.client.reactive.endpoints=" + elasticsearch.getContainerIpAddress() + ":"
+ elasticsearch.getFirstMappedPort(),
"spring.data.elasticsearch.client.reactive.connection-timeout=120s",
"spring.data.elasticsearch.client.reactive.socket-timeout=120s").run((context) -> {
ReactiveElasticsearchClient client = context.getBean(ReactiveElasticsearchClient.class);
Map<String, String> source = new HashMap<>();
source.put("a", "alpha");

View File

@@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.transaction;
import java.util.UUID;
import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
@@ -81,7 +83,7 @@ class TransactionAutoConfigurationTests {
DataSourceTransactionManagerAutoConfiguration.class))
.withUserConfiguration(SinglePlatformTransactionManagerConfiguration.class,
SingleReactiveTransactionManagerConfiguration.class)
.run((context) -> {
.withPropertyValues("spring.datasource.url:jdbc:h2:mem:" + UUID.randomUUID()).run((context) -> {
PlatformTransactionManager platformTransactionManager = context
.getBean(PlatformTransactionManager.class);
TransactionTemplate transactionTemplate = context.getBean(TransactionTemplate.class);

View File

@@ -0,0 +1,195 @@
plugins {
id 'java'
id 'org.springframework.boot.deployed'
id 'org.springframework.boot.conventions'
id 'org.springframework.boot.integration-test'
}
description = "Spring Boot CLI"
configurations {
dependenciesBom
loader
testRepository
}
dependencies {
compileOnly project(':spring-boot-project:spring-boot')
compileOnly 'jakarta.servlet:jakarta.servlet-api'
compileOnly 'org.codehaus.groovy:groovy-templates'
compileOnly 'org.springframework:spring-web'
dependenciesBom project(path: ':spring-boot-project:spring-boot-dependencies', configuration: 'effectiveBom')
implementation enforcedPlatform(project(':spring-boot-project:spring-boot-parent'))
implementation project(':spring-boot-project:spring-boot-tools:spring-boot-loader-tools')
implementation 'com.vaadin.external.google:android-json'
implementation 'jline:jline'
implementation 'net.sf.jopt-simple:jopt-simple'
implementation('org.apache.httpcomponents:httpclient') {
exclude group: 'commons-logging', module: 'commons-logging'
}
implementation 'org.apache.maven:maven-model'
implementation('org.apache.maven:maven-resolver-provider') {
exclude group: 'com.google.guava', module: 'guava'
}
implementation 'org.apache.maven.resolver:maven-resolver-connector-basic'
implementation 'org.apache.maven.resolver:maven-resolver-transport-file'
implementation('org.apache.maven.resolver:maven-resolver-transport-http') {
exclude group: 'org.slf4j', module: 'jcl-over-slf4j'
}
implementation 'org.apache.maven:maven-settings-builder'
implementation 'org.codehaus.groovy:groovy'
implementation 'org.slf4j:slf4j-simple'
implementation 'org.sonatype.plexus:plexus-sec-dispatcher'
implementation('org.sonatype.sisu:sisu-inject-plexus') {
exclude group: 'javax.enterprise', module: 'cdi-api'
exclude group: 'org.sonatype.sisu', module: 'sisu-inject-bean'
}
implementation 'org.springframework:spring-core'
implementation 'org.springframework.security:spring-security-crypto'
intTestImplementation enforcedPlatform(project(':spring-boot-project:spring-boot-dependencies'))
intTestImplementation project(':spring-boot-project:spring-boot-tools:spring-boot-loader-tools')
intTestImplementation project(':spring-boot-project:spring-boot-tools:spring-boot-test-support')
intTestImplementation 'org.assertj:assertj-core'
intTestImplementation 'org.junit.jupiter:junit-jupiter'
intTestImplementation 'org.springframework:spring-core'
loader project(':spring-boot-project:spring-boot-tools:spring-boot-loader')
testImplementation project(':spring-boot-project:spring-boot')
testImplementation project(':spring-boot-project:spring-boot-tools:spring-boot-test-support')
testImplementation project(':spring-boot-project:spring-boot-test')
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.codehaus.groovy:groovy-templates'
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.mockito:mockito-core'
testImplementation 'org.springframework:spring-test'
testRepository project(path: ':spring-boot-project:spring-boot-starters:spring-boot-starter-actuator', configuration: 'mavenRepository')
testRepository project(path: ':spring-boot-project:spring-boot-starters:spring-boot-starter-amqp', configuration: 'mavenRepository')
testRepository project(path: ':spring-boot-project:spring-boot-starters:spring-boot-starter-aop', configuration: 'mavenRepository')
testRepository project(path: ':spring-boot-project:spring-boot-starters:spring-boot-starter-artemis', configuration: 'mavenRepository')
testRepository project(path: ':spring-boot-project:spring-boot-starters:spring-boot-starter-batch', configuration: 'mavenRepository')
testRepository project(path: ':spring-boot-project:spring-boot-starters:spring-boot-starter-data-jpa', configuration: 'mavenRepository')
testRepository project(path: ':spring-boot-project:spring-boot-starters:spring-boot-starter-jdbc', configuration: 'mavenRepository')
testRepository project(path: ':spring-boot-project:spring-boot-starters:spring-boot-starter-integration', configuration: 'mavenRepository')
testRepository project(path: ':spring-boot-project:spring-boot-starters:spring-boot-starter-security', configuration: 'mavenRepository')
testRepository project(path: ':spring-boot-project:spring-boot-starters:spring-boot-starter-web', configuration: 'mavenRepository')
}
task syncSpringBootDependenciesBom(type: Sync) {
destinationDir = file("$buildDir/generated-resources/org/springframework/boot/cli/compiler/dependencies")
from configurations.dependenciesBom
}
task syncTestRepository(type: Sync) {
destinationDir = file("${buildDir}/test-repository")
from configurations.testRepository
}
sourceSets {
main {
output.dir("$buildDir/generated-resources", builtBy: 'syncSpringBootDependenciesBom')
}
}
test {
dependsOn syncTestRepository
useJUnitPlatform()
}
task fullJar(type: Jar) {
classifier = 'full'
entryCompression = 'stored'
from(configurations.runtimeClasspath) {
into 'BOOT-INF/lib'
}
from(sourceSets.main.output) {
into 'BOOT-INF/classes'
}
into("") {
from zipTree(configurations.loader.singleFile)
}
manifest {
attributes(
'Class-Loader': 'groovy.lang.GroovyClassLoader',
'Main-Class': 'org.springframework.boot.loader.JarLauncher',
'Start-Class': 'org.springframework.boot.cli.SpringCli'
)
}
}
def configureArchive(archive) {
archive.classifier = 'bin'
archive.into "spring-${project.version}"
archive.from(fullJar) {
rename {
it.replace("-full", "")
}
into 'lib/'
}
archive.from(file('src/main/content')) {
eachFile { it.mode = it.directory ? 0x755 : 0x644 }
}
archive.from(file('src/main/executablecontent')) {
eachFile { it.mode = 0x755 }
}
}
task zip(type: Zip) {
classifier = 'bin'
configureArchive it
}
intTest {
dependsOn syncTestRepository, zip
}
task tar(type: Tar) {
compression = 'gzip'
archiveExtension = 'tar.gz'
configureArchive it
}
task scoopManifest(type: org.springframework.boot.build.cli.ScoopManifest) {
dependsOn zip
outputDir = file("$buildDir/scoop")
template = file('src/main/scoop/springboot.json')
archive = zip.archiveFile
}
def scoopManifestArtifact = artifacts.add('archives', file("$buildDir/scoop/springboot.json")) {
type 'json'
classifier 'scoop'
builtBy 'scoopManifest'
}
task homebrewFormula(type: org.springframework.boot.build.cli.HomebrewFormula) {
dependsOn tar
outputDir = file("$buildDir/homebrew")
template = file('src/main/homebrew/springboot.rb')
archive = tar.archiveFile
}
def homebrewFormulaArtifact = artifacts.add('archives', file("$buildDir/homebrew/springboot.rb")) {
type 'rb'
classifier 'homebrew'
builtBy 'homebrewFormula'
}
publishing {
publications {
getByName('maven') {
artifact fullJar
artifact tar
artifact zip
artifact scoopManifestArtifact
artifact homebrewFormulaArtifact
}
}
}

View File

@@ -1,469 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>${revision}</version>
<relativePath>../spring-boot-parent</relativePath>
</parent>
<artifactId>spring-boot-cli</artifactId>
<name>Spring Boot CLI</name>
<description>Spring Boot CLI</description>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
<start-class>org.springframework.boot.cli.SpringCli</start-class>
<spring.profiles.active>default</spring.profiles.active>
<generated.pom.dir>${project.build.directory}/generated-resources/org/springframework/boot/cli/compiler/dependencies</generated.pom.dir>
</properties>
<scm>
<url>${git.url}</url>
<connection>${git.connection}</connection>
<developerConnection>${git.developerConnection}</developerConnection>
</scm>
<dependencies>
<!-- Compile -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader-tools</artifactId>
</dependency>
<dependency>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
</dependency>
<dependency>
<groupId>jline</groupId>
<artifactId>jline</artifactId>
</dependency>
<dependency>
<groupId>net.sf.jopt-simple</groupId>
<artifactId>jopt-simple</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
</dependency>
<dependency>
<groupId>org.sonatype.plexus</groupId>
<artifactId>plexus-sec-dispatcher</artifactId>
</dependency>
<dependency>
<groupId>org.sonatype.sisu</groupId>
<artifactId>sisu-inject-plexus</artifactId>
<exclusions>
<exclusion>
<groupId>org.sonatype.sisu</groupId>
<artifactId>sisu-inject-bean</artifactId>
</exclusion>
<exclusion>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-settings-builder</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-resolver-provider</artifactId>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-connector-basic</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-impl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-transport-file</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-transport-http</artifactId>
<exclusions>
<exclusion>
<artifactId>jcl-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- Provided -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<type>effective-pom</type>
<scope>provided</scope>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-templates</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test-support</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>${project.build.directory}/generated-resources</directory>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>${project.build.directory}/generated-resources</additionalClasspathElement>
</additionalClasspathElements>
<systemPropertyVariables>
<spring.profiles.active>${spring.profiles.active}</spring.profiles.active>
</systemPropertyVariables>
</configuration>
</plugin>
<!-- Build an executable JAR manually since we can't easily depend on
a maven plugin that is part of the reactor -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-effective-pom</id>
<phase>generate-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<type>effective-pom</type>
<overWrite>true</overWrite>
<outputDirectory>${generated.pom.dir}</outputDirectory>
<destFileName>effective-pom.xml</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
<execution>
<id>unpack</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
<version>${project.version}</version>
<type>jar</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/assembly</outputDirectory>
</configuration>
</execution>
<execution>
<id>copy</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/assembly/BOOT-INF/lib</outputDirectory>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/jar-with-dependencies.xml</descriptor>
</descriptors>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<mainClass>org.springframework.boot.loader.JarLauncher</mainClass>
</manifest>
<manifestEntries>
<Start-Class>${start-class}</Start-Class>
<Class-Loader>groovy.lang.GroovyClassLoader</Class-Loader>
</manifestEntries>
</archive>
</configuration>
</execution>
<execution>
<id>bin-package</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/bin-package.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b3</version>
<exclusions>
<exclusion>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.8.1</version>
</dependency>
<dependency>
<groupId>org.tigris.antelope</groupId>
<artifactId>antelopetasks</artifactId>
<version>3.2.10</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>homebrew</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<inherited>false</inherited>
<configuration>
<target>
<taskdef
resource="net/sf/antcontrib/antcontrib.properties" />
<taskdef name="stringutil"
classname="ise.antelope.tasks.StringUtilTask" />
<var name="version-type" value="${project.version}" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp=".*\.(.*)"
replace="\1" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp="(M)\d+"
replace="MILESTONE" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp="(RC)\d+"
replace="MILESTONE" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp="BUILD-(.*)"
replace="SNAPSHOT" />
<stringutil string="${version-type}" property="repo">
<lowercase />
</stringutil>
<checksum algorithm="sha-256"
file="${project.build.directory}/spring-boot-cli-${project.version}-bin.tar.gz"
property="checksum" />
<echo
message="Customizing homebrew for ${project.version} with checksum ${checksum} in ${repo} repo" />
<copy file="${basedir}/src/main/homebrew/springboot.rb"
tofile="${project.build.directory}/homebrew/springboot.rb"
overwrite="true">
<filterchain>
<expandproperties />
</filterchain>
</copy>
<attachartifact
file="${project.build.directory}/homebrew/springboot.rb"
classifier="homebrew" type="rb" />
</target>
</configuration>
</execution>
<execution>
<id>scoop</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<inherited>false</inherited>
<configuration>
<target>
<taskdef
resource="net/sf/antcontrib/antcontrib.properties" />
<taskdef name="stringutil"
classname="ise.antelope.tasks.StringUtilTask" />
<var name="scoop-version" value="${project.version}" />
<propertyregex property="scoop-version"
override="true" input="${scoop-version}" regexp="(.*)\..*"
replace="\1" />
<var name="version-type" value="${project.version}" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp=".*\.(.*)"
replace="\1" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp="(M)\d+"
replace="MILESTONE" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp="(RC)\d+"
replace="MILESTONE" />
<propertyregex property="version-type"
override="true" input="${version-type}" regexp="BUILD-(.*)"
replace="SNAPSHOT" />
<stringutil string="${version-type}" property="repo">
<lowercase />
</stringutil>
<checksum algorithm="sha-256"
file="${project.build.directory}/spring-boot-cli-${project.version}-bin.zip"
property="hash" />
<echo
message="Customizing scoop for ${project.version} with hash ${hash} in ${repo} repo" />
<copy file="${basedir}/src/main/scoop/springboot.json"
tofile="${project.build.directory}/scoop/springboot.json"
overwrite="true">
<filterchain>
<expandproperties>
<propertyset>
<propertyref name="scoop-version" />
<propertyref name="hash" />
<propertyref name="repo" />
<propertyref name="project.version" />
</propertyset>
</expandproperties>
</filterchain>
</copy>
<attachartifact
file="${project.build.directory}/scoop/springboot.json"
classifier="scoop" type="json" />
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-test-source</id>
<phase>process-resources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/it/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>integration</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profiles.active>integration</spring.profiles.active>
</properties>
</profile>
<profile>
<id>java9+</id>
<activation>
<jdk>[9,)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View File

@@ -43,39 +43,40 @@ class CommandLineIT {
this.cli = new CommandLineInvoker(tempDir);
}
@Test void hintProducesListOfValidCommands()
throws IOException, InterruptedException {
@Test
void hintProducesListOfValidCommands() throws IOException, InterruptedException {
Invocation cli = this.cli.invoke("hint");
assertThat(cli.await()).isEqualTo(0);
assertThat(cli.getErrorOutput()).isEmpty();
assertThat(cli.getStandardOutputLines()).hasSize(11);
}
@Test void invokingWithNoArgumentsDisplaysHelp()
throws IOException, InterruptedException {
@Test
void invokingWithNoArgumentsDisplaysHelp() throws IOException, InterruptedException {
Invocation cli = this.cli.invoke();
assertThat(cli.await()).isEqualTo(1);
assertThat(cli.getErrorOutput()).isEmpty();
assertThat(cli.getStandardOutput()).startsWith("usage:");
}
@Test void unrecognizedCommandsAreHandledGracefully()
throws IOException, InterruptedException {
@Test
void unrecognizedCommandsAreHandledGracefully() throws IOException, InterruptedException {
Invocation cli = this.cli.invoke("not-a-real-command");
assertThat(cli.await()).isEqualTo(1);
assertThat(cli.getErrorOutput())
.contains("'not-a-real-command' is not a valid command");
assertThat(cli.getErrorOutput()).contains("'not-a-real-command' is not a valid command");
assertThat(cli.getStandardOutput()).isEmpty();
}
@Test void version() throws IOException, InterruptedException {
@Test
void version() throws IOException, InterruptedException {
Invocation cli = this.cli.invoke("version");
assertThat(cli.await()).isEqualTo(0);
assertThat(cli.getErrorOutput()).isEmpty();
assertThat(cli.getStandardOutput()).startsWith("Spring CLI v");
}
@Test void help() throws IOException, InterruptedException {
@Test
void help() throws IOException, InterruptedException {
Invocation cli = this.cli.invoke("help");
assertThat(cli.await()).isEqualTo(1);
assertThat(cli.getErrorOutput()).isEmpty();

View File

@@ -37,8 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class JarCommandIT {
private static final boolean JAVA_9_OR_LATER = isClassPresent(
"java.security.cert.URICertStoreParameters");
private static final boolean JAVA_9_OR_LATER = isClassPresent("java.security.cert.URICertStoreParameters");
private CommandLineInvoker cli;
@@ -46,31 +45,32 @@ class JarCommandIT {
@BeforeEach
void setup(@TempDir File tempDir) {
this.cli = new CommandLineInvoker(new File("src/it/resources/jar-command"),
tempDir);
this.cli = new CommandLineInvoker(new File("src/intTest/resources/jar-command"), tempDir);
this.tempDir = tempDir;
}
@Test void noArguments() throws Exception {
@Test
void noArguments() throws Exception {
Invocation invocation = this.cli.invoke("jar");
invocation.await();
assertThat(invocation.getStandardOutput()).isEqualTo("");
assertThat(invocation.getErrorOutput()).contains("The name of the "
+ "resulting jar and at least one source file must be specified");
assertThat(invocation.getErrorOutput())
.contains("The name of the " + "resulting jar and at least one source file must be specified");
}
@Test void noSources() throws Exception {
@Test
void noSources() throws Exception {
Invocation invocation = this.cli.invoke("jar", "test-app.jar");
invocation.await();
assertThat(invocation.getStandardOutput()).isEqualTo("");
assertThat(invocation.getErrorOutput()).contains("The name of the "
+ "resulting jar and at least one source file must be specified");
assertThat(invocation.getErrorOutput())
.contains("The name of the " + "resulting jar and at least one source file must be specified");
}
@Test void jarCreationWithGrabResolver() throws Exception {
@Test
void jarCreationWithGrabResolver() throws Exception {
File jar = new File(this.tempDir, "test-app.jar");
Invocation invocation = this.cli.invoke("run", jar.getAbsolutePath(),
"bad.groovy");
Invocation invocation = this.cli.invoke("run", jar.getAbsolutePath(), "bad.groovy");
invocation.await();
if (!JAVA_9_OR_LATER) {
assertThat(invocation.getErrorOutput()).isEqualTo("");
@@ -82,8 +82,7 @@ class JarCommandIT {
}
assertThat(jar).exists();
Process process = new JavaExecutable()
.processBuilder("-jar", jar.getAbsolutePath()).start();
Process process = new JavaExecutable().processBuilder("-jar", jar.getAbsolutePath()).start();
invocation = new Invocation(process);
invocation.await();
@@ -92,9 +91,33 @@ class JarCommandIT {
}
}
@Test void jarCreation() throws Exception {
@Test
void jarCreation() throws Exception {
File jar = new File(this.tempDir, "test-app.jar");
Invocation invocation = this.cli.invoke("jar", jar.getAbsolutePath(),
Invocation invocation = this.cli.invoke("jar", jar.getAbsolutePath(), "jar.groovy");
invocation.await();
if (!JAVA_9_OR_LATER) {
assertThat(invocation.getErrorOutput()).isEmpty();
}
assertThat(jar).exists();
Process process = new JavaExecutable().processBuilder("-jar", jar.getAbsolutePath()).start();
invocation = new Invocation(process);
invocation.await();
if (!JAVA_9_OR_LATER) {
assertThat(invocation.getErrorOutput()).isEqualTo("");
}
assertThat(invocation.getStandardOutput()).contains("Hello World!")
.contains("/BOOT-INF/classes!/public/public.txt").contains("/BOOT-INF/classes!/resources/resource.txt")
.contains("/BOOT-INF/classes!/static/static.txt").contains("/BOOT-INF/classes!/templates/template.txt")
.contains("/BOOT-INF/classes!/root.properties").contains("Goodbye Mama");
}
@Test
void jarCreationWithIncludes() throws Exception {
File jar = new File(this.tempDir, "test-app.jar");
Invocation invocation = this.cli.invoke("jar", jar.getAbsolutePath(), "--include", "-public/**,-resources/**",
"jar.groovy");
invocation.await();
if (!JAVA_9_OR_LATER) {
@@ -102,42 +125,14 @@ class JarCommandIT {
}
assertThat(jar).exists();
Process process = new JavaExecutable()
.processBuilder("-jar", jar.getAbsolutePath()).start();
Process process = new JavaExecutable().processBuilder("-jar", jar.getAbsolutePath()).start();
invocation = new Invocation(process);
invocation.await();
if (!JAVA_9_OR_LATER) {
assertThat(invocation.getErrorOutput()).isEqualTo("");
}
assertThat(invocation.getStandardOutput()).contains("Hello World!")
.contains("/BOOT-INF/classes!/public/public.txt")
.contains("/BOOT-INF/classes!/resources/resource.txt")
.contains("/BOOT-INF/classes!/static/static.txt")
.contains("/BOOT-INF/classes!/templates/template.txt")
.contains("/BOOT-INF/classes!/root.properties").contains("Goodbye Mama");
}
@Test void jarCreationWithIncludes() throws Exception {
File jar = new File(this.tempDir, "test-app.jar");
Invocation invocation = this.cli.invoke("jar", jar.getAbsolutePath(), "--include",
"-public/**,-resources/**", "jar.groovy");
invocation.await();
if (!JAVA_9_OR_LATER) {
assertThat(invocation.getErrorOutput()).isEmpty();
}
assertThat(jar).exists();
Process process = new JavaExecutable()
.processBuilder("-jar", jar.getAbsolutePath()).start();
invocation = new Invocation(process);
invocation.await();
if (!JAVA_9_OR_LATER) {
assertThat(invocation.getErrorOutput()).isEqualTo("");
}
assertThat(invocation.getStandardOutput()).contains("Hello World!")
.doesNotContain("/public/public.txt")
assertThat(invocation.getStandardOutput()).contains("Hello World!").doesNotContain("/public/public.txt")
.doesNotContain("/resources/resource.txt").contains("/static/static.txt")
.contains("/templates/template.txt").contains("Goodbye Mama");
}

View File

@@ -43,25 +43,22 @@ class WarCommandIT {
@BeforeEach
void setup(@TempDir File tempDir) {
this.cli = new CommandLineInvoker(new File("src/it/resources/war-command"),
tempDir);
this.cli = new CommandLineInvoker(new File("src/intTest/resources/war-command"), tempDir);
this.tempDir = tempDir;
}
@Test void warCreation() throws Exception {
@Test
void warCreation() throws Exception {
File war = new File(this.tempDir, "test-app.war");
Invocation invocation = this.cli.invoke("war", war.getAbsolutePath(),
"war.groovy");
Invocation invocation = this.cli.invoke("war", war.getAbsolutePath(), "war.groovy");
invocation.await();
assertThat(war.exists()).isTrue();
Process process = new JavaExecutable()
.processBuilder("-jar", war.getAbsolutePath(), "--server.port=0").start();
Process process = new JavaExecutable().processBuilder("-jar", war.getAbsolutePath(), "--server.port=0").start();
invocation = new Invocation(process);
invocation.await();
assertThat(invocation.getOutput()).contains("onStart error");
assertThat(invocation.getOutput()).contains("Tomcat started");
assertThat(invocation.getOutput())
.contains("/WEB-INF/lib-provided/tomcat-embed-core");
assertThat(invocation.getOutput()).contains("/WEB-INF/lib-provided/tomcat-embed-core");
assertThat(invocation.getOutput()).contains("WEB-INF/classes!/root.properties");
process.destroy();
}

View File

@@ -25,6 +25,10 @@ import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -63,19 +67,22 @@ public final class CommandLineInvoker {
}
private Process runCliProcess(String... args) throws IOException {
Path m2 = this.temp.toPath().resolve(".m2");
Files.createDirectories(m2);
Files.copy(Paths.get("src", "intTest", "resources", "settings.xml"), m2.resolve("settings.xml"),
StandardCopyOption.REPLACE_EXISTING);
List<String> command = new ArrayList<>();
command.add(findLaunchScript().getAbsolutePath());
command.addAll(Arrays.asList(args));
ProcessBuilder processBuilder = new ProcessBuilder(command)
.directory(this.workingDirectory);
processBuilder.environment().remove("JAVA_OPTS");
ProcessBuilder processBuilder = new ProcessBuilder(command).directory(this.workingDirectory);
processBuilder.environment().put("JAVA_OPTS", "-Duser.home=" + this.temp);
return processBuilder.start();
}
private File findLaunchScript() throws IOException {
File unpacked = new File(this.temp, "unpacked-cli");
if (!unpacked.isDirectory()) {
File zip = new BuildOutput(getClass()).getRootLocation()
File zip = new File(new BuildOutput(getClass()).getRootLocation(), "distributions")
.listFiles((pathname) -> pathname.getName().endsWith("-bin.zip"))[0];
try (ZipInputStream input = new ZipInputStream(new FileInputStream(zip))) {
ZipEntry entry;
@@ -99,8 +106,7 @@ public final class CommandLineInvoker {
File bin = new File(unpacked.listFiles()[0], "bin");
File launchScript = new File(bin, isWindows() ? "spring.bat" : "spring");
Assert.state(launchScript.exists() && launchScript.isFile(),
() -> "Could not find CLI launch script "
+ launchScript.getAbsolutePath());
() -> "Could not find CLI launch script " + launchScript.getAbsolutePath());
return launchScript;
}
@@ -125,10 +131,10 @@ public final class CommandLineInvoker {
public Invocation(Process process) {
this.process = process;
this.streamReaders.add(new Thread(new StreamReadingRunnable(
this.process.getErrorStream(), this.err, this.combined)));
this.streamReaders.add(new Thread(new StreamReadingRunnable(
this.process.getInputStream(), this.out, this.combined)));
this.streamReaders
.add(new Thread(new StreamReadingRunnable(this.process.getErrorStream(), this.err, this.combined)));
this.streamReaders
.add(new Thread(new StreamReadingRunnable(this.process.getInputStream(), this.out, this.combined)));
for (Thread streamReader : this.streamReaders) {
streamReader.start();
}
@@ -162,10 +168,8 @@ public final class CommandLineInvoker {
}
private List<String> getLines(StringBuffer buffer) {
BufferedReader reader = new BufferedReader(
new StringReader(buffer.toString()));
return reader.lines().filter((line) -> !line.startsWith("Picked up "))
.collect(Collectors.toList());
BufferedReader reader = new BufferedReader(new StringReader(buffer.toString()));
return reader.lines().filter((line) -> !line.startsWith("Picked up ")).collect(Collectors.toList());
}
public int await() throws InterruptedException {

View File

@@ -0,0 +1,23 @@
<settings>
<localRepository>../../../../build/local-m2-repository</localRepository>
<profiles>
<profile>
<id>cli-test-repo</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>local.central</id>
<url>file:../../../../build/test-repository</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
</settings>

View File

@@ -4,7 +4,7 @@ class Springboot < Formula
homepage 'https://spring.io/projects/spring-boot'
url 'https://repo.spring.io/${repo}/org/springframework/boot/spring-boot-cli/${project.version}/spring-boot-cli-${project.version}-bin.tar.gz'
version '${project.version}'
sha256 '${checksum}'
sha256 '${hash}'
head 'https://github.com/spring-projects/spring-boot.git'
if build.head?

View File

@@ -42,8 +42,8 @@ public class SpringBootDependenciesDependencyManagement extends MavenModelDepend
modelProcessor.setModelReader(new DefaultModelReader());
try {
return modelProcessor.read(
SpringBootDependenciesDependencyManagement.class.getResourceAsStream("effective-pom.xml"), null);
return modelProcessor.read(SpringBootDependenciesDependencyManagement.class
.getResourceAsStream("spring-boot-dependencies-effective-bom.xml"), null);
}
catch (IOException ex) {
throw new IllegalStateException("Failed to build model from effective pom", ex);

View File

@@ -17,7 +17,6 @@
package org.springframework.boot.cli.compiler.maven;
import java.io.File;
import java.lang.reflect.Field;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.building.DefaultSettingsBuilderFactory;
@@ -83,21 +82,7 @@ public class MavenSettingsReader {
}
private SettingsDecrypter createSettingsDecrypter() {
SettingsDecrypter settingsDecrypter = new DefaultSettingsDecrypter();
setField(DefaultSettingsDecrypter.class, "securityDispatcher", settingsDecrypter,
new SpringBootSecDispatcher());
return settingsDecrypter;
}
private void setField(Class<?> sourceClass, String fieldName, Object target, Object value) {
try {
Field field = sourceClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(target, value);
}
catch (Exception ex) {
throw new IllegalStateException("Failed to set field '" + fieldName + "' on '" + target + "'", ex);
}
return new DefaultSettingsDecrypter(new SpringBootSecDispatcher());
}
private class SpringBootSecDispatcher extends DefaultSecDispatcher {

View File

@@ -1,11 +1,11 @@
{
"homepage": "https://projects.spring.io/spring-boot/",
"version": "${scoop-version}",
"version": "${scoopVersion}",
"license": "Apache 2.0",
"hash": "${hash}",
"url": "https://repo.spring.io/${repo}/org/springframework/boot/spring-boot-cli/${project.version}/spring-boot-cli-${project.version}-bin.zip",
"extract_dir": "spring-${project.version}",
"bin": "bin\\spring.bat",
"bin": "bin\\\\spring.bat",
"suggest": {
"JDK": [
"java/oraclejdk",
@@ -14,13 +14,13 @@
},
"checkver": {
"github": "https://github.com/spring-projects/spring-boot",
"re": "/releases/tag/(?:v)?(2[\\d.]+)\\.RELEASE"
"re": "/releases/tag/(?:v)?(2[\\d.]+)\\\\.RELEASE"
},
"autoupdate": {
"url": "https://repo.spring.io/release/org/springframework/boot/spring-boot-cli/$version.RELEASE/spring-boot-cli-$version.RELEASE-bin.zip",
"extract_dir": "spring-$version.RELEASE",
"url": "https://repo.spring.io/release/org/springframework/boot/spring-boot-cli/\$version.RELEASE/spring-boot-cli-\$version.RELEASE-bin.zip",
"extract_dir": "spring-\$version.RELEASE",
"hash": {
"url": "$url.sha256"
"url": "\$url.sha256"
}
}
}

View File

@@ -96,12 +96,14 @@ public class CliTester implements BeforeEachCallback, AfterEachCallback {
for (String arg : args) {
if (arg.startsWith("--classpath=")) {
arg = arg + ":" + this.buildOutput.getTestClassesLocation().getAbsolutePath();
arg = arg + ":" + this.buildOutput.getTestResourcesLocation().getAbsolutePath();
classpathUpdated = true;
}
updatedArgs.add(arg);
}
if (!classpathUpdated) {
updatedArgs.add("--classpath=.:" + this.buildOutput.getTestClassesLocation().getAbsolutePath());
updatedArgs.add("--classpath=.:" + this.buildOutput.getTestClassesLocation().getAbsolutePath() + ":"
+ this.buildOutput.getTestResourcesLocation().getAbsolutePath());
}
Future<RunCommand> future = submitCommand(new RunCommand(), StringUtils.toStringArray(updatedArgs));
this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
@@ -134,6 +136,8 @@ public class CliTester implements BeforeEachCallback, AfterEachCallback {
"org.springframework.boot.cli.CliTesterSpringApplication");
this.serverPortFile = new File(this.temp, "server.port");
System.setProperty("portfile", this.serverPortFile.getAbsolutePath());
String userHome = System.getProperty("user.home");
System.setProperty("user.home", "src/test/resources/cli-tester");
try {
command.run(sources);
return command;
@@ -142,6 +146,7 @@ public class CliTester implements BeforeEachCallback, AfterEachCallback {
System.clearProperty("server.port");
System.clearProperty("spring.application.class.name");
System.clearProperty("portfile");
System.setProperty("user.home", userHome);
Thread.currentThread().setContextClassLoader(loader);
}
});

View File

@@ -57,15 +57,12 @@ class GrabCommandIntegrationTests {
@Test
void grab() throws Exception {
System.setProperty("grape.root", this.cli.getTemp().getAbsolutePath());
System.setProperty("groovy.grape.report.downloads", "true");
// Use --autoconfigure=false to limit the amount of downloaded dependencies
String output = this.cli.grab("grab.groovy", "--autoconfigure=false");
assertThat(new File(this.cli.getTemp(), "repository/joda-time/joda-time")).isDirectory();
// Should be resolved from local repository cache
assertThat(output.contains("Downloading: file:")).isTrue();
assertThat(output).contains("Downloading: ");
}
@Test

View File

@@ -42,7 +42,7 @@ class RunCommandIntegrationTests {
CliTester cli;
RunCommandIntegrationTests(CapturedOutput output) {
this.cli = new CliTester("src/it/resources/run-command/", output);
this.cli = new CliTester("src/test/resources/run-command/", output);
}
private Properties systemProperties = new Properties();

View File

@@ -19,7 +19,6 @@ package org.springframework.boot.cli.compiler.dependencies;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.empty;
/**
* Tests for {@link SpringBootDependenciesDependencyManagement}
@@ -45,7 +44,7 @@ class SpringBootDependenciesDependencyManagementTests {
@Test
void getDependencies() {
assertThat(this.dependencyManagement.getDependencies()).isNotEqualTo(empty());
assertThat(this.dependencyManagement.getDependencies()).isNotEmpty();
}
}

View File

@@ -47,9 +47,12 @@ class AetherGrapeEngineTests {
private final GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
private final RepositoryConfiguration springMilestones = new RepositoryConfiguration("spring-milestones",
private final RepositoryConfiguration springMilestone = new RepositoryConfiguration("spring-milestone",
URI.create("https://repo.spring.io/milestone"), false);
private final RepositoryConfiguration springSnaphot = new RepositoryConfiguration("spring-snapshot",
URI.create("https://repo.spring.io/snapshot"), true);
private AetherGrapeEngine createGrapeEngine(RepositoryConfiguration... additionalRepositories) {
List<RepositoryConfiguration> repositoryConfigurations = new ArrayList<>();
repositoryConfigurations
@@ -64,7 +67,7 @@ class AetherGrapeEngineTests {
@Test
void dependencyResolution() {
Map<String, Object> args = new HashMap<>();
createGrapeEngine(this.springMilestones).grab(args,
createGrapeEngine(this.springMilestone, this.springSnaphot).grab(args,
createDependency("org.springframework", "spring-jdbc", null));
assertThat(this.groovyClassLoader.getURLs()).hasSize(5);
}
@@ -104,7 +107,7 @@ class AetherGrapeEngineTests {
Map<String, Object> args = new HashMap<>();
args.put("excludes", Arrays.asList(createExclusion("org.springframework", "spring-core")));
createGrapeEngine(this.springMilestones).grab(args,
createGrapeEngine(this.springMilestone, this.springSnaphot).grab(args,
createDependency("org.springframework", "spring-jdbc", "3.2.4.RELEASE"),
createDependency("org.springframework", "spring-beans", "3.2.4.RELEASE"));
@@ -126,7 +129,7 @@ class AetherGrapeEngineTests {
GroovyClassLoader customClassLoader = new GroovyClassLoader();
args.put("classLoader", customClassLoader);
createGrapeEngine(this.springMilestones).grab(args,
createGrapeEngine(this.springMilestone, this.springSnaphot).grab(args,
createDependency("org.springframework", "spring-jdbc", null));
assertThat(this.groovyClassLoader.getURLs()).isEmpty();

View File

@@ -2,7 +2,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>build/local-m2-repository</localRepository>
<mirrors>
<mirror>
<id>central-mirror</id>
@@ -10,7 +10,6 @@
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<servers>
<server>
<id>central-mirror</id>
@@ -18,7 +17,6 @@
<password>password</password>
</server>
</servers>
<proxies>
<proxy>
<active>true</active>
@@ -29,5 +27,4 @@
<password>password</password>
</proxy>
</proxies>
</settings>

View File

@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<localRepository>build/local-m2-repository</localRepository>
<profiles>
<profile>
<id>it-repo</id>
<id>cli-test-repo</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>local.central</id>
<url>@localRepositoryUrl@</url>
<url>file:build/test-repository</url>
<releases>
<enabled>true</enabled>
</releases>
@@ -17,19 +18,27 @@
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>local.central</id>
<url>@localRepositoryUrl@</url>
<repository>
<id>spring-snapshot</id>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>true</enabled>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</repository>
<repository>
<id>spring-milestone</id>
<url>https://repo.spring.io/milestone</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
</settings>

View File

@@ -0,0 +1,10 @@
package org.test
@Component
class Example implements CommandLineRunner {
void run(String... args) {
print "Ssshh"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,86 @@
plugins {
id 'java-library'
id 'org.springframework.boot.auto-configuration'
id 'org.springframework.boot.conventions'
id 'org.springframework.boot.deployed'
id 'org.springframework.boot.integration-test'
id 'org.springframework.boot.optional-dependencies'
}
description = 'Spring Boot Developer Tools'
configurations {
intTestDependencies
}
dependencies {
implementation enforcedPlatform(project(':spring-boot-project:spring-boot-dependencies'))
implementation project(':spring-boot-project:spring-boot')
implementation project(':spring-boot-project:spring-boot-autoconfigure')
intTestDependencies project(':spring-boot-project:spring-boot-starters:spring-boot-starter-web')
intTestImplementation enforcedPlatform(project(':spring-boot-project:spring-boot-dependencies'))
intTestImplementation project(':spring-boot-project:spring-boot-autoconfigure')
intTestImplementation project(':spring-boot-project:spring-boot-test')
intTestImplementation project(':spring-boot-project:spring-boot-tools:spring-boot-test-support')
intTestImplementation 'org.apache.httpcomponents:httpclient'
intTestImplementation 'org.assertj:assertj-core'
intTestImplementation 'org.awaitility:awaitility'
intTestImplementation 'org.junit.jupiter:junit-jupiter'
intTestImplementation 'net.bytebuddy:byte-buddy'
intTestRuntimeOnly 'org.springframework:spring-web'
optional enforcedPlatform(project(':spring-boot-project:spring-boot-dependencies'))
optional 'javax.servlet:javax.servlet-api'
optional 'org.apache.derby:derby'
optional 'org.hibernate:hibernate-core'
optional 'org.springframework:spring-jdbc'
optional 'org.springframework:spring-orm'
optional 'org.springframework:spring-web'
optional 'org.springframework.security:spring-security-config'
optional 'org.springframework.security:spring-security-web'
optional 'org.springframework.data:spring-data-redis'
optional 'org.springframework.session:spring-session-core'
testImplementation project(':spring-boot-project:spring-boot-tools:spring-boot-test-support')
testImplementation project(':spring-boot-project:spring-boot-test')
testImplementation 'ch.qos.logback:logback-classic'
testImplementation 'com.h2database:h2'
testImplementation 'com.zaxxer:HikariCP'
testImplementation 'org.apache.derby:derbyclient'
testImplementation 'org.apache.tomcat.embed:tomcat-embed-websocket'
testImplementation 'org.apache.tomcat.embed:tomcat-embed-core'
testImplementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.awaitility:awaitility'
testImplementation 'org.eclipse.jetty.websocket:websocket-client'
testImplementation 'org.hamcrest:hamcrest-library'
testImplementation 'org.hsqldb:hsqldb'
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.mockito:mockito-core'
testImplementation 'org.postgresql:postgresql'
testImplementation 'org.springframework:spring-test'
testImplementation 'org.springframework:spring-webmvc'
testImplementation 'org.springframework:spring-websocket'
testImplementation 'org.springframework.hateoas:spring-hateoas'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.thymeleaf:thymeleaf'
testImplementation 'org.thymeleaf:thymeleaf-spring5'
testImplementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testRuntimeOnly 'org.yaml:snakeyaml'
}
task copyIntTestDependencies(type: Copy) {
destinationDir = file("$buildDir/dependencies")
from {
configurations.intTestDependencies
}
from jar
}
intTest {
dependsOn copyIntTestDependencies
}

View File

@@ -1,220 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>${revision}</version>
<relativePath>../spring-boot-parent</relativePath>
</parent>
<artifactId>spring-boot-devtools</artifactId>
<name>Spring Boot Developer Tools</name>
<description>Spring Boot Developer Tools</description>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<scm>
<url>${git.url}</url>
<connection>${git.connection}</connection>
<developerConnection>${git.developerConnection}</developerConnection>
</scm>
<dependencies>
<!-- Compile -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- Optional -->
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
<optional>true</optional>
</dependency>
<!-- Annotation processing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test-support</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>${derby.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -14,24 +14,17 @@
* limitations under the License.
*/
package org.springframework.boot.load.it.war;
package com.example;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* Simple example Spring MVC Controller.
*
* @author Phillip Webb
*/
@Controller
public class ExampleController {
@RestController
public class ControllerOne {
@RequestMapping("/")
@ResponseBody
public String helloWorld() {
return "Hello Embedded WAR World!";
@RequestMapping("/one")
public String one() {
return "one";
}
}

View File

@@ -14,24 +14,18 @@
* limitations under the License.
*/
package org.springframework.boot.load.it.jar;
package com.example;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.context.WebServerPortFileWriter;
/**
* Simple example Spring MVC Controller.
*
* @author Phillip Webb
*/
@Controller
public class ExampleController {
@SpringBootApplication
public class DevToolsTestApplication {
@RequestMapping("/")
@ResponseBody
public String helloWorld() {
return "Hello Embedded Jar World!";
public static void main(String[] args) {
new SpringApplicationBuilder(DevToolsTestApplication.class).listeners(new WebServerPortFileWriter(args[0]))
.run(args);
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2012-2019 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
*
* https://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.devtools.tests;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.util.FileSystemUtils;
/**
* Base class for all {@link ApplicationLauncher} implementations.
*
* @author Andy Wilkinson
*/
abstract class AbstractApplicationLauncher implements ApplicationLauncher {
private final Directories directories;
AbstractApplicationLauncher(Directories directories) {
this.directories = directories;
}
protected final void copyApplicationTo(File location) throws IOException {
FileSystemUtils.deleteRecursively(location);
location.mkdirs();
FileSystemUtils.copyRecursively(new File(this.directories.getTestClassesDirectory(), "com"),
new File(location, "com"));
}
protected final List<String> getDependencyJarPaths() {
return Stream.of(this.directories.getDependenciesDirectory().listFiles()).map(File::getAbsolutePath)
.collect(Collectors.toList());
}
protected final Directories getDirectories() {
return this.directories;
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright 2012-2019 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
*
* https://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.devtools.tests;
import java.io.File;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FixedValue;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Base class for DevTools integration tests.
*
* @author Andy Wilkinson
*/
abstract class AbstractDevToolsIntegrationTests {
protected static final BuildOutput buildOutput = new BuildOutput(AbstractDevToolsIntegrationTests.class);
protected final File serverPortFile = new File(buildOutput.getRootLocation(), "server.port");
@RegisterExtension
protected final JvmLauncher javaLauncher = new JvmLauncher();
@TempDir
protected static File temp;
protected LaunchedApplication launchedApplication;
protected void launchApplication(ApplicationLauncher applicationLauncher, String... args) throws Exception {
this.serverPortFile.delete();
this.launchedApplication = applicationLauncher.launchApplication(this.javaLauncher, this.serverPortFile, args);
}
@AfterEach
void stopApplication() throws InterruptedException {
this.launchedApplication.stop();
}
protected int awaitServerPort() throws Exception {
int port = Awaitility.waitAtMost(Duration.ofSeconds(30))
.until(() -> new ApplicationState(this.serverPortFile, this.launchedApplication),
ApplicationState::hasServerPort)
.getServerPort();
this.serverPortFile.delete();
this.launchedApplication.restartRemote(port);
Thread.sleep(1000);
return port;
}
protected ControllerBuilder controller(String name) {
return new ControllerBuilder(name, this.launchedApplication.getClassesDirectory());
}
protected static final class ControllerBuilder {
private final List<String> mappings = new ArrayList<>();
private final String name;
private final File classesDirectory;
protected ControllerBuilder(String name, File classesDirectory) {
this.name = name;
this.classesDirectory = classesDirectory;
}
protected ControllerBuilder withRequestMapping(String mapping) {
this.mappings.add(mapping);
return this;
}
protected void build() throws Exception {
DynamicType.Builder<Object> builder = new ByteBuddy().subclass(Object.class).name(this.name)
.annotateType(AnnotationDescription.Builder.ofType(RestController.class).build());
for (String mapping : this.mappings) {
builder = builder.defineMethod(mapping, String.class, Visibility.PUBLIC)
.intercept(FixedValue.value(mapping)).annotateMethod(AnnotationDescription.Builder
.ofType(RequestMapping.class).defineArray("value", mapping).build());
}
builder.make().saveIn(this.classesDirectory);
}
}
}

View File

@@ -14,24 +14,21 @@
* limitations under the License.
*/
package org.springframework.boot.load.it.jar;
package org.springframework.boot.devtools.tests;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.File;
/**
* Simple example Spring MVC Controller.
* Launches an application with DevTools.
*
* @author Phillip Webb
* @author Andy Wilkinson
* @author Madhura Bhave
*/
@Controller
public class ExampleController {
public interface ApplicationLauncher {
@RequestMapping("/")
@ResponseBody
public String helloWorld() {
return "Hello Embedded Jar World!";
}
LaunchedApplication launchApplication(JvmLauncher javaLauncher, File serverPortFile) throws Exception;
LaunchedApplication launchApplication(JvmLauncher jvmLauncher, File serverPortFile, String... additionalArgs)
throws Exception;
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2012-2019 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
*
* https://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.devtools.tests;
import java.io.File;
import org.springframework.boot.devtools.tests.JvmLauncher.LaunchedJvm;
/**
* State of an application.
*
* @author Andy Wilkinson
*/
final class ApplicationState {
private final Integer serverPort;
private final FileContents out;
private final FileContents err;
ApplicationState(File serverPortFile, LaunchedJvm jvm) {
this(serverPortFile, jvm.getStandardOut(), jvm.getStandardError());
}
ApplicationState(File serverPortFile, LaunchedApplication application) {
this(serverPortFile, application.getStandardOut(), application.getStandardError());
}
private ApplicationState(File serverPortFile, File out, File err) {
this.serverPort = new FileContents(serverPortFile).get(Integer::parseInt);
this.out = new FileContents(out);
this.err = new FileContents(err);
}
boolean hasServerPort() {
return this.serverPort != null;
}
int getServerPort() {
return this.serverPort;
}
@Override
public String toString() {
return String.format("Application output:%n%s%n%s", this.out, this.err);
}
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright 2012-2019 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
*
* https://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.devtools.tests;
import java.io.File;
import java.io.IOException;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.StandardHttpRequestRetryHandler;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for DevTools.
*
* @author Andy Wilkinson
*/
class DevToolsIntegrationTests extends AbstractDevToolsIntegrationTests {
private final TestRestTemplate template = new TestRestTemplate(
new RestTemplateBuilder().requestFactory(() -> new HttpComponentsClientHttpRequestFactory(
HttpClients.custom().setRetryHandler(new StandardHttpRequestRetryHandler(10, false)).build())));
@ParameterizedTest(name = "{0}")
@MethodSource("parameters")
void addARequestMappingToAnExistingController(ApplicationLauncher applicationLauncher) throws Exception {
launchApplication(applicationLauncher);
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
controller("com.example.ControllerOne").withRequestMapping("one").withRequestMapping("two").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
}
@ParameterizedTest(name = "{0}")
@MethodSource("parameters")
void removeARequestMappingFromAnExistingController(ApplicationLauncher applicationLauncher) throws Exception {
launchApplication(applicationLauncher);
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
controller("com.example.ControllerOne").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForEntity(urlBase + "/one", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
}
@ParameterizedTest(name = "{0}")
@MethodSource("parameters")
void createAController(ApplicationLauncher applicationLauncher) throws Exception {
launchApplication(applicationLauncher);
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
controller("com.example.ControllerTwo").withRequestMapping("two").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
}
@ParameterizedTest(name = "{0}")
@MethodSource("parameters")
void createAControllerAndThenAddARequestMapping(ApplicationLauncher applicationLauncher) throws Exception {
launchApplication(applicationLauncher);
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
controller("com.example.ControllerTwo").withRequestMapping("two").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
controller("com.example.ControllerTwo").withRequestMapping("two").withRequestMapping("three").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/three", String.class)).isEqualTo("three");
}
@ParameterizedTest(name = "{0}")
@MethodSource("parameters")
void createAControllerAndThenAddARequestMappingToAnExistingController(ApplicationLauncher applicationLauncher)
throws Exception {
launchApplication(applicationLauncher);
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
controller("com.example.ControllerTwo").withRequestMapping("two").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
controller("com.example.ControllerOne").withRequestMapping("one").withRequestMapping("three").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
assertThat(this.template.getForObject(urlBase + "/three", String.class)).isEqualTo("three");
}
@ParameterizedTest(name = "{0}")
@MethodSource("parameters")
void deleteAController(ApplicationLauncher applicationLauncher) throws Exception {
launchApplication(applicationLauncher);
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(new File(this.launchedApplication.getClassesDirectory(), "com/example/ControllerOne.class").delete())
.isTrue();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForEntity(urlBase + "/one", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
}
@ParameterizedTest(name = "{0}")
@MethodSource("parameters")
void createAControllerAndThenDeleteIt(ApplicationLauncher applicationLauncher) throws Exception {
launchApplication(applicationLauncher);
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
controller("com.example.ControllerTwo").withRequestMapping("two").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
assertThat(new File(this.launchedApplication.getClassesDirectory(), "com/example/ControllerTwo.class").delete())
.isTrue();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
}
static Object[] parameters() throws IOException {
Directories directories = new Directories(buildOutput, temp);
return new Object[] { new Object[] { new LocalApplicationLauncher(directories) },
new Object[] { new ExplodedRemoteApplicationLauncher(directories) },
new Object[] { new JarFileRemoteApplicationLauncher(directories) } };
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2012-2019 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
*
* https://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.devtools.tests;
import java.io.IOException;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpStatus;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for DevTools with lazy initialization enabled.
*
* @author Madhura Bhave
*/
class DevToolsWithLazyInitializationIntegrationTests extends AbstractDevToolsIntegrationTests {
@ParameterizedTest(name = "{0}")
@MethodSource("parameters")
void addARequestMappingToAnExistingControllerWhenLazyInit(ApplicationLauncher applicationLauncher)
throws Exception {
launchApplication(applicationLauncher, "--spring.main.lazy-initialization=true");
TestRestTemplate template = new TestRestTemplate();
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
controller("com.example.ControllerOne").withRequestMapping("one").withRequestMapping("two").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
}
static Object[] parameters() throws IOException {
Directories directories = new Directories(buildOutput, temp);
return new Object[] { new Object[] { new LocalApplicationLauncher(directories) },
new Object[] { new ExplodedRemoteApplicationLauncher(directories) },
new Object[] { new JarFileRemoteApplicationLauncher(directories) } };
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2012-2019 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
*
* https://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.devtools.tests;
import java.io.File;
import org.springframework.boot.testsupport.BuildOutput;
/**
* Various directories used by the {@link ApplicationLauncher ApplicationLaunchers}.
*
* @author Andy Wilkinson
*/
class Directories {
private final BuildOutput buildOutput;
private final File temp;
Directories(BuildOutput buildOutput, File temp) {
this.buildOutput = buildOutput;
this.temp = temp;
}
File getTestClassesDirectory() {
return this.buildOutput.getTestClassesLocation();
}
File getRemoteAppDirectory() {
return new File(this.temp, "remote");
}
File getDependenciesDirectory() {
return new File(this.buildOutput.getRootLocation(), "dependencies");
}
File getAppDirectory() {
return new File(this.temp, "app");
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2012-2019 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
*
* https://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.devtools.tests;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.springframework.util.StringUtils;
/**
* {@link ApplicationLauncher} that launches a remote application with its classes
* available directly on the file system.
*
* @author Andy Wilkinson
*/
public class ExplodedRemoteApplicationLauncher extends RemoteApplicationLauncher {
public ExplodedRemoteApplicationLauncher(Directories directories) {
super(directories);
}
@Override
protected String createApplicationClassPath() throws Exception {
File appDirectory = getDirectories().getAppDirectory();
copyApplicationTo(appDirectory);
List<String> entries = new ArrayList<>();
entries.add(appDirectory.getAbsolutePath());
entries.addAll(getDependencyJarPaths());
return StringUtils.collectionToDelimitedString(entries, File.pathSeparator);
}
@Override
public String toString() {
return "exploded remote";
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2012-2019 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
*
* https://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.devtools.tests;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.function.Function;
import org.springframework.util.FileCopyUtils;
/**
* Provides access to the contents of a file.
*
* @author Andy Wilkinson
*/
class FileContents {
private final File file;
FileContents(File file) {
this.file = file;
}
String get() {
return get(Function.identity());
}
<T> T get(Function<String, T> transformer) {
if ((!this.file.exists()) || this.file.length() == 0) {
return null;
}
try {
return transformer.apply(FileCopyUtils.copyToString(new FileReader(this.file)));
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
}
@Override
public String toString() {
return get();
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright 2012-2019 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
*
* https://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.devtools.tests;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
/**
* {@link ApplicationLauncher} that launches a remote application with its classes in a
* jar file.
*
* @author Andy Wilkinson
*/
public class JarFileRemoteApplicationLauncher extends RemoteApplicationLauncher {
public JarFileRemoteApplicationLauncher(Directories directories) {
super(directories);
}
@Override
protected String createApplicationClassPath() throws Exception {
File appDirectory = getDirectories().getAppDirectory();
copyApplicationTo(appDirectory);
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
File appJar = new File(appDirectory, "app.jar");
JarOutputStream output = new JarOutputStream(new FileOutputStream(appJar), manifest);
addToJar(output, appDirectory, appDirectory);
output.close();
List<String> entries = new ArrayList<>();
entries.add(appJar.getAbsolutePath());
entries.addAll(getDependencyJarPaths());
String classpath = StringUtils.collectionToDelimitedString(entries, File.pathSeparator);
return classpath;
}
private void addToJar(JarOutputStream output, File root, File current) throws IOException {
for (File file : current.listFiles()) {
if (file.isDirectory()) {
addToJar(output, root, file);
}
output.putNextEntry(new ZipEntry(
file.getAbsolutePath().substring(root.getAbsolutePath().length() + 1).replace("\\", "/")
+ (file.isDirectory() ? "/" : "")));
if (file.isFile()) {
try (FileInputStream input = new FileInputStream(file)) {
StreamUtils.copy(input, output);
}
}
output.closeEntry();
}
}
@Override
public String toString() {
return "jar file remote";
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright 2012-2019 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
*
* https://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.devtools.tests;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.Extension;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.util.StringUtils;
/**
* {@link Extension} that launches a JVM and redirects its output to a test
* method-specific location.
*
* @author Andy Wilkinson
*/
class JvmLauncher implements BeforeTestExecutionCallback {
private static final Pattern NON_ALPHABET_PATTERN = Pattern.compile("[^A-Za-z]+");
private final BuildOutput buildOutput = new BuildOutput(getClass());
private File outputDirectory;
@Override
public void beforeTestExecution(ExtensionContext context) throws Exception {
this.outputDirectory = new File(this.buildOutput.getRootLocation(),
"output/" + NON_ALPHABET_PATTERN.matcher(context.getRequiredTestMethod().getName()).replaceAll(""));
this.outputDirectory.mkdirs();
}
LaunchedJvm launch(String name, String classpath, String... args) throws IOException {
List<String> command = new ArrayList<>(
Arrays.asList(System.getProperty("java.home") + "/bin/java", "-cp", classpath));
command.addAll(Arrays.asList(args));
File standardOut = new File(this.outputDirectory, name + ".out");
File standardError = new File(this.outputDirectory, name + ".err");
Process process = new ProcessBuilder(StringUtils.toStringArray(command)).redirectError(standardError)
.redirectOutput(standardOut).start();
return new LaunchedJvm(process, standardOut, standardError);
}
static class LaunchedJvm {
private final Process process;
private final File standardOut;
private final File standardError;
LaunchedJvm(Process process, File standardOut, File standardError) {
this.process = process;
this.standardOut = standardOut;
this.standardError = standardError;
}
Process getProcess() {
return this.process;
}
File getStandardOut() {
return this.standardOut;
}
File getStandardError() {
return this.standardError;
}
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright 2012-2019 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
*
* https://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.devtools.tests;
import java.io.File;
import java.util.function.BiFunction;
/**
* An application launched by {@link ApplicationLauncher}.
*
* @author Andy Wilkinson
*/
class LaunchedApplication {
private final File classesDirectory;
private final File standardOut;
private final File standardError;
private final Process localProcess;
private Process remoteProcess;
private final BiFunction<Integer, File, Process> remoteProcessRestarter;
LaunchedApplication(File classesDirectory, File standardOut, File standardError, Process localProcess,
Process remoteProcess, BiFunction<Integer, File, Process> remoteProcessRestarter) {
this.classesDirectory = classesDirectory;
this.standardOut = standardOut;
this.standardError = standardError;
this.localProcess = localProcess;
this.remoteProcess = remoteProcess;
this.remoteProcessRestarter = remoteProcessRestarter;
}
void restartRemote(int port) throws InterruptedException {
if (this.remoteProcessRestarter != null) {
stop(this.remoteProcess);
this.remoteProcess = this.remoteProcessRestarter.apply(port, this.classesDirectory);
}
}
void stop() throws InterruptedException {
stop(this.localProcess);
stop(this.remoteProcess);
}
private void stop(Process process) throws InterruptedException {
if (process != null) {
process.destroy();
process.waitFor();
}
}
File getStandardOut() {
return this.standardOut;
}
File getStandardError() {
return this.standardError;
}
File getClassesDirectory() {
return this.classesDirectory;
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2012-2019 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
*
* https://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.devtools.tests;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.boot.devtools.tests.JvmLauncher.LaunchedJvm;
import org.springframework.util.StringUtils;
/**
* {@link ApplicationLauncher} that launches a local application with DevTools enabled.
*
* @author Andy Wilkinson
*/
public class LocalApplicationLauncher extends AbstractApplicationLauncher {
LocalApplicationLauncher(Directories directories) {
super(directories);
}
@Override
public LaunchedApplication launchApplication(JvmLauncher jvmLauncher, File serverPortFile) throws Exception {
LaunchedJvm jvm = jvmLauncher.launch("local", createApplicationClassPath(),
"com.example.DevToolsTestApplication", serverPortFile.getAbsolutePath(), "--server.port=0");
return new LaunchedApplication(getDirectories().getAppDirectory(), jvm.getStandardOut(), jvm.getStandardError(),
jvm.getProcess(), null, null);
}
@Override
public LaunchedApplication launchApplication(JvmLauncher jvmLauncher, File serverPortFile, String... additionalArgs)
throws Exception {
List<String> args = new ArrayList<>(Arrays.asList("com.example.DevToolsTestApplication",
serverPortFile.getAbsolutePath(), "--server.port=0"));
args.addAll(Arrays.asList(additionalArgs));
LaunchedJvm jvm = jvmLauncher.launch("local", createApplicationClassPath(), args.toArray(new String[] {}));
return new LaunchedApplication(getDirectories().getAppDirectory(), jvm.getStandardOut(), jvm.getStandardError(),
jvm.getProcess(), null, null);
}
protected String createApplicationClassPath() throws Exception {
File appDirectory = getDirectories().getAppDirectory();
copyApplicationTo(appDirectory);
List<String> entries = new ArrayList<>();
entries.add(appDirectory.getAbsolutePath());
entries.addAll(getDependencyJarPaths());
return StringUtils.collectionToDelimitedString(entries, File.pathSeparator);
}
@Override
public String toString() {
return "local";
}
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright 2012-2019 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
*
* https://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.devtools.tests;
import java.io.File;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import org.awaitility.Awaitility;
import org.springframework.boot.devtools.RemoteSpringApplication;
import org.springframework.boot.devtools.tests.JvmLauncher.LaunchedJvm;
import org.springframework.util.StringUtils;
import static org.hamcrest.Matchers.containsString;
/**
* Base class for {@link ApplicationLauncher} implementations that use
* {@link RemoteSpringApplication}.
*
* @author Andy Wilkinson
*/
abstract class RemoteApplicationLauncher extends AbstractApplicationLauncher {
RemoteApplicationLauncher(Directories directories) {
super(directories);
}
@Override
public LaunchedApplication launchApplication(JvmLauncher javaLauncher, File serverPortFile) throws Exception {
LaunchedJvm applicationJvm = javaLauncher.launch("app", createApplicationClassPath(),
"com.example.DevToolsTestApplication", serverPortFile.getAbsolutePath(), "--server.port=0",
"--spring.devtools.remote.secret=secret");
int port = awaitServerPort(applicationJvm, serverPortFile);
BiFunction<Integer, File, Process> remoteRestarter = getRemoteRestarter(javaLauncher);
return new LaunchedApplication(getDirectories().getRemoteAppDirectory(), applicationJvm.getStandardOut(),
applicationJvm.getStandardError(), applicationJvm.getProcess(), remoteRestarter.apply(port, null),
remoteRestarter);
}
@Override
public LaunchedApplication launchApplication(JvmLauncher javaLauncher, File serverPortFile,
String... additionalArgs) throws Exception {
List<String> args = new ArrayList<>(Arrays.asList("com.example.DevToolsTestApplication",
serverPortFile.getAbsolutePath(), "--server.port=0", "--spring.devtools.remote.secret=secret"));
args.addAll(Arrays.asList(additionalArgs));
LaunchedJvm applicationJvm = javaLauncher.launch("app", createApplicationClassPath(),
args.toArray(new String[] {}));
int port = awaitServerPort(applicationJvm, serverPortFile);
BiFunction<Integer, File, Process> remoteRestarter = getRemoteRestarter(javaLauncher);
return new LaunchedApplication(getDirectories().getRemoteAppDirectory(), applicationJvm.getStandardOut(),
applicationJvm.getStandardError(), applicationJvm.getProcess(), remoteRestarter.apply(port, null),
remoteRestarter);
}
private BiFunction<Integer, File, Process> getRemoteRestarter(JvmLauncher javaLauncher) {
return (port, classesDirectory) -> {
try {
LaunchedJvm remoteSpringApplicationJvm = javaLauncher.launch("remote-spring-application",
createRemoteSpringApplicationClassPath(classesDirectory),
RemoteSpringApplication.class.getName(), "--spring.devtools.remote.secret=secret",
"http://localhost:" + port);
awaitRemoteSpringApplication(remoteSpringApplicationJvm.getStandardOut());
return remoteSpringApplicationJvm.getProcess();
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
};
}
protected abstract String createApplicationClassPath() throws Exception;
private String createRemoteSpringApplicationClassPath(File classesDirectory) throws Exception {
File remoteAppDirectory = getDirectories().getRemoteAppDirectory();
if (classesDirectory == null) {
copyApplicationTo(remoteAppDirectory);
}
List<String> entries = new ArrayList<>();
entries.add(remoteAppDirectory.getAbsolutePath());
entries.addAll(getDependencyJarPaths());
return StringUtils.collectionToDelimitedString(entries, File.pathSeparator);
}
private int awaitServerPort(LaunchedJvm jvm, File serverPortFile) throws Exception {
return Awaitility.waitAtMost(Duration.ofSeconds(30))
.until(() -> new ApplicationState(serverPortFile, jvm), ApplicationState::hasServerPort)
.getServerPort();
}
private void awaitRemoteSpringApplication(File standardOut) throws Exception {
FileContents contents = new FileContents(standardOut);
Awaitility.waitAtMost(Duration.ofSeconds(30)).until(contents::get,
containsString("Started RemoteSpringApplication"));
}
}

View File

@@ -1,6 +1,6 @@
restart.exclude.spring-boot=/spring-boot/target/classes/
restart.exclude.spring-boot-devtools=/spring-boot-devtools/target/classes/
restart.exclude.spring-boot-autoconfigure=/spring-boot-autoconfigure/target/classes/
restart.exclude.spring-boot-actuator=/spring-boot-actuator/target/classes/
restart.exclude.spring-boot-starter=/spring-boot-starter/target/classes/
restart.exclude.spring-boot=/spring-boot/(bin|build|out)/
restart.exclude.spring-boot-devtools=/spring-boot-devtools/(bin|build|out)/
restart.exclude.spring-boot-autoconfigure=/spring-boot-autoconfigure/(bin|build|out)/
restart.exclude.spring-boot-actuator=/spring-boot-actuator/(bin|build|out)/
restart.exclude.spring-boot-starter=/spring-boot-starter/(bin|build|out)/
restart.exclude.spring-boot-starters=/spring-boot-starter-[\\w-]+/

View File

@@ -100,11 +100,12 @@ class FileSystemWatcherTests {
}
@Test
void sourceFolderMustNotBeAFile() {
File folder = new File("pom.xml");
assertThat(folder.isFile()).isTrue();
assertThatIllegalArgumentException().isThrownBy(() -> this.watcher.addSourceFolder(new File("pom.xml")))
.withMessageContaining("Folder 'pom.xml' must not be a file");
void sourceFolderMustNotBeAFile() throws IOException {
File file = new File(this.tempDir, "file");
assertThat(file.createNewFile()).isTrue();
assertThat(file.isFile()).isTrue();
assertThatIllegalArgumentException().isThrownBy(() -> this.watcher.addSourceFolder(file))
.withMessageContaining("Folder '" + file + "' must not be a file");
}
@Test

View File

@@ -104,7 +104,7 @@ class ChangeableUrlsTests {
private URL makeUrl(String name) throws IOException {
File file = new File(this.tempDir, UUID.randomUUID().toString());
file = new File(file, name);
file = new File(file, "target");
file = new File(file, "build");
file = new File(file, "classes");
file.mkdirs();
return file.toURI().toURL();

View File

@@ -16,6 +16,10 @@
package org.springframework.boot.devtools.restart;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@@ -82,8 +86,17 @@ class DefaultRestartInitializerTests {
}
@Test
void urlsCanBeRetrieved() {
assertThat(new DefaultRestartInitializer().getUrls(Thread.currentThread())).isNotEmpty();
void urlsCanBeRetrieved() throws IOException {
Thread thread = Thread.currentThread();
ClassLoader classLoader = thread.getContextClassLoader();
try (URLClassLoader contextClassLoader = new URLClassLoader(
new URL[] { new URL("file:test-app/build/classes/main/") }, classLoader)) {
thread.setContextClassLoader(contextClassLoader);
assertThat(new DefaultRestartInitializer().getUrls(thread)).isNotEmpty();
}
finally {
thread.setContextClassLoader(classLoader);
}
}
protected void testSkippedStacks(String s) {

View File

@@ -62,7 +62,7 @@ class DevToolsSettingsTests {
private URL makeUrl(File file, String name) throws IOException {
file = new File(file, name);
file = new File(file, "target");
file = new File(file, "build");
file = new File(file, "classes");
file.mkdirs();
return file.toURI().toURL();

View File

@@ -0,0 +1,241 @@
plugins {
id 'java-base'
id 'org.asciidoctor.jvm.convert'
id 'org.asciidoctor.jvm.pdf'
id 'org.springframework.boot.conventions'
id 'org.springframework.boot.deployed'
}
configurations {
actuatorApiDocumentation
autoConfiguration
configurationProperties
gradlePluginDocumentation
mavenPluginDocumentation
testSlices
}
dependencies {
testSlices project(path: ':spring-boot-project:spring-boot-test-autoconfigure', configuration: 'testSliceMetadata')
autoConfiguration project(path: ':spring-boot-project:spring-boot-autoconfigure', configuration: 'autoConfigurationMetadata')
autoConfiguration project(path: ':spring-boot-project:spring-boot-actuator-autoconfigure', configuration: 'autoConfigurationMetadata')
autoConfiguration project(path: ':spring-boot-project:spring-boot-devtools', configuration: 'autoConfigurationMetadata')
configurationProperties project(path: ':spring-boot-project:spring-boot', configuration: 'configurationPropertiesMetadata')
configurationProperties project(path: ':spring-boot-project:spring-boot-actuator', configuration: 'configurationPropertiesMetadata')
configurationProperties project(path: ':spring-boot-project:spring-boot-actuator-autoconfigure', configuration: 'configurationPropertiesMetadata')
configurationProperties project(path: ':spring-boot-project:spring-boot-autoconfigure', configuration: 'configurationPropertiesMetadata')
configurationProperties project(path: ':spring-boot-project:spring-boot-devtools', configuration: 'configurationPropertiesMetadata')
gradlePluginDocumentation project(path: ':spring-boot-project:spring-boot-tools:spring-boot-gradle-plugin', configuration: 'documentation')
actuatorApiDocumentation project(path: ':spring-boot-project:spring-boot-actuator-autoconfigure', configuration: 'documentation')
mavenPluginDocumentation project(path: ':spring-boot-project:spring-boot-tools:spring-boot-maven-plugin', configuration: 'documentation')
}
task dependencyVersions(type: org.springframework.boot.build.constraints.ExtractVersionConstraints) {
enforcedPlatform(':spring-boot-project:spring-boot-dependencies')
}
task javadoc(type: Javadoc) {
dependsOn dependencyVersions
project.rootProject.gradle.projectsEvaluated {
Set<Project> publishedProjects = rootProject.subprojects.findAll { it != project}
.findAll { it.plugins.hasPlugin(JavaPlugin) && it.plugins.hasPlugin(MavenPublishPlugin) }
.findAll { it.name != 'spring-boot-maven-plugin' && it.name != 'spring-boot-gradle-plugin' }
dependsOn publishedProjects.javadoc
source publishedProjects.javadoc.source
classpath = project.files(publishedProjects.javadoc.classpath)
destinationDir = project.file "$buildDir/docs/javadoc"
options {
author = true
docTitle = "Spring Boot ${project.version} API"
encoding = 'UTF-8'
memberLevel = 'protected'
outputLevel = 'quiet'
source = '1.8'
splitIndex = true
stylesheetFile = file('src/main/javadoc/spring-javadoc.css')
use = true
windowTitle = "Spring Boot ${project.version} API"
}
doFirst {
def versionConstraints = dependencyVersions.versionConstraints
options.links = [
'https://docs.oracle.com/javase/8/docs/api/',
'https://docs.oracle.com/javaee/7/api/',
"https://docs.spring.io/spring-framework/docs/${versionConstraints['org.springframework:spring-core']}/javadoc-api/",
"https://docs.spring.io/spring-security/site/docs/${versionConstraints['org.springframework.security:spring-security-core']}/api/",
'https://tomcat.apache.org/tomcat-9.0-doc/api/',
"https://www.eclipse.org/jetty/javadoc/${versionConstraints['org.eclipse.jetty:jetty-server']}/",
"https://www.thymeleaf.org/apidocs/thymeleaf/${versionConstraints['org.thymeleaf:thymeleaf']}/"
] as String[]
}
}
}
task documentTestSlices(type: org.springframework.boot.build.test.autoconfigure.DocumentTestSlices) {
testSlices = configurations.testSlices
outputFile = file("$buildDir/docs/generated/test-slice-auto-configuration.adoc")
}
task documentStarters(type: org.springframework.boot.build.starters.DocumentStarters) {
outputDir = file("$buildDir/docs/generated/starters/")
}
task documentAutoConfigurationClasses(type: org.springframework.boot.build.autoconfigure.DocumentAutoConfigurationClasses) {
autoConfiguration = configurations.autoConfiguration
outputDir = file("$buildDir/docs/generated/auto-configuration-classes/")
}
task documentDependencyVersions(type: org.springframework.boot.build.constraints.DocumentConstrainedVersions) {
dependsOn dependencyVersions
constrainedVersions.set(providers.provider { dependencyVersions.constrainedVersions })
outputFile = file("$buildDir/docs/generated/dependency-versions.adoc")
}
task documentConfigurationProperties(type: org.springframework.boot.build.context.properties.DocumentConfigurationProperties) {
configurationPropertyMetadata = configurations.configurationProperties
outputDir = file("$buildDir/docs/generated/config-docs/")
}
tasks.withType(org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask) {
dependsOn dependencyVersions
baseDirFollowsSourceDir()
doFirst {
def versionConstraints = dependencyVersions.versionConstraints
attributes 'jetty-version': versionConstraints['org.eclipse.jetty:jetty-server'],
'jooq-version': versionConstraints['org.jooq:jooq'],
'spring-amqp-version': versionConstraints['org.springframework.amqp:spring-amqp'],
'spring-batch-version': versionConstraints['org.springframework.batch:spring-batch-core'],
'spring-boot-version': project.version,
'spring-data-commons-version': versionConstraints['org.springframework.data:spring-data-commons'],
'spring-data-couchbase-version': versionConstraints['org.springframework.data:spring-data-couchbase'],
'spring-data-jdbc-version': versionConstraints['org.springframework.data:spring-data-jdbc'],
'spring-data-jpa-version': versionConstraints['org.springframework.data:spring-data-jpa'],
'spring-data-mongodb-version': versionConstraints['org.springframework.data:spring-data-mongodb'],
'spring-data-neo4j-version': versionConstraints['org.springframework.data:spring-data-neo4j'],
'spring-data-rest-version': versionConstraints['org.springframework.data:spring-data-rest-core'],
'spring-data-solr-version': versionConstraints['org.springframework.data:spring-data-solr'],
'spring-framework-version': versionConstraints['org.springframework:spring-core'],
'spring-integration-version': versionConstraints['org.springframework.integration:spring-integration-core'],
'spring-security-version': versionConstraints['org.springframework.security:spring-security-core'],
'spring-webservices-version': versionConstraints['org.springframework.ws:spring-ws-core']
}
}
asciidoctor {
sources {
include '*.htmlsingleadoc'
}
}
asciidoctorPdf {
sources {
include '*.pdfadoc'
}
}
task asciidoctorMultipage(type: org.asciidoctor.gradle.jvm.AsciidoctorTask) {
sources {
include '*.htmladoc'
include '*.adoc'
}
}
syncDocumentationSourceForAsciidoctor {
dependsOn documentTestSlices
dependsOn documentStarters
dependsOn documentAutoConfigurationClasses
dependsOn documentDependencyVersions
dependsOn documentConfigurationProperties
from("$buildDir/docs/generated") {
into 'asciidoc'
}
from ("src/main/java") {
into 'main/java'
}
from ("src/test/java") {
into 'test/java'
}
}
syncDocumentationSourceForAsciidoctorMultipage {
dependsOn documentTestSlices
dependsOn documentStarters
dependsOn documentAutoConfigurationClasses
dependsOn documentDependencyVersions
dependsOn documentConfigurationProperties
from("$buildDir/docs/generated") {
into 'asciidoc'
}
from ("src/main/java") {
into 'main/java'
}
from ("src/test/java") {
into 'test/java'
}
}
syncDocumentationSourceForAsciidoctorPdf {
dependsOn documentTestSlices
dependsOn documentStarters
dependsOn documentAutoConfigurationClasses
dependsOn documentDependencyVersions
dependsOn documentConfigurationProperties
from("$buildDir/docs/generated") {
into 'asciidoc'
}
from ("src/main/java") {
into 'main/java'
}
from ("src/test/java") {
into 'test/java'
}
}
task zip(type: Zip) {
dependsOn asciidoctor,
asciidoctorMultipage,
asciidoctorPdf,
configurations.gradlePluginDocumentation,
configurations.actuatorApiDocumentation,
configurations.mavenPluginDocumentation
duplicatesStrategy 'fail'
from(asciidoctor.outputDir) {
into 'reference/htmlsingle'
}
from(asciidoctorPdf.outputDir) {
into 'reference/pdf'
}
from(asciidoctorMultipage.outputDir) {
into 'reference/html'
}
from(javadoc) {
into 'api'
}
into('gradle-plugin') {
from {
zipTree(configurations.gradlePluginDocumentation.singleFile)
}
}
into('actuator-api') {
from {
zipTree(configurations.actuatorApiDocumentation.singleFile)
}
}
into('maven-plugin') {
from {
zipTree(configurations.mavenPluginDocumentation.singleFile)
}
}
}
artifacts {
archives zip
}
publishing {
publications {
deployment(MavenPublication) {
artifact zip
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
[appendix]
[[common-application-properties]]
= Common Application properties
include::{asciidoc-sources-root}/attributes.adoc[]
include::attributes.adoc[]
Various properties can be specified inside your `application.properties` file, inside your `application.yml` file, or as command line switches.
This appendix provides a list of common Spring Boot properties and references to the underlying classes that consume them.
@@ -15,64 +15,64 @@ Also, you can define your own properties.
== Core properties
include::{generated-resources-root}/config-docs/core.adoc[]
include::config-docs/core.adoc[]
== Cache properties
include::{generated-resources-root}/config-docs/cache.adoc[]
include::config-docs/cache.adoc[]
== Mail properties
include::{generated-resources-root}/config-docs/mail.adoc[]
include::config-docs/mail.adoc[]
== JSON properties
include::{generated-resources-root}/config-docs/json.adoc[]
include::config-docs/json.adoc[]
== Data properties
include::{generated-resources-root}/config-docs/data.adoc[]
include::config-docs/data.adoc[]
== Transaction properties
include::{generated-resources-root}/config-docs/transaction.adoc[]
include::config-docs/transaction.adoc[]
== Data migration properties
include::{generated-resources-root}/config-docs/data-migration.adoc[]
include::config-docs/data-migration.adoc[]
== Integration properties
include::{generated-resources-root}/config-docs/integration.adoc[]
include::config-docs/integration.adoc[]
== Web properties
include::{generated-resources-root}/config-docs/web.adoc[]
include::config-docs/web.adoc[]
== Templating properties
include::{generated-resources-root}/config-docs/templating.adoc[]
include::config-docs/templating.adoc[]
== Server properties
include::{generated-resources-root}/config-docs/server.adoc[]
include::config-docs/server.adoc[]
== Security properties
include::{generated-resources-root}/config-docs/security.adoc[]
include::config-docs/security.adoc[]
== RSocket properties
include::{generated-resources-root}/config-docs/rsocket.adoc[]
include::config-docs/rsocket.adoc[]
== Actuator properties
include::{generated-resources-root}/config-docs/actuator.adoc[]
include::config-docs/actuator.adoc[]
== Devtools properties
include::{generated-resources-root}/config-docs/devtools.adoc[]
include::config-docs/devtools.adoc[]
== Testing properties
include::{generated-resources-root}/config-docs/testing.adoc[]
include::config-docs/testing.adoc[]

View File

@@ -1,7 +1,7 @@
[appendix]
[[auto-configuration-classes]]
= Auto-configuration Classes
include::{asciidoc-sources-root}/attributes.adoc[]
include::attributes.adoc[]
This appendix contains details of all of the auto-configuration classes provided by Spring Boot, with links to documentation and source code.
Remember to also look at the conditions report in your application for more details of which features are switched on.
@@ -13,7 +13,7 @@ Remember to also look at the conditions report in your application for more deta
== `spring-boot-autoconfigure`
The following auto-configuration classes are from the `spring-boot-autoconfigure` module:
include::{generated-resources-root}/auto-configuration-classes-spring-boot-autoconfigure.adoc[]
include::auto-configuration-classes/spring-boot-autoconfigure.adoc[]
@@ -21,4 +21,4 @@ include::{generated-resources-root}/auto-configuration-classes-spring-boot-autoc
== `spring-boot-actuator-autoconfigure`
The following auto-configuration classes are from the `spring-boot-actuator-autoconfigure` module:
include::{generated-resources-root}/auto-configuration-classes-spring-boot-actuator-autoconfigure.adoc[]
include::auto-configuration-classes/spring-boot-actuator-autoconfigure.adoc[]

View File

@@ -1,7 +1,7 @@
[appendix]
[[configuration-metadata]]
= Configuration Metadata
include::{asciidoc-sources-root}/attributes.adoc[]
include::attributes.adoc[]
Spring Boot jars include metadata files that provide details of all supported configuration properties.
The files are designed to let IDE developers offer contextual help and "`code completion`" as users are working with `application.properties` or `application.yml` files.

View File

@@ -1,7 +1,7 @@
[appendix]
[[dependency-versions]]
= Dependency versions
include::{asciidoc-sources-root}/attributes.adoc[]
include::attributes.adoc[]
This appendix provides details of the dependencies that are managed by Spring Boot.
@@ -11,4 +11,4 @@ This appendix provides details of the dependencies that are managed by Spring Bo
The following table provides details of all of the dependency versions that are provided by Spring Boot in its CLI (Command Line Interface), Maven dependency management, and Gradle plugin.
When you declare a dependency on one of these artifacts without declaring a version, the version listed in the table is used.
include::{generated-resources-root}/effective-pom.adoc[]
include::dependency-versions.adoc[]

View File

@@ -1,7 +1,7 @@
[appendix]
[[executable-jar]]
= The Executable Jar Format
include::{asciidoc-sources-root}/attributes.adoc[]
include::attributes.adoc[]
The `spring-boot-loader` modules lets Spring Boot support executable jar and war files.
If you use the Maven plugin or the Gradle plugin, executable jars are automatically generated, and you generally do not need to know the details of how they work.

View File

@@ -1,7 +1,7 @@
[appendix]
[[test-auto-configuration]]
= Test Auto-configuration Annotations
include::{asciidoc-sources-root}/attributes.adoc[]
include::attributes.adoc[]
This appendix describes the `@…Test` auto-configuration annotations that Spring Boot provides to test slices of your application.
@@ -10,4 +10,4 @@ This appendix describes the `@…Test` auto-configuration annotations that Sprin
The following table lists the various `@…Test` annotations that can be used to test slices of your application and the auto-configuration that they import by default:
include::{generated-resources-root}/test-slice-auto-configuration.adoc[]
include::test-slice-auto-configuration.adoc[]

View File

@@ -20,8 +20,8 @@
:github-issues: https://github.com/{github-repo}/issues/
:github-wiki: https://github.com/{github-repo}/wiki
:code-examples: {sources-root}/main/java/org/springframework/boot/docs
:test-examples: {sources-root}/test/java/org/springframework/boot/docs
:code-examples: ../main/java/org/springframework/boot/docs
:test-examples: ../test/java/org/springframework/boot/docs
:spring-boot-code: https://github.com/{github-repo}/tree/{github-tag}
:spring-boot-api: https://docs.spring.io/spring-boot/docs/{spring-boot-version}/api/

Some files were not shown because too many files have changed in this diff Show More