Commit 4a605f62 authored by Andy Wilkinson's avatar Andy Wilkinson

Drop custom software component in favor of just publishing an artifact

Previously, Spring Boot's Gradle plugin provided custom software
components (bootJava and bootWeb) for publishing the artifacts created
by the standard bootJar and bootWar tasks respectively. Providing a
custom software component requires the usage of some of Gradle's
internal APIs and this has now proven to be more trouble than it is
worth.

This commit removes the custom software component and documents how
to publish the artifact created by a BootJar or BootWar task directly
instead.

Closes gh-9153
parent 725a42a6
...@@ -43,6 +43,7 @@ In addition to this user guide, {api-documentation}[API documentation] is also a ...@@ -43,6 +43,7 @@ In addition to this user guide, {api-documentation}[API documentation] is also a
include::getting-started.adoc[] include::getting-started.adoc[]
include::managing-dependencies.adoc[] include::managing-dependencies.adoc[]
include::packaging.adoc[] include::packaging.adoc[]
include::publishing.adoc[]
include::running.adoc[] include::running.adoc[]
include::integrating-with-actuator.adoc[] include::integrating-with-actuator.adoc[]
include::reacting.adoc[] include::reacting.adoc[]
\ No newline at end of file
...@@ -20,12 +20,10 @@ include::../gradle/publishing/maven.gradle[tags=upload] ...@@ -20,12 +20,10 @@ include::../gradle/publishing/maven.gradle[tags=upload]
[[publishing-your-application-maven-publish]] [[publishing-your-application-maven-publish]]
=== Publishing with the `maven-publish` plugin === Publishing with the `maven-publish` plugin
When the {java-plugin}[`java` plugin] is applied Spring Boot automatically creates a To publish your Spring Boot jar or war, add it to the publication using the `artifact`
{software-component}[software component] named `bootJava`. Similarly, when the `war` method on `MavenPublication`. Pass the task that produces that artifact that you wish
plugin is applied, a software component named `bootWeb` is created. `bootJava` contains to publish to the `artifact` method. For example, to publish the artifact produced by the
the archive produced by the `bootJar` task and `bootWeb` contains the archive provided by default `bootJar` task:
the `bootWar` task. The components can be used with the
{maven-publish-plugin}[`maven-publish` plugin] to publish the archive, for example:
[source,groovy,indent=0,subs="verbatim"] [source,groovy,indent=0,subs="verbatim"]
---- ----
......
...@@ -16,13 +16,11 @@ plugin: ...@@ -16,13 +16,11 @@ plugin:
are packaged in `BOOT-INF/lib` are packaged in `BOOT-INF/lib`
2. Configures the `assemble` task to depend on the `bootJar` task. 2. Configures the `assemble` task to depend on the `bootJar` task.
3. Disables the `jar` task. 3. Disables the `jar` task.
4. Creates a {software-component}[software component] named `bootJava` that contains the 4. Creates a {boot-run-javadoc}[`BootRun`] task named `bootRun` that can be used to run
archive produced by the `bootJar` task.
5. Creates a {boot-run-javadoc}[`BootRun`] task named `bootRun` that can be used to run
your application. your application.
6. Creates a configuration named `bootArchives` that contains the artifact produced by 5. Creates a configuration named `bootArchives` that contains the artifact produced by
the `bootJar` task. the `bootJar` task.
7. Configures any `JavaCompile` tasks with no configured encoding to use `UTF-8`. 6. Configures any `JavaCompile` tasks with no configured encoding to use `UTF-8`.
...@@ -36,9 +34,7 @@ When Gradle's {war-plugin}[`war` plugin] is applied to a project, the Spring Boo ...@@ -36,9 +34,7 @@ When Gradle's {war-plugin}[`war` plugin] is applied to a project, the Spring Boo
in the `providedRuntime` configuration will be packaged in `WEB-INF/lib-provided`. in the `providedRuntime` configuration will be packaged in `WEB-INF/lib-provided`.
2. Configures the `assemble` task to depend on the `bootWar` task. 2. Configures the `assemble` task to depend on the `bootWar` task.
3. Disables the `war` task. 3. Disables the `war` task.
4. Creates a {software-component}[software component] named `bootWeb` that contains the 4. Configures the `bootArchives` configuration to contain the artifact produced by the
archive produced by the `bootWar` task.
5. Configures the `bootArchives` configuration to contain the artifact produced by the
`bootWar` task. `bootWar` task.
......
...@@ -12,7 +12,7 @@ apply plugin: 'maven-publish' ...@@ -12,7 +12,7 @@ apply plugin: 'maven-publish'
publishing { publishing {
publications { publications {
bootJava(MavenPublication) { bootJava(MavenPublication) {
from components.bootJava artifact bootJar
} }
} }
repositories { repositories {
......
...@@ -92,8 +92,6 @@ final class JavaPluginAction implements PluginApplicationAction { ...@@ -92,8 +92,6 @@ final class JavaPluginAction implements PluginApplicationAction {
private void configureArtifactPublication(Project project, BootJar bootJar) { private void configureArtifactPublication(Project project, BootJar bootJar) {
ArchivePublishArtifact artifact = new ArchivePublishArtifact(bootJar); ArchivePublishArtifact artifact = new ArchivePublishArtifact(bootJar);
this.singlePublishedArtifact.addCandidate(artifact); this.singlePublishedArtifact.addCandidate(artifact);
project.getComponents().add(new SpringBootSoftwareComponent(project, artifact,
SpringBootPlugin.BOOT_JAVA_SOFTWARE_COMPONENT_NAME));
} }
private void configureBootRunTask(Project project) { private void configureBootRunTask(Project project) {
......
...@@ -23,7 +23,6 @@ import org.gradle.api.GradleException; ...@@ -23,7 +23,6 @@ import org.gradle.api.GradleException;
import org.gradle.api.Plugin; import org.gradle.api.Plugin;
import org.gradle.api.Project; import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Configuration;
import org.gradle.api.component.SoftwareComponent;
import org.gradle.util.GradleVersion; import org.gradle.util.GradleVersion;
import org.springframework.boot.gradle.dsl.SpringBootExtension; import org.springframework.boot.gradle.dsl.SpringBootExtension;
...@@ -46,20 +45,6 @@ public class SpringBootPlugin implements Plugin<Project> { ...@@ -46,20 +45,6 @@ public class SpringBootPlugin implements Plugin<Project> {
*/ */
public static final String BOOT_ARCHIVES_CONFIGURATION_NAME = "bootArchives"; public static final String BOOT_ARCHIVES_CONFIGURATION_NAME = "bootArchives";
/**
* The name of the {@link SoftwareComponent} for a Spring Boot Java application.
*
* @since 2.0.0
*/
public static final String BOOT_JAVA_SOFTWARE_COMPONENT_NAME = "bootJava";
/**
* The name of the {@link SoftwareComponent} for a Spring Boot Web application.
*
* @since 2.0.0
*/
public static final String BOOT_WEB_SOFTWARE_COMPONENT_NAME = "bootWeb";
/** /**
* The name of the default {@link BootJar} task. * The name of the default {@link BootJar} task.
* *
......
/*
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.gradle.plugin;
import java.util.Collections;
import java.util.Set;
import org.gradle.api.Project;
import org.gradle.api.artifacts.ModuleDependency;
import org.gradle.api.artifacts.PublishArtifact;
import org.gradle.api.attributes.Usage;
import org.gradle.api.internal.attributes.Usages;
import org.gradle.api.internal.component.SoftwareComponentInternal;
import org.gradle.api.internal.component.UsageContext;
/**
* {@link org.gradle.api.component.SoftwareComponent} for a Spring Boot fat jar or war.
*
* @author Andy Wilkinson
*/
final class SpringBootSoftwareComponent implements SoftwareComponentInternal {
private final PublishArtifact artifact;
private final String name;
private final Usage usage;
SpringBootSoftwareComponent(Project project, PublishArtifact artifact, String name) {
this.artifact = artifact;
this.name = name;
this.usage = createUsage(project);
}
private static Usage createUsage(Project project) {
try {
return Usages.usage("master");
}
catch (Throwable ex) {
return createUsageUsingObjectFactory(project);
}
}
private static Usage createUsageUsingObjectFactory(Project project) {
try {
Object objects = project.getClass().getMethod("getObjects").invoke(project);
return (Usage) objects.getClass()
.getMethod("named", Class.class, String.class)
.invoke(objects, Usage.class, "master");
}
catch (Throwable ex) {
throw new RuntimeException(ex);
}
}
@Override
public String getName() {
return this.name;
}
@Override
public Set<UsageContext> getUsages() {
return Collections.singleton(new BootUsageContext(this.usage, this.artifact));
}
private static final class BootUsageContext implements UsageContext {
private final Usage usage;
private final PublishArtifact artifact;
private BootUsageContext(Usage usage, PublishArtifact artifact) {
this.usage = usage;
this.artifact = artifact;
}
@Override
public Usage getUsage() {
return this.usage;
}
@Override
public Set<PublishArtifact> getArtifacts() {
return Collections.singleton(this.artifact);
}
@Override
public Set<ModuleDependency> getDependencies() {
return Collections.emptySet();
}
}
}
...@@ -55,8 +55,6 @@ class WarPluginAction implements PluginApplicationAction { ...@@ -55,8 +55,6 @@ class WarPluginAction implements PluginApplicationAction {
bootWar.providedClasspath(providedRuntimeConfiguration(project)); bootWar.providedClasspath(providedRuntimeConfiguration(project));
ArchivePublishArtifact artifact = new ArchivePublishArtifact(bootWar); ArchivePublishArtifact artifact = new ArchivePublishArtifact(bootWar);
this.singlePublishedArtifact.addCandidate(artifact); this.singlePublishedArtifact.addCandidate(artifact);
project.getComponents().add(new SpringBootSoftwareComponent(project, artifact,
SpringBootPlugin.BOOT_WEB_SOFTWARE_COMPONENT_NAME));
bootWar.conventionMapping("mainClass", bootWar.conventionMapping("mainClass",
new MainClassConvention(project, bootWar::getClasspath)); new MainClassConvention(project, bootWar::getClasspath));
} }
......
...@@ -66,19 +66,6 @@ public class JavaPluginActionIntegrationTests { ...@@ -66,19 +66,6 @@ public class JavaPluginActionIntegrationTests {
.getOutput()).contains("bootRun exists = true"); .getOutput()).contains("bootRun exists = true");
} }
@Test
public void noBootJavaSoftwareComponentWithoutJavaPluginApplied() {
assertThat(this.gradleBuild.build("componentExists", "-PcomponentName=bootJava")
.getOutput()).contains("bootJava exists = false");
}
@Test
public void applyingJavaPluginCreatesBootJavaSoftwareComponent() {
assertThat(this.gradleBuild
.build("componentExists", "-PcomponentName=bootJava", "-PapplyJavaPlugin")
.getOutput()).contains("bootJava exists = true");
}
@Test @Test
public void javaCompileTasksUseUtf8Encoding() { public void javaCompileTasksUseUtf8Encoding() {
assertThat(this.gradleBuild.build("javaCompileEncoding", "-PapplyJavaPlugin") assertThat(this.gradleBuild.build("javaCompileEncoding", "-PapplyJavaPlugin")
......
...@@ -53,19 +53,6 @@ public class WarPluginActionIntegrationTests { ...@@ -53,19 +53,6 @@ public class WarPluginActionIntegrationTests {
.getOutput()).contains("bootWar exists = true"); .getOutput()).contains("bootWar exists = true");
} }
@Test
public void noBootWebSoftwareComponentWithoutJavaPluginApplied() {
assertThat(this.gradleBuild.build("componentExists", "-PcomponentName=bootWeb")
.getOutput()).contains("bootWeb exists = false");
}
@Test
public void applyingJavaPluginCreatesBootWebSoftwareComponent() {
assertThat(this.gradleBuild
.build("componentExists", "-PcomponentName=bootWeb", "-PapplyWarPlugin")
.getOutput()).contains("bootWeb exists = true");
}
@Test @Test
public void assembleRunsBootWarAndWarIsSkipped() { public void assembleRunsBootWarAndWarIsSkipped() {
BuildResult result = this.gradleBuild.build("assemble"); BuildResult result = this.gradleBuild.build("assemble");
......
...@@ -16,12 +16,6 @@ task('taskExists') { ...@@ -16,12 +16,6 @@ task('taskExists') {
} }
} }
task('componentExists') {
doFirst {
println "$componentName exists = ${components.findByName(componentName) != null}"
}
}
task('javaCompileEncoding') { task('javaCompileEncoding') {
doFirst { doFirst {
tasks.withType(JavaCompile) { tasks.withType(JavaCompile) {
......
...@@ -15,9 +15,3 @@ task('taskExists') { ...@@ -15,9 +15,3 @@ task('taskExists') {
println "$taskName exists = ${tasks.findByName(taskName) != null}" println "$taskName exists = ${tasks.findByName(taskName) != null}"
} }
} }
task('componentExists') {
doFirst {
println "$componentName exists = ${components.findByName(componentName) != null}"
}
}
...@@ -22,8 +22,8 @@ publishing { ...@@ -22,8 +22,8 @@ publishing {
} }
} }
publications { publications {
mavenBootJava(MavenPublication) { bootJava(MavenPublication) {
from components.bootJava artifact bootJar
} }
} }
} }
...@@ -22,8 +22,8 @@ publishing { ...@@ -22,8 +22,8 @@ publishing {
} }
} }
publications { publications {
mavenBootWeb(MavenPublication) { bootWeb(MavenPublication) {
from components.bootWeb artifact bootWar
} }
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment