Skip to content

Commit 9378fc4

Browse files
committed
Set implementation name and version in Gradle-built archives
Closes gh-34059
1 parent d65f1cd commit 9378fc4

File tree

4 files changed

+66
-7
lines changed

4 files changed

+66
-7
lines changed

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootArchiveSupport.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -54,6 +54,8 @@ class BootArchiveSupport {
5454

5555
private static final byte[] ZIP_FILE_HEADER = new byte[] { 'P', 'K', 3, 4 };
5656

57+
private static final String UNSPECIFIED_VERSION = "unspecified";
58+
5759
private static final Set<String> DEFAULT_LAUNCHER_CLASSES;
5860

5961
static {
@@ -85,7 +87,7 @@ class BootArchiveSupport {
8587
}
8688

8789
void configureManifest(Manifest manifest, String mainClass, String classes, String lib, String classPathIndex,
88-
String layersIndex, String jdkVersion) {
90+
String layersIndex, String jdkVersion, String implementationName, Object implementationVersion) {
8991
Attributes attributes = manifest.getAttributes();
9092
attributes.putIfAbsent("Main-Class", this.loaderMainClass);
9193
attributes.putIfAbsent("Start-Class", mainClass);
@@ -99,6 +101,13 @@ void configureManifest(Manifest manifest, String mainClass, String classes, Stri
99101
attributes.putIfAbsent("Spring-Boot-Layers-Index", layersIndex);
100102
}
101103
attributes.putIfAbsent("Build-Jdk-Spec", jdkVersion);
104+
attributes.putIfAbsent("Implementation-Name", implementationName);
105+
if (implementationVersion != null) {
106+
String versionString = implementationVersion.toString();
107+
if (!UNSPECIFIED_VERSION.equals(versionString)) {
108+
attributes.putIfAbsent("Implementation-Version", versionString);
109+
}
110+
}
102111
}
103112

104113
private String determineSpringBootVersion() {

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@
2929
import org.gradle.api.file.FileCopyDetails;
3030
import org.gradle.api.file.FileTreeElement;
3131
import org.gradle.api.internal.file.copy.CopyAction;
32+
import org.gradle.api.provider.Provider;
3233
import org.gradle.api.specs.Spec;
3334
import org.gradle.api.tasks.Internal;
3435
import org.gradle.api.tasks.Nested;
@@ -65,6 +66,10 @@ public abstract class BootJar extends Jar implements BootArchive {
6566

6667
private final LayeredSpec layered;
6768

69+
private final Provider<String> projectName;
70+
71+
private final Provider<Object> projectVersion;
72+
6873
private FileCollection classpath;
6974

7075
/**
@@ -85,6 +90,8 @@ public BootJar() {
8590
}
8691
});
8792
});
93+
this.projectName = project.provider(project::getName);
94+
this.projectVersion = project.provider(project::getVersion);
8895
}
8996

9097
private void configureBootInfSpec(CopySpec bootInfSpec) {
@@ -120,7 +127,7 @@ private void moveMetaInfToRoot(CopySpec spec) {
120127
public void copy() {
121128
this.support.configureManifest(getManifest(), getMainClass().get(), CLASSES_DIRECTORY, LIB_DIRECTORY,
122129
CLASSPATH_INDEX, (isLayeredDisabled()) ? null : LAYERS_INDEX,
123-
this.getTargetJavaVersion().get().getMajorVersion());
130+
this.getTargetJavaVersion().get().getMajorVersion(), this.projectName.get(), this.projectVersion.get());
124131
super.copy();
125132
}
126133

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootWar.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@
2828
import org.gradle.api.file.FileCopyDetails;
2929
import org.gradle.api.file.FileTreeElement;
3030
import org.gradle.api.internal.file.copy.CopyAction;
31+
import org.gradle.api.provider.Provider;
3132
import org.gradle.api.specs.Spec;
3233
import org.gradle.api.tasks.Classpath;
3334
import org.gradle.api.tasks.Internal;
@@ -65,6 +66,10 @@ public abstract class BootWar extends War implements BootArchive {
6566

6667
private final LayeredSpec layered;
6768

69+
private final Provider<String> projectName;
70+
71+
private final Provider<Object> projectVersion;
72+
6873
private FileCollection providedClasspath;
6974

7075
/**
@@ -85,6 +90,8 @@ public BootWar() {
8590
}
8691
});
8792
});
93+
this.projectName = project.provider(project::getName);
94+
this.projectVersion = project.provider(project::getVersion);
8895
}
8996

9097
private Object getProvidedLibFiles() {
@@ -95,7 +102,7 @@ private Object getProvidedLibFiles() {
95102
public void copy() {
96103
this.support.configureManifest(getManifest(), getMainClass().get(), CLASSES_DIRECTORY, LIB_DIRECTORY,
97104
CLASSPATH_INDEX, (isLayeredDisabled()) ? null : LAYERS_INDEX,
98-
this.getTargetJavaVersion().get().getMajorVersion());
105+
this.getTargetJavaVersion().get().getMajorVersion(), this.projectName.get(), this.projectVersion.get());
99106
super.copy();
100107
}
101108

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveTests.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -132,6 +132,42 @@ void basicArchiveCreation() throws IOException {
132132
.isEqualTo(this.classesPath);
133133
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Lib")).isEqualTo(this.libPath);
134134
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Version")).isNotNull();
135+
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Name"))
136+
.isEqualTo(this.project.getName());
137+
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Version")).isNull();
138+
}
139+
}
140+
141+
@Test
142+
void whenImplementationNameIsCustomizedItShouldAppearInArchiveManifest() throws IOException {
143+
this.task.getMainClass().set("com.example.Main");
144+
this.task.getManifest().getAttributes().put("Implementation-Name", "Customized");
145+
executeTask();
146+
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
147+
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Name"))
148+
.isEqualTo("Customized");
149+
}
150+
}
151+
152+
@Test
153+
void whenProjectVersionIsSetThenImplementationVersionShouldAppearInArchiveManifest() throws IOException {
154+
this.project.setVersion("1.0.0");
155+
this.task.getMainClass().set("com.example.Main");
156+
executeTask();
157+
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
158+
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Version")).isEqualTo("1.0.0");
159+
}
160+
}
161+
162+
@Test
163+
void whenImplementationVersionIsCustomizedItShouldAppearInArchiveManifest() throws IOException {
164+
this.project.setVersion("1.0.0");
165+
this.task.getMainClass().set("com.example.Main");
166+
this.task.getManifest().getAttributes().put("Implementation-Version", "Customized");
167+
executeTask();
168+
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
169+
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Version"))
170+
.isEqualTo("Customized");
135171
}
136172
}
137173

0 commit comments

Comments
 (0)