Browse Source

Merge branch '3.2.x'

Closes gh-40643
pull/40644/head
Phillip Webb 2 years ago
parent
commit
ac9d2e7c11
  1. 8
      spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/launch/Archive.java
  2. 40
      spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/net/protocol/nested/NestedLocation.java
  3. 3
      spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/net/protocol/nested/NestedUrlConnection.java
  4. 2
      spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/net/protocol/nested/NestedLocationTests.java

8
spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/launch/Archive.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@ -20,6 +20,7 @@ import java.io.File; @@ -20,6 +20,7 @@ import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.Set;
@ -107,11 +108,10 @@ public interface Archive extends AutoCloseable { @@ -107,11 +108,10 @@ public interface Archive extends AutoCloseable {
static Archive create(ProtectionDomain protectionDomain) throws Exception {
CodeSource codeSource = protectionDomain.getCodeSource();
URI location = (codeSource != null) ? codeSource.getLocation().toURI() : null;
String path = (location != null) ? location.getSchemeSpecificPart() : null;
if (path == null) {
if (location == null) {
throw new IllegalStateException("Unable to determine code source archive");
}
return create(new File(path));
return create(Path.of(location).toFile());
}
/**

40
spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/net/protocol/nested/NestedLocation.java

@ -53,7 +53,9 @@ import org.springframework.boot.loader.net.util.UrlDecoder; @@ -53,7 +53,9 @@ import org.springframework.boot.loader.net.util.UrlDecoder;
*/
public record NestedLocation(Path path, String nestedEntryName) {
private static final Map<String, NestedLocation> cache = new ConcurrentHashMap<>();
private static final Map<String, NestedLocation> locationCache = new ConcurrentHashMap<>();
private static final Map<String, Path> pathCache = new ConcurrentHashMap<>();
public NestedLocation(Path path, String nestedEntryName) {
if (path == null) {
@ -89,35 +91,37 @@ public record NestedLocation(Path path, String nestedEntryName) { @@ -89,35 +91,37 @@ public record NestedLocation(Path path, String nestedEntryName) {
return parse(uri.getSchemeSpecificPart());
}
static NestedLocation parse(String path) {
if (path == null || path.isEmpty()) {
throw new IllegalArgumentException("'path' must not be empty");
static NestedLocation parse(String location) {
if (location == null || location.isEmpty()) {
throw new IllegalArgumentException("'location' must not be empty");
}
int index = path.lastIndexOf("/!");
return cache.computeIfAbsent(path, (l) -> create(index, l));
return locationCache.computeIfAbsent(location, (key) -> create(location));
}
private static NestedLocation create(int index, String location) {
private static NestedLocation create(String location) {
int index = location.lastIndexOf("/!");
String locationPath = (index != -1) ? location.substring(0, index) : location;
if (isWindows() && !isUncPath(location)) {
while (locationPath.startsWith("/")) {
locationPath = locationPath.substring(1, locationPath.length());
}
}
String nestedEntryName = (index != -1) ? location.substring(index + 2) : null;
return new NestedLocation((!locationPath.isEmpty()) ? Path.of(locationPath) : null, nestedEntryName);
return new NestedLocation((!locationPath.isEmpty()) ? asPath(locationPath) : null, nestedEntryName);
}
private static boolean isWindows() {
return File.separatorChar == '\\';
private static Path asPath(String locationPath) {
return pathCache.computeIfAbsent(locationPath, (key) -> {
if (isWindows() && locationPath.length() > 2 && locationPath.charAt(2) == ':') {
// Use the same logic as Java's internal WindowsUriSupport class
return Path.of(locationPath.substring(1));
}
return Path.of(locationPath);
});
}
private static boolean isUncPath(String input) {
return !input.contains(":");
private static boolean isWindows() {
return File.separatorChar == '\\';
}
static void clearCache() {
cache.clear();
locationCache.clear();
pathCache.clear();
}
}

3
spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/net/protocol/nested/NestedUrlConnection.java

@ -38,7 +38,6 @@ import java.util.List; @@ -38,7 +38,6 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.springframework.boot.loader.net.util.UrlDecoder;
import org.springframework.boot.loader.ref.Cleaner;
/**
@ -77,7 +76,7 @@ class NestedUrlConnection extends URLConnection { @@ -77,7 +76,7 @@ class NestedUrlConnection extends URLConnection {
private NestedLocation parseNestedLocation(URL url) throws MalformedURLException {
try {
return NestedLocation.parse(UrlDecoder.decode(url.getPath()));
return NestedLocation.fromUrl(url);
}
catch (IllegalArgumentException ex) {
throw new MalformedURLException(ex.getMessage());

2
spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/net/protocol/nested/NestedLocationTests.java

@ -85,7 +85,7 @@ class NestedLocationTests { @@ -85,7 +85,7 @@ class NestedLocationTests {
@Test
void fromUrlWhenNoPathThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() -> NestedLocation.fromUrl(new URL("nested:")))
.withMessageContaining("'path' must not be empty");
.withMessageContaining("'location' must not be empty");
}
@Test

Loading…
Cancel
Save