Fix regression in `JarUrlConnection` where a NullPointerException could
be thrown internally causing performance issues.
When the SecurityManager is present, the following stack trace is
thrown:
java.lang.NullPointerException: Cannot invoke "java.net.URLConnection.getPermission()" because "this.jarFileConnection" is null
at org.springframework.boot.loader.net.protocol.jar.JarUrlConnection.getPermission(JarUrlConnection.java:175)
at java.base/jdk.internal.loader.URLClassPath.check(URLClassPath.java:553)
at java.base/jdk.internal.loader.URLClassPath$Loader.findResource(URLClassPath.java:612)
at java.base/jdk.internal.loader.URLClassPath.findResource(URLClassPath.java:296)
at java.base/java.net.URLClassLoader$2.run(URLClassLoader.java:629)
at java.base/java.net.URLClassLoader$2.run(URLClassLoader.java:627)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.net.URLClassLoader.findResource(URLClassLoader.java:626)
at org.springframework.boot.loader.net.protocol.jar.JarUrlClassLoader.findResource(JarUrlClassLoader.java:70)
at java.base/java.lang.ClassLoader.getResource(ClassLoader.java:1403)
at java.base/java.net.URLClassLoader.getResourceAsStream(URLClassLoader.java:290)
at java.base/java.lang.Class.getResourceAsStream(Class.java:2850)
See gh-39856
Update buildpack support to allow gzip compressed image layers to be
used when returned by the Docker engine. This update is restores
buildpack support when using Docker Desktop with the "Use containerd
for pulling and storing images" option enabled.
This commit introduces a new `ExportedImageTar` class to deal with the
intricacies of determining the mimetype of a layer. The class deals with
the parsing of `index.json' and related manifest blobs in order to
obtain layer information. The legacy `manifest.json` format is also
supported should `index.json` be missing.
Tests have been added to ensure that export archives from Docker Engine,
Docker Desktop (with and without containerd), and Podman can be used.
Fixes gh-40100
Co-authored-by: Moritz Halbritter <moritz.halbritter@broadcom.com>
Co-authored-by: Scott Frederick <scott.frederick@broadcom.com>
Refine the fix for gh-38611 so that `ClosedByInterruptException` no
longer retries in a loop.
Our previous fix was flawed due to the fact that another interrupt
could occur after we clear the first and whilst we are reading data.
If this happens 10 times in a row, we raise an exception and end up
causing NoClassDefFoundError errors.
Our new approach retains the use of `FileChannel` and a direct buffer
up to the point that a `ClosedByInterruptException` is raised or the
thread is detected as interrupted. At that point, we temporarily
switch to using a `RandomAccessFile` to access the data. This will
block the thread until the data has been read.
Fixes gh-40096
Rename the internal `FileChannelDataBlock` to `FileDataBlock` since we
want to fallback to a `RandomAccessFile` when a thread is interrupted.
See gh-40096
URL can contains empty spaced encoded as %20, so it should be decoded
before passing it to NestedLocation. NestedLocation expects file system
path which should not contain URL encoded values.
See gh-39675
Update the regular expression used to parse Docker images references to
prevent catastrophic backtracking when images names are long and the
tag contains an illegal character.
See gh-39617
The logic to extract layers from a downloaded Docker image assumed that
the layer entries in the image tar archive always had the file extension
`.tar`. This was the case with Docker and other compatible daemons until
Docker 25.0. With this commit, the extension is no longer assumed, but
any entries listed in `manifest.json` will be recognized.
Fixes gh-39323
Update `NestedJarFile` so that the `getManifest()` method returns the
manifest from the parent jar file for nested jars based on directory
entries.
This restores the previous behavior supported by Spring Boot 3.1 and
allows class methods such as `getPackage().getImplementationVersion()`
to return non `null` results.
Fixes gh-38996
Update `ZipContent` so that `META-INF` entries are no longer duplicated
in nested jars created from directory entries. This aligns with the
behavior of the classic loader and prevents the same META-INF file from
being discovered twice.
Fixes gh-38862
Update `JarFileArchive` so that unpacked jars use `file:` URLs rather
than `jar:file:`. This aligns with the behavior of Spring Boot 3.1 and
allows calls to `class.getSigners()` to work again.
Fixes gh-38833
1. remove unused imports
2. remove redundant semicolon
3. remove empty class body
4. remove redundant 'constructor' keyword
5. remove redundant 'Unit' return type
6. use non-null type if possible
See gh-38708
In gh-38154, we started handling ClosedByInterruptException. The
FileChannel was repaired by recreating it and then the exception was
rethrown. This allowed other threads to use the channel that had been
read by an interrupted thread while allowing that interruption to
continue.
This approach has proven to be insufficient as there are scenarios
where the read needs to succeed on the interrupted thread. This
commit updates the handling of ClosedByInterruptException so that
this is the case. The FileChannel is recreated as before but the
thread's interrupted flag is now cleared before retrying the read.
The flag is then reinstated so that any subsequent actions that
should fail due to the interruption will do so.
We could clear and reinstate the interrupted flag before the first
read, rather than catching ClosedByInterruptException. This approach
was rejected as it will have an impact on the performance of the
happy path where the thread hasn't been interrupted.
Fixes gh-38611
Relax the constraint that a `NestedLocation` must have a nested entry
name specified so that URLs can be split and rebuilt.
Prior to this commit, given a URL of the following form:
jar:nested:/myjar.jar!/nested.jar!/my/file
It was possible to create a FileSystem from
"jar:nested:/myjar.jar!/nested.jar" and from that create a path to
"my/file".
However, it wasn't possible to create a FileSystem from
"jar:nested:/myjar.jar", then create another file system from the path
"nested.jar" and then finally create a path to "/nested.jar".
This was because `nested:/myjar.jar` was not considered a value URL
because it didn't include a nested entry name.
Projects such as `JobRunr` were relying on the ability to compose file
systems, so it makes sense to remove our somewhat artificial
restriction.
Fixes gh-38592