processing / processing/processing4

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

未关闭
#1,537 1 条评论 0 个 reaction 已指派 1 人 在 GitHub 查看

@ZanDev32 已经在做这个了。

开始于 2026年7月7日。

bug
主要语言
Java
星标
497
派生
183
平均合并
4 小时 39 分钟
30 天内合并 PR
3

描述

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

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。