Set implementation name and version in Gradle-built archives

Closes gh-34059
This commit is contained in:
Andy Wilkinson 2023-02-08 10:52:32 +00:00
parent d65f1cd704
commit 9378fc47a7
4 changed files with 66 additions and 7 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@ -54,6 +54,8 @@ class BootArchiveSupport {
private static final byte[] ZIP_FILE_HEADER = new byte[] { 'P', 'K', 3, 4 };
private static final String UNSPECIFIED_VERSION = "unspecified";
private static final Set<String> DEFAULT_LAUNCHER_CLASSES;
static {
@ -85,7 +87,7 @@ class BootArchiveSupport {
}
void configureManifest(Manifest manifest, String mainClass, String classes, String lib, String classPathIndex,
String layersIndex, String jdkVersion) {
String layersIndex, String jdkVersion, String implementationName, Object implementationVersion) {
Attributes attributes = manifest.getAttributes();
attributes.putIfAbsent("Main-Class", this.loaderMainClass);
attributes.putIfAbsent("Start-Class", mainClass);
@ -99,6 +101,13 @@ class BootArchiveSupport {
attributes.putIfAbsent("Spring-Boot-Layers-Index", layersIndex);
}
attributes.putIfAbsent("Build-Jdk-Spec", jdkVersion);
attributes.putIfAbsent("Implementation-Name", implementationName);
if (implementationVersion != null) {
String versionString = implementationVersion.toString();
if (!UNSPECIFIED_VERSION.equals(versionString)) {
attributes.putIfAbsent("Implementation-Version", versionString);
}
}
}
private String determineSpringBootVersion() {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@ -29,6 +29,7 @@ import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileCopyDetails;
import org.gradle.api.file.FileTreeElement;
import org.gradle.api.internal.file.copy.CopyAction;
import org.gradle.api.provider.Provider;
import org.gradle.api.specs.Spec;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.Nested;
@ -65,6 +66,10 @@ public abstract class BootJar extends Jar implements BootArchive {
private final LayeredSpec layered;
private final Provider<String> projectName;
private final Provider<Object> projectVersion;
private FileCollection classpath;
/**
@ -85,6 +90,8 @@ public abstract class BootJar extends Jar implements BootArchive {
}
});
});
this.projectName = project.provider(project::getName);
this.projectVersion = project.provider(project::getVersion);
}
private void configureBootInfSpec(CopySpec bootInfSpec) {
@ -120,7 +127,7 @@ public abstract class BootJar extends Jar implements BootArchive {
public void copy() {
this.support.configureManifest(getManifest(), getMainClass().get(), CLASSES_DIRECTORY, LIB_DIRECTORY,
CLASSPATH_INDEX, (isLayeredDisabled()) ? null : LAYERS_INDEX,
this.getTargetJavaVersion().get().getMajorVersion());
this.getTargetJavaVersion().get().getMajorVersion(), this.projectName.get(), this.projectVersion.get());
super.copy();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@ -28,6 +28,7 @@ import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileCopyDetails;
import org.gradle.api.file.FileTreeElement;
import org.gradle.api.internal.file.copy.CopyAction;
import org.gradle.api.provider.Provider;
import org.gradle.api.specs.Spec;
import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.Internal;
@ -65,6 +66,10 @@ public abstract class BootWar extends War implements BootArchive {
private final LayeredSpec layered;
private final Provider<String> projectName;
private final Provider<Object> projectVersion;
private FileCollection providedClasspath;
/**
@ -85,6 +90,8 @@ public abstract class BootWar extends War implements BootArchive {
}
});
});
this.projectName = project.provider(project::getName);
this.projectVersion = project.provider(project::getVersion);
}
private Object getProvidedLibFiles() {
@ -95,7 +102,7 @@ public abstract class BootWar extends War implements BootArchive {
public void copy() {
this.support.configureManifest(getManifest(), getMainClass().get(), CLASSES_DIRECTORY, LIB_DIRECTORY,
CLASSPATH_INDEX, (isLayeredDisabled()) ? null : LAYERS_INDEX,
this.getTargetJavaVersion().get().getMajorVersion());
this.getTargetJavaVersion().get().getMajorVersion(), this.projectName.get(), this.projectVersion.get());
super.copy();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@ -132,6 +132,42 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
.isEqualTo(this.classesPath);
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Lib")).isEqualTo(this.libPath);
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Version")).isNotNull();
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Name"))
.isEqualTo(this.project.getName());
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Version")).isNull();
}
}
@Test
void whenImplementationNameIsCustomizedItShouldAppearInArchiveManifest() throws IOException {
this.task.getMainClass().set("com.example.Main");
this.task.getManifest().getAttributes().put("Implementation-Name", "Customized");
executeTask();
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Name"))
.isEqualTo("Customized");
}
}
@Test
void whenProjectVersionIsSetThenImplementationVersionShouldAppearInArchiveManifest() throws IOException {
this.project.setVersion("1.0.0");
this.task.getMainClass().set("com.example.Main");
executeTask();
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Version")).isEqualTo("1.0.0");
}
}
@Test
void whenImplementationVersionIsCustomizedItShouldAppearInArchiveManifest() throws IOException {
this.project.setVersion("1.0.0");
this.task.getMainClass().set("com.example.Main");
this.task.getManifest().getAttributes().put("Implementation-Version", "Customized");
executeTask();
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Version"))
.isEqualTo("Customized");
}
}