Most appropriate sub-area of Processing 4?
OpenGL
Processing version
4.5.5
Operating system
EndeavourOS x86_64 Linux 7.0.5
Bug description
Every 3D/OpenGL sketch (P3D, P2D, Lights, OBJ-loading sketches, or anything that using JOGL) fails at launch:
Warning: Caught Exception while retrieving executable temp base directory:
java.io.IOException: Could not determine a temporary executable directory
at com.jogamp.common.util.IOUtil.getTempDir(IOUtil.java:1401)
at com.jogamp.common.util.cache.TempFileCache.<clinit>(TempFileCache.java:84)
at com.jogamp.common.os.Platform$1.run(Platform.java:313)
...
java.lang.UnsatisfiedLinkError: 'boolean jogamp.common.jvm.JVMUtil.initialize(java.nio.ByteBuffer)'
at jogamp.common.jvm.JVMUtil.initialize(Native Method)
at com.jogamp.common.os.Platform.<clinit>(Platform.java:290)
at com.jogamp.opengl.GLProfile.<clinit>(GLProfile.java:151)
at processing.opengl.PSurfaceJOGL.initGL(PSurfaceJOGL.java:204)
...
A library used by this sketch relies on native code that is not available.
2D (Java2D) sketches run fine.
Findings using Ai Agents
JOGL's IOUtil.testDirExec() writes a tiny test script into a temp directory, sets +x, and actually execve()s it to verify the temp dir allows execution. If that exec fails, JOGL's native-lib cache (TempFileCache) never starts, and subsequent JVMUtil.initialize (a native method) fails with UnsatisfiedLinkError.
The bundled sketch JDK at resources/jdk (Temurin 17.0.19) cannot fork+exec anything even /bin/true as a child process, while the system's own JDK on the same machine/user succeeds.
This was confirmed by running the exact same Java program on both JDKs (Build-in and System):
# bundled Temurin 17 (Build-In):
new ProcessBuilder("/bin/true").start()
→ IOException: Cannot run program "/bin/true": error=13, Permission denied
# system OpenJDK 21 (System):
new ProcessBuilder("/bin/true").start()
→ OK exit 0
error=13 is EACCES. This is a per-process exec denial affecting only the bundled binary (same uid, same caps, no seccomp, no AppArmor/SELinux). The exact mechanism applying the denial is unconfirmed (likely a Landlock restriction from the environment, not from the JVM itself, perhaps the bundled libjvm does not reference landlock symbols).
Why Platform.getJavaHome() can't recover
processing/app/Platform.getJavaHome() either returns resources/jdk (the broken bundle) or falls back to java.home (the IDE's own runtime at lib/runtime/). On the jpackage-based Linux install the IDE runtime has no bin/java (the launcher loads the JVM in-process via libjli.so, so a standalone java binary is not shipped in that tree). The fallback is therefore dead on Linux: removing resources/jdk gives a "file not found" error instead of working.
No preference or environment variable is read for the sketch JDK path — confirmed by decompiling Platform, Runner, and JavaBuild.
Affected file(s)
processing/app/Platform.java — getJavaHome() and getJavaPath()
Suggested fix direction
Before returning the bundled resources/jdk from getJavaHome(), validate it can launch a child process (one-shot Runtime.exec("/bin/true")). When it fails:
- Honor
JAVA_HOME / JDK_HOME env vars or a runtime.java.path preference before the bundled JDK, so users can override a broken bundle.
- On Linux, probe a system JDK (
/usr/lib/jvm/default-runtime, update-alternatives --list java, archlinux-java) as the fallback before giving up.
- Report a clear message when no working JDK is found, instead of letting the crash surface as an opaque
UnsatisfiedLinkError from JOGL.
Verified workaround
sudo mv resources/jdk resources/jdk.broken
sudo ln -s /usr/lib/jvm/{any installed JDK} resources/jdk
After this, JOGL initializes cleanly (GLProfile init OK, GL 4.6 hardware detected) and all 3D sketches render.
Steps to reproduce this
-
Run any 3D/OpenGL sketch (P3D, P2D, Lights, OBJ-loading sketches, or anything that using JOGL
-
Crash
snippet
Using OnOff sketch template
/**
* On/Off.
*
* Uses the default lights to show a simple box. The lights() function
* is used to turn on the default lighting. Click the mouse to turn the
* lights off.
*/
float spin = 0.0;
void setup() {
size(640, 360, P3D);
noStroke();
}
void draw() {
background(51);
if (!mousePressed) {
lights();
}
spin += 0.01;
pushMatrix();
translate(width/2, height/2, 0);
rotateX(PI/9);
rotateY(PI/5 + spin);
box(150);
popMatrix();
}```
### Additional context
## Environment
- Arch Linux, kernel 7.0.5-arch1-1-g14
- Processing 4.5.5, bundled sketch JDK Temurin 17.0.19+10
- System JDK: OpenJDK 21.0.11 at `/usr/lib/jvm/java-21-openjdk`
- `/tmp`: `tmpfs (rw,noatime)` — not `noexec`
### Would you like to work on the issue?
Yes, I’d like to help with this
Most appropriate sub-area of Processing 4?
OpenGL
Processing version
4.5.5
Operating system
EndeavourOS x86_64 Linux 7.0.5
Bug description
Every 3D/OpenGL sketch (P3D, P2D,
Lights, OBJ-loading sketches, or anything that using JOGL) fails at launch:2D (Java2D) sketches run fine.
Findings using Ai Agents
JOGL's
IOUtil.testDirExec()writes a tiny test script into a temp directory, sets+x, and actuallyexecve()s it to verify the temp dir allows execution. If that exec fails, JOGL's native-lib cache (TempFileCache) never starts, and subsequentJVMUtil.initialize(a native method) fails withUnsatisfiedLinkError.The bundled sketch JDK at
resources/jdk(Temurin 17.0.19) cannotfork+execanything even/bin/trueas a child process, while the system's own JDK on the same machine/user succeeds.This was confirmed by running the exact same Java program on both JDKs (Build-in and System):
error=13isEACCES. This is a per-process exec denial affecting only the bundled binary (same uid, same caps, no seccomp, no AppArmor/SELinux). The exact mechanism applying the denial is unconfirmed (likely a Landlock restriction from the environment, not from the JVM itself, perhaps the bundled libjvm does not reference landlock symbols).Why
Platform.getJavaHome()can't recoverprocessing/app/Platform.getJavaHome()either returnsresources/jdk(the broken bundle) or falls back tojava.home(the IDE's own runtime atlib/runtime/). On the jpackage-based Linux install the IDE runtime has nobin/java(the launcher loads the JVM in-process vialibjli.so, so a standalonejavabinary is not shipped in that tree). The fallback is therefore dead on Linux: removingresources/jdkgives a "file not found" error instead of working.No preference or environment variable is read for the sketch JDK path — confirmed by decompiling
Platform,Runner, andJavaBuild.Affected file(s)
processing/app/Platform.java—getJavaHome()andgetJavaPath()Suggested fix direction
Before returning the bundled
resources/jdkfromgetJavaHome(), validate it can launch a child process (one-shotRuntime.exec("/bin/true")). When it fails:JAVA_HOME/JDK_HOMEenv vars or aruntime.java.pathpreference before the bundled JDK, so users can override a broken bundle./usr/lib/jvm/default-runtime,update-alternatives --list java,archlinux-java) as the fallback before giving up.UnsatisfiedLinkErrorfrom JOGL.Verified workaround
sudo mv resources/jdk resources/jdk.broken sudo ln -s /usr/lib/jvm/{any installed JDK} resources/jdkAfter this, JOGL initializes cleanly (
GLProfile init OK, GL 4.6 hardware detected) and all 3D sketches render.Steps to reproduce this
Run any 3D/OpenGL sketch (P3D, P2D,
Lights, OBJ-loading sketches, or anything that using JOGLCrash
snippet
Using OnOff sketch template