Skip to content

Commit

Permalink
Fix parsing of recursive JAR URIs in CloseablePath (#3606)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mpkorstanje authored Feb 25, 2024
1 parent 0fb3e19 commit 3923fd7
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ repository on GitHub.
==== Bug Fixes

* `ReflectionSupport.findFields(...)` now returns a distinct set of fields.
* Fixed parsing of recursive jar uris. Allows the JUnit Platform Launcher to be used
inside Spring Boot executable jars for Spring Boot 3.2 and later.

[[release-notes-5.11.0-M1-junit-platform-deprecations-and-breaking-changes]]
==== Deprecations and Breaking Changes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ final class CloseablePath implements Closeable {
private static final String FILE_URI_SCHEME = "file";
static final String JAR_URI_SCHEME = "jar";
private static final String JAR_FILE_EXTENSION = ".jar";
private static final String JAR_URI_SEPARATOR = "!";
private static final String JAR_URI_SEPARATOR = "!/";

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

static CloseablePath create(URI uri, FileSystemProvider fileSystemProvider) throws URISyntaxException {
if (JAR_URI_SCHEME.equals(uri.getScheme())) {
String[] parts = uri.toString().split(JAR_URI_SEPARATOR);
String jarUri = parts[0];
String jarEntry = parts[1];
// Parsing: jar:<url>!/[<entry>], see java.net.JarURLConnection
String uriString = uri.toString();
int lastJarUriSeparator = uriString.lastIndexOf(JAR_URI_SEPARATOR);
String jarUri = uriString.substring(0, lastJarUriSeparator);
String jarEntry = uriString.substring(lastJarUriSeparator + 1);
return createForJarFileSystem(new URI(jarUri), fileSystem -> fileSystem.getPath(jarEntry),
fileSystemProvider);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.only;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.FileSystems;
import java.util.ArrayList;
Expand Down Expand Up @@ -51,6 +53,37 @@ void closeAllPaths() {
closeAll(paths);
}

@Test
void parsesJarUri() throws Exception {
FileSystemProvider fileSystemProvider = mock();

FileSystem fileSystem = mock();
when(fileSystemProvider.newFileSystem(any())).thenReturn(fileSystem);

URI jarFileWithEntry = URI.create("jar:file:/example.jar!/com/example/Example.class");
CloseablePath.create(jarFileWithEntry, fileSystemProvider).close();

URI jarFileUri = URI.create("jar:file:/example.jar");
verify(fileSystemProvider).newFileSystem(jarFileUri);
verifyNoMoreInteractions(fileSystemProvider);
}

@Test
void parsesRecursiveJarUri() throws Exception {
FileSystemProvider fileSystemProvider = mock();

FileSystem fileSystem = mock();
when(fileSystemProvider.newFileSystem(any())).thenReturn(fileSystem);

URI jarNestedFileWithEntry = URI.create(
"jar:nested:file:/example.jar!/BOOT-INF/classes!/com/example/Example.class");
CloseablePath.create(jarNestedFileWithEntry, fileSystemProvider).close();

URI jarNestedFile = URI.create("jar:nested:file:/example.jar!/BOOT-INF/classes");
verify(fileSystemProvider).newFileSystem(jarNestedFile);
verifyNoMoreInteractions(fileSystemProvider);
}

@Test
void createsAndClosesJarFileSystemOnceWhenCalledConcurrently() throws Exception {
var numThreads = 50;
Expand Down

0 comments on commit 3923fd7

Please sign in to comment.