Skip to content

Commit ec8fb61

Browse files
hsellikwilkinsona
authored andcommitted
Determine Spring Boot version correctly when using module path
In Java 9, a package may return null for its implementation version even when the manifest attribute specifying the version is present in the jar from which the package was loaded. This commit updates SpringBootVersion to fall back to accessing the jar and its manifest attributes directly when the implementation version of its package is null. See gh-16182
1 parent 47d42cb commit ec8fb61

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringBootVersion.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@
1616

1717
package org.springframework.boot;
1818

19+
import java.io.File;
20+
import java.io.IOException;
21+
import java.net.JarURLConnection;
22+
import java.net.URL;
23+
import java.net.URLConnection;
24+
import java.util.jar.Attributes;
25+
import java.util.jar.JarFile;
26+
1927
/**
2028
* Class that exposes the Spring Boot version. Fetches the "Implementation-Version"
2129
* manifest attribute from the jar file.
@@ -40,8 +48,35 @@ private SpringBootVersion() {
4048
* @see Package#getImplementationVersion()
4149
*/
4250
public static String getVersion() {
43-
Package pkg = SpringBootVersion.class.getPackage();
44-
return (pkg != null) ? pkg.getImplementationVersion() : null;
51+
return determineSpringBootVersion();
52+
}
53+
54+
private static String determineSpringBootVersion() {
55+
String implementationVersion = SpringBootVersion.class.getPackage()
56+
.getImplementationVersion();
57+
if (implementationVersion != null) {
58+
return implementationVersion;
59+
}
60+
URL codeSourceLocation = SpringBootVersion.class.getProtectionDomain()
61+
.getCodeSource().getLocation();
62+
try {
63+
URLConnection connection = codeSourceLocation.openConnection();
64+
if (connection instanceof JarURLConnection) {
65+
return getImplementationVersion(
66+
((JarURLConnection) connection).getJarFile());
67+
}
68+
try (JarFile jarFile = new JarFile(new File(codeSourceLocation.toURI()))) {
69+
return getImplementationVersion(jarFile);
70+
}
71+
}
72+
catch (Exception ex) {
73+
return null;
74+
}
75+
}
76+
77+
private static String getImplementationVersion(JarFile jarFile) throws IOException {
78+
return jarFile.getManifest().getMainAttributes()
79+
.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
4580
}
4681

4782
}

0 commit comments

Comments
 (0)