Skip to content

Commit d0708ad

Browse files
committed
Fix jar uri parsing in CloseablePath
Jar uris follow the format[1]: ``` jar:<url>!/[<entry>] ``` So splitting should be done on the last `!/` rather than the first. Fixes: #1724 for Spring Boot 3.2 and later. 1. https://docs.oracle.com/javase/8/docs/api/java/net/JarURLConnection.html
1 parent 8f5fbd0 commit d0708ad

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

junit-platform-commons/src/main/java/org/junit/platform/commons/util/CloseablePath.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ final class CloseablePath implements Closeable {
3535
private static final String FILE_URI_SCHEME = "file";
3636
static final String JAR_URI_SCHEME = "jar";
3737
private static final String JAR_FILE_EXTENSION = ".jar";
38-
private static final String JAR_URI_SEPARATOR = "!";
38+
private static final String JAR_URI_SEPARATOR = "!/";
3939

4040
private static final Closeable NULL_CLOSEABLE = () -> {
4141
};
@@ -53,9 +53,11 @@ static CloseablePath create(URI uri) throws URISyntaxException {
5353

5454
static CloseablePath create(URI uri, FileSystemProvider fileSystemProvider) throws URISyntaxException {
5555
if (JAR_URI_SCHEME.equals(uri.getScheme())) {
56-
String[] parts = uri.toString().split(JAR_URI_SEPARATOR);
57-
String jarUri = parts[0];
58-
String jarEntry = parts[1];
56+
// Parsing: jar:<url>!/[<entry>]
57+
String uriString = uri.toString();
58+
int lastJarUriSeparator = uriString.lastIndexOf(JAR_URI_SEPARATOR);
59+
String jarUri = uriString.substring(0, lastJarUriSeparator);
60+
String jarEntry = uriString.substring(lastJarUriSeparator + 1);
5961
return createForJarFileSystem(new URI(jarUri), fileSystem -> fileSystem.getPath(jarEntry),
6062
fileSystemProvider);
6163
}

platform-tests/src/test/java/org/junit/platform/commons/util/CloseablePathTests.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
import static org.mockito.Mockito.mock;
1919
import static org.mockito.Mockito.only;
2020
import static org.mockito.Mockito.verify;
21+
import static org.mockito.Mockito.verifyNoMoreInteractions;
2122
import static org.mockito.Mockito.when;
2223

2324
import java.net.URI;
25+
import java.nio.file.FileSystem;
2426
import java.nio.file.FileSystemNotFoundException;
2527
import java.nio.file.FileSystems;
2628
import java.util.ArrayList;
@@ -51,6 +53,37 @@ void closeAllPaths() {
5153
closeAll(paths);
5254
}
5355

56+
@Test
57+
void parsesJarUri() throws Exception {
58+
FileSystemProvider fileSystemProvider = mock();
59+
60+
FileSystem fileSystem = mock();
61+
when(fileSystemProvider.newFileSystem(any())).thenReturn(fileSystem);
62+
63+
URI jarFileWithEntry = URI.create("jar:file:/example.jar!/com/example/Example.class");
64+
CloseablePath.create(jarFileWithEntry, fileSystemProvider).close();
65+
66+
URI jarFileUri = URI.create("jar:file:/example.jar");
67+
verify(fileSystemProvider).newFileSystem(jarFileUri);
68+
verifyNoMoreInteractions(fileSystemProvider);
69+
}
70+
71+
@Test
72+
void parsesRecursiveJarUri() throws Exception {
73+
FileSystemProvider fileSystemProvider = mock();
74+
75+
FileSystem fileSystem = mock();
76+
when(fileSystemProvider.newFileSystem(any())).thenReturn(fileSystem);
77+
78+
URI jarNestedFileWithEntry = URI.create(
79+
"jar:nested:file:/example.jar!/BOOT-INF/classes!/com/example/Example.class");
80+
CloseablePath.create(jarNestedFileWithEntry, fileSystemProvider).close();
81+
82+
URI jarNestedFile = URI.create("jar:nested:file:/example.jar!/BOOT-INF/classes");
83+
verify(fileSystemProvider).newFileSystem(jarNestedFile);
84+
verifyNoMoreInteractions(fileSystemProvider);
85+
}
86+
5487
@Test
5588
void createsAndClosesJarFileSystemOnceWhenCalledConcurrently() throws Exception {
5689
var numThreads = 50;

0 commit comments

Comments
 (0)