-
Notifications
You must be signed in to change notification settings - Fork 39
Description
Describe the bug
When running the application inside a Docker container with param -Djava.security.manager=allow, the Java common ForkJoinPool creates instances of InnocuousForkJoinWorkerThread instead of the standard ForkJoinWorkerThread. As a result, the Thread.setContextClassLoader throws the SecurityException.
This behavior differs from running the same application outside of Docker, where normal ForkJoinWorkerThread instances are created, and no exception is thrown.
Reproduced on 21.0.6.7-1, but does not reproduce on 21.0.5.11-1
To Reproduce
Docker:
taken from https://github.com/corretto/corretto-docker/blob/main/21/jdk/al2-generic/Dockerfile
FROM amazonlinux:2
# success:
# ARG version=21.0.5.11-1
# failure:
ARG version=21.0.6.7-1
# In addition to installing the Amazon corretto, we also install
# fontconfig. The folks who manage the docker hub's
# official image library have found that font management
# is a common usecase, and painpoint, and have
# recommended that Java images include font support.
#
# See:
# https://github.com/docker-library/official-images/blob/master/test/tests/java-uimanager-font/container.java
# The logic and code related to Fingerprint is contributed by @tianon in a Github PR's Conversation
# Comment = https://github.com/docker-library/official-images/pull/7459#issuecomment-592242757
# PR = https://github.com/docker-library/official-images/pull/7459
RUN set -eux \
&& export GNUPGHOME="$(mktemp -d)" \
&& curl -fL -o corretto.key https://yum.corretto.aws/corretto.key \
&& gpg --batch --import corretto.key \
&& gpg --batch --export --armor '6DC3636DAE534049C8B94623A122542AB04F24E3' > corretto.key \
&& rpm --import corretto.key \
&& rm -r "$GNUPGHOME" corretto.key \
&& curl -fL -o /etc/yum.repos.d/corretto.repo https://yum.corretto.aws/corretto.repo \
&& grep -q '^gpgcheck=1' /etc/yum.repos.d/corretto.repo \
&& echo "priority=9" >> /etc/yum.repos.d/corretto.repo \
&& yum install -y java-21-amazon-corretto-devel-$version \
&& (find /usr/lib/jvm/java-21-amazon-corretto -name src.zip -delete || true) \
&& yum install -y fontconfig \
&& yum clean all
ENV LANG=C.UTF-8
ENV JAVA_HOME=/usr/lib/jvm/java-21-amazon-corretto
WORKDIR /app
COPY App.java .
RUN javac App.java
CMD ["java", "-Djava.security.manager=allow", "App"]
App:
public class App {
public static void main(String[] args) {
var defaultExecutor = ForkJoinPool.commonPool();
defaultExecutor.execute(() -> {
Thread t = Thread.currentThread();
System.out.println("Running in thread: " + t.getClass().getName());
try {
t.setContextClassLoader(new java.net.URLClassLoader(new java.net.URL[0]));
System.out.println("Set context class loader.");
} catch (SecurityException e) {
System.err.println("SecurityException: " + e.getMessage());
e.printStackTrace();
}
});
try {
Thread.sleep(1_000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Build:
#!/bin/bash
cp ../src/main/java/App.java .
docker build -t demo .
docker run --rm demo
Result:
Running in thread: java.util.concurrent.ForkJoinWorkerThread$InnocuousForkJoinWorkerThread
SecurityException: setContextClassLoader
java.lang.SecurityException: setContextClassLoader
at java.base/java.util.concurrent.ForkJoinWorkerThread$InnocuousForkJoinWorkerThread.setContextClassLoader(ForkJoinWorkerThread.java:231)
at App.lambda$main$0(App.java:11)
at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1423)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
Expected behavior
When running inside Docker, the common ForkJoinPool should create instances of java.util.concurrent.ForkJoinWorkerThread instead of InnocuousForkJoinWorkerThread, and no security exceptions should be thrown.
Alternatively, a clear explanation of why the jdk creates InnocuousForkJoinWorkerThread in this context, and how this behavior can be avoided.
Platform information
OS: macOs, 14.4.1
Version: Corretto-21.0.6.7-1
Additional context
The project does not use a Security Manager.
Running the same application either inside a container with Corretto 21.0.5 or locally (outside a container) produces the following result:
Running in thread: java.util.concurrent.ForkJoinWorkerThread
Set context class loader.