Skip to content

Commit 73f4ef2

Browse files
authored
Merge pull request #470 from nebula-plugins/NEBULA-3609
NEBULA-3609 document the code paths for spring boot 1 and 3 better
2 parents a24c740 + ae798df commit 73f4ef2

File tree

5 files changed

+108
-70
lines changed

5 files changed

+108
-70
lines changed

build.gradle

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import org.gradle.api.attributes.plugin.GradlePluginApiVersion
2+
13
/*
24
* Copyright 2014-2019 Netflix, Inc.
35
*
@@ -66,6 +68,20 @@ tasks.withType(Javadoc) {
6668
options.links(javaApiUrl, groovyApiUrl)
6769
}
6870

71+
java {
72+
toolchain {
73+
languageVersion = JavaLanguageVersion.of(17)
74+
}
75+
}
76+
77+
configurations.named("runtimeClasspath") {
78+
attributes {
79+
attribute(
80+
GradlePluginApiVersion.GRADLE_PLUGIN_API_VERSION_ATTRIBUTE as Attribute<GradlePluginApiVersion>,
81+
objects.named(GradlePluginApiVersion, "8.6") as GradlePluginApiVersion)
82+
}
83+
}
84+
6985
gradlePlugin {
7086
plugins {
7187
ospackage {

settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
plugins {
22
id 'com.gradle.develocity' version '3.19'
3+
id("org.gradle.toolchains.foojay-resolver-convention") version("1.0.0")
34
}
45

56
develocity {

src/main/groovy/com/netflix/gradle/plugins/application/OspackageApplicationSpringBootPlugin.groovy

Lines changed: 71 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import org.gradle.api.Project
2323
import org.gradle.api.distribution.plugins.DistributionPlugin
2424
import org.gradle.api.plugins.ApplicationPlugin
2525
import org.gradle.api.plugins.JavaPlugin
26-
import org.gradle.api.tasks.TaskProvider
2726
import org.gradle.api.tasks.application.CreateStartScripts
2827
import org.gradle.util.GradleVersion
2928

@@ -54,85 +53,95 @@ class OspackageApplicationSpringBootPlugin implements Plugin<Project> {
5453
void apply(Project project) {
5554
project.plugins.apply(OspackageApplicationPlugin)
5655

57-
if (!project.plugins.hasPlugin('org.springframework.boot')) {
58-
throw new IllegalStateException("The 'org.springframework.boot' plugin must be applied before applying this plugin")
56+
project.afterEvaluate {
57+
if (!project.plugins.hasPlugin('org.springframework.boot')) {
58+
project.logger.error("The '{}' plugin requires the '{}' plugin.",
59+
"com.netflix.nebula.ospackage-application-spring-boot",
60+
"org.springframework.boot")
61+
throw new RuntimeException("The 'com.netflix.nebula.ospackage-application-spring-boot' plugin requires the 'org.springframework.boot' plugin.")
62+
}
5963
}
6064

61-
// Spring Boot 2.0 configured distributions that have everything we need
62-
if (project.distributions.findByName('boot') != null) {
63-
// Use the main distribution and configure it to have the same baseName as the boot distribution
64-
project.tasks.named(JavaPlugin.JAR_TASK_NAME) {
65-
enabled = true
66-
}
67-
project.afterEvaluate {
68-
project.tasks.named('bootJar').configure {
69-
if (GradleVersion.current().baseVersion < GradleVersion.version('6.0').baseVersion) {
70-
classifier = 'boot'
71-
} else {
72-
archiveClassifier = 'boot'
73-
}
65+
project.plugins.withId("org.springframework.boot") {
66+
// Spring Boot 2.0+ configured distributions that have everything we need
67+
if (project.distributions.findByName('boot') != null) {
68+
project.logger.info("Spring Boot 2+ detected")
69+
// Use the main distribution and configure it to have the same baseName as the boot distribution
70+
project.tasks.named(JavaPlugin.JAR_TASK_NAME) {
71+
enabled = true
7472
}
75-
project.distributions {
76-
main {
73+
project.afterEvaluate {
74+
project.tasks.named('bootJar').configure {
7775
if (GradleVersion.current().baseVersion < GradleVersion.version('6.0').baseVersion) {
78-
baseName = "${project.distributions.main.baseName}-boot"
76+
classifier = 'boot'
7977
} else {
80-
getDistributionBaseName().set "${project.distributions.main.getDistributionBaseName().getOrNull()}-boot"
78+
archiveClassifier = 'boot'
79+
}
80+
}
81+
project.distributions {
82+
main {
83+
if (GradleVersion.current().baseVersion < GradleVersion.version('6.0').baseVersion) {
84+
baseName = "${project.distributions.main.baseName}-boot"
85+
} else {
86+
getDistributionBaseName().set "${project.distributions.main.getDistributionBaseName().getOrNull()}-boot"
87+
}
8188
}
8289
}
83-
}
8490

85-
// Allow the springBoot extension configuration to propagate to the application plugin
86-
def mainClass = project.objects.property(String)
87-
try {
88-
mainClass.set(project.springBoot.mainClass)
89-
} catch (Exception ignore) {
90-
mainClass.set(project.springBoot.mainClassName)
91-
}
92-
if (!mainClass.isPresent()) {
91+
// Allow the springBoot extension configuration to propagate to the application plugin
92+
def mainClass = project.objects.property(String)
9393
try {
94-
mainClass.set(project.application.mainClass.isPresent() ? project.application.mainClass.get() : project.application.mainClassName)
94+
mainClass.set(project.springBoot.mainClass)
9595
} catch (Exception ignore) {
96+
mainClass.set(project.springBoot.mainClassName)
9697
}
97-
}
98-
if (GradleVersion.current().baseVersion < GradleVersion.version('6.4').baseVersion) {
99-
if (project.application.mainClassName == null) {
100-
project.application.mainClassName = mainClass.getOrNull() // Fail only when startScripts runs
98+
if (!mainClass.isPresent()) {
99+
try {
100+
mainClass.set(project.application.mainClass.isPresent() ? project.application.mainClass.get() : project.application.mainClassName)
101+
} catch (Exception ignore) {
102+
}
103+
}
104+
if (GradleVersion.current().baseVersion < GradleVersion.version('6.4').baseVersion) {
105+
if (project.application.mainClassName == null) {
106+
project.application.mainClassName = mainClass.getOrNull()
107+
// Fail only when startScripts runs
108+
}
109+
} else {
110+
project.application.mainClass.convention(mainClass)
101111
}
102-
} else {
103-
project.application.mainClass.convention(mainClass)
104112
}
105-
}
106113

107-
// Workaround for https://github.com/gradle/gradle/issues/16371
108-
if (GradleVersion.current().baseVersion >= GradleVersion.version('6.4').baseVersion) {
109-
project.tasks.named(ApplicationPlugin.TASK_START_SCRIPTS_NAME).configure {
110-
doFirst {
111-
if (!project.application.mainClass.isPresent()) {
112-
throw new GradleException("mainClass should be configured in order to generate a valid start script. i.e. mainClass = 'com.netflix.app.MyApp'")
114+
// Workaround for https://github.com/gradle/gradle/issues/16371
115+
if (GradleVersion.current().baseVersion >= GradleVersion.version('6.4').baseVersion) {
116+
project.tasks.named(ApplicationPlugin.TASK_START_SCRIPTS_NAME).configure {
117+
doFirst {
118+
if (!project.application.mainClass.isPresent()) {
119+
throw new GradleException("mainClass should be configured in order to generate a valid start script. i.e. mainClass = 'com.netflix.app.MyApp'")
120+
}
113121
}
114122
}
115123
}
116-
}
117-
} else {
118-
project.afterEvaluate {
119-
project.tasks.named(DistributionPlugin.TASK_INSTALL_NAME).configure {
120-
it.dependsOn('bootRepackage')
121-
}
122-
project.tasks.named(ApplicationPlugin.TASK_START_SCRIPTS_NAME).configure { CreateStartScripts createStartScripts ->
123-
createStartScripts.mainClassName = 'org.springframework.boot.loader.JarLauncher'
124-
}
124+
} else {
125+
project.logger.info("Spring Boot 1 detected")
126+
project.afterEvaluate {
127+
project.tasks.named(DistributionPlugin.TASK_INSTALL_NAME).configure {
128+
it.dependsOn('bootRepackage')
129+
}
130+
project.tasks.named(ApplicationPlugin.TASK_START_SCRIPTS_NAME).configure { CreateStartScripts createStartScripts ->
131+
createStartScripts.mainClassName = 'org.springframework.boot.loader.JarLauncher'
132+
}
125133

126-
// `ApplicationPlugin` automatically adds `runtimeClasspath` files to the distribution. We want most of that
127-
// stripped out since we want just the fat jar that Spring produces.
128-
project.distributions {
129-
main {
130-
contents {
131-
into('lib') {
132-
project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME).files.findAll { file ->
133-
file.getName() != project.tasks.getByName(JavaPlugin.JAR_TASK_NAME).outputs.files.singleFile.name
134-
}.each { file ->
135-
exclude file.name
134+
// `ApplicationPlugin` automatically adds `runtimeClasspath` files to the distribution. We want most of that
135+
// stripped out since we want just the fat jar that Spring produces.
136+
project.distributions {
137+
main {
138+
contents {
139+
into('lib') {
140+
project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME).files.findAll { file ->
141+
file.getName() != project.tasks.getByName(JavaPlugin.JAR_TASK_NAME).outputs.files.singleFile.name
142+
}.each { file ->
143+
exclude file.name
144+
}
136145
}
137146
}
138147
}
@@ -141,5 +150,4 @@ class OspackageApplicationSpringBootPlugin implements Plugin<Project> {
141150
}
142151
}
143152
}
144-
145153
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.netflix.gradle.plugins
2+
3+
class SupportedGradleVersions {
4+
public static String GRADLE_MIN = "8.6"
5+
public static String GRADLE_MAX = "9.0.0-rc-4"
6+
public static List<String> ALL = [GRADLE_MIN, GRADLE_MAX]
7+
}

src/test/groovy/com/netflix/gradle/plugins/application/OspackageApplicationSpringBootPluginLauncherSpec.groovy

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
package com.netflix.gradle.plugins.application
1818

1919
import com.netflix.gradle.plugins.BaseIntegrationTestKitSpec
20+
import com.netflix.gradle.plugins.SupportedGradleVersions
2021
import com.netflix.gradle.plugins.deb.Scanner
2122
import org.junit.Rule
2223
import org.junit.contrib.java.lang.system.ProvideSystemProperty
2324
import spock.lang.Unroll
24-
import spock.lang.IgnoreIf
2525

2626
import java.util.jar.JarFile
2727

@@ -30,7 +30,8 @@ class OspackageApplicationSpringBootPluginLauncherSpec extends BaseIntegrationTe
3030
public final ProvideSystemProperty ignoreDeprecations = new ProvideSystemProperty("ignoreDeprecations", "true")
3131

3232
def setup() {
33-
disableConfigurationCache() // org.gradle.api.tasks.application.CreateStartScript does not support config cache and it is used in Spring Boot plugin in these tests
33+
disableConfigurationCache()
34+
// org.gradle.api.tasks.application.CreateStartScript does not support config cache and it is used in Spring Boot plugin in these tests
3435
}
3536

3637
def 'plugin throws exception if spring-boot plugin not applied'() {
@@ -44,7 +45,7 @@ class OspackageApplicationSpringBootPluginLauncherSpec extends BaseIntegrationTe
4445
def result = runTasksAndFail("help")
4546

4647
then:
47-
result.output.contains("The 'org.springframework.boot' plugin must be applied before applying this plugin")
48+
result.output.contains("The 'com.netflix.nebula.ospackage-application-spring-boot' plugin requires the 'org.springframework.boot' plugin.")
4849
}
4950

5051
String buildScript(String bootVersion, File startScript) {
@@ -90,13 +91,15 @@ class OspackageApplicationSpringBootPluginLauncherSpec extends BaseIntegrationTe
9091
}
9192

9293
@Unroll
93-
def 'application shows up in deb for boot #bootVersion'() {
94+
def 'application shows up in deb for boot #bootVersion and gradle #testGradleVersion'() {
9495
final applicationDir = "$moduleName-boot"
9596
final startScript = "./opt/${applicationDir}/bin/${moduleName}"
9697
buildFile << buildScript(bootVersion, null)
9798

9899
when:
99-
runTasks('build', 'buildDeb')
100+
forwardOutput = true
101+
gradleVersion = testGradleVersion
102+
runTasks('build', 'buildDeb', "--stacktrace")
100103

101104
then:
102105
final archivePath = file("build/distributions/test_0_all.deb")
@@ -119,8 +122,10 @@ class OspackageApplicationSpringBootPluginLauncherSpec extends BaseIntegrationTe
119122
!scanner.controlContents.containsKey('./postinst')
120123

121124
where:
122-
bootVersion | moduleSuffix
123-
'3.5.2' | '-plain'
125+
bootVersion | testGradleVersion | moduleSuffix
126+
'3.5.2' | SupportedGradleVersions.GRADLE_MAX | '-plain'
127+
'3.5.2' | SupportedGradleVersions.GRADLE_MIN | '-plain'
128+
'2.7.18' | SupportedGradleVersions.GRADLE_MIN | '-plain'
124129
}
125130

126131
private boolean isBootJar(JarFile jarFile) {
@@ -137,6 +142,7 @@ class OspackageApplicationSpringBootPluginLauncherSpec extends BaseIntegrationTe
137142
buildFile << buildScript(bootVersion, startScript)
138143

139144
when:
145+
forwardOutput = true
140146
def result = runTasks('runStartScript')
141147

142148
then:

0 commit comments

Comments
 (0)