Skip to content

Commit 3a6fe98

Browse files
committed
Merge pull request spring-projects#16182 from Hendrig Sellik
* spring-projectsgh-16182: Polish "Determine Spring Boot version correctly when using module path" Determine Spring Boot version correctly when using module path Closes spring-projectsgh-16182
2 parents 47d42cb + 15f28dc commit 3a6fe98

File tree

1 file changed

+49
-9
lines changed

1 file changed

+49
-9
lines changed

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

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2018 the original author or authors.
2+
* Copyright 2012-2019 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.
@@ -16,16 +16,29 @@
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.Attributes.Name;
26+
import java.util.jar.JarFile;
27+
1928
/**
20-
* Class that exposes the Spring Boot version. Fetches the "Implementation-Version"
21-
* manifest attribute from the jar file.
29+
* Class that exposes the Spring Boot version. Fetches the
30+
* {@link Name#IMPLEMENTATION_VERSION Implementation-Version} manifest attribute from the
31+
* jar file via {@link Package#getImplementationVersion()}, falling back to locating the
32+
* jar file that contains this class and reading the {@code Implementation-Version}
33+
* attribute from its manifest.
2234
* <p>
23-
* Note that some ClassLoaders do not expose the package metadata, hence this class might
24-
* not be able to determine the Spring Boot version in all environments. Consider using a
25-
* reflection-based check instead: For example, checking for the presence of a specific
26-
* Spring Boot method that you intend to call.
35+
* This class might not be able to determine the Spring Boot version in all environments.
36+
* Consider using a reflection-based check instead: For example, checking for the presence
37+
* of a specific Spring Boot method that you intend to call.
2738
*
2839
* @author Drummond Dawson
40+
* @author Hendrig Sellik
41+
* @author Andy Wilkinson
2942
* @since 1.3.0
3043
*/
3144
public final class SpringBootVersion {
@@ -40,8 +53,35 @@ private SpringBootVersion() {
4053
* @see Package#getImplementationVersion()
4154
*/
4255
public static String getVersion() {
43-
Package pkg = SpringBootVersion.class.getPackage();
44-
return (pkg != null) ? pkg.getImplementationVersion() : null;
56+
return determineSpringBootVersion();
57+
}
58+
59+
private static String determineSpringBootVersion() {
60+
String implementationVersion = SpringBootVersion.class.getPackage()
61+
.getImplementationVersion();
62+
if (implementationVersion != null) {
63+
return implementationVersion;
64+
}
65+
URL codeSourceLocation = SpringBootVersion.class.getProtectionDomain()
66+
.getCodeSource().getLocation();
67+
try {
68+
URLConnection connection = codeSourceLocation.openConnection();
69+
if (connection instanceof JarURLConnection) {
70+
return getImplementationVersion(
71+
((JarURLConnection) connection).getJarFile());
72+
}
73+
try (JarFile jarFile = new JarFile(new File(codeSourceLocation.toURI()))) {
74+
return getImplementationVersion(jarFile);
75+
}
76+
}
77+
catch (Exception ex) {
78+
return null;
79+
}
80+
}
81+
82+
private static String getImplementationVersion(JarFile jarFile) throws IOException {
83+
return jarFile.getManifest().getMainAttributes()
84+
.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
4585
}
4686

4787
}

0 commit comments

Comments
 (0)