Skip to content

OpenGL/3D sketches crash with UnsatisfiedLinkError on Linux when the bundled sketch JDK cannot fork+exec #1537

Description

@ZanDev32

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.javagetJavaHome() 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:

  1. Honor JAVA_HOME / JDK_HOME env vars or a runtime.java.path preference before the bundled JDK, so users can override a broken bundle.
  2. On Linux, probe a system JDK (/usr/lib/jvm/default-runtime, update-alternatives --list java, archlinux-java) as the fallback before giving up.
  3. 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

  1. Run any 3D/OpenGL sketch (P3D, P2D, Lights, OBJ-loading sketches, or anything that using JOGL

  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions