Skip to content

Commit 9db42a6

Browse files
committed
fix: preserve exec permissions on jspawnhelper in bundled JDK ([#1537](#1537))
Fix: - Move the permission loop in includeJdk into a doLast block so it runs after the copy, and re-apply the exec bit from the source JDK for files that should be executable. - Extend setExecutablePermissions to also cover the IDE runtime/ path (not just resources/), since the runtime's jspawnhelper had the same issue. - Add JAVA_HOME / JDK_HOME env var support in Platform.getJavaHome(), inside the existing "If the JDK is set in the environment" fallback block, so users can point Processing at a different JDK when the bundle is absent.
1 parent 11ef4a6 commit 9db42a6

2 files changed

Lines changed: 29 additions & 4 deletions

File tree

app/build.gradle.kts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,20 @@ tasks.register<Copy>("includeJdk") {
437437
destinationDir = composeResources("jdk").get().asFile
438438

439439
dirPermissions { unix("rwx------") }
440-
fileTree(destinationDir).files.forEach { file ->
441-
file.setWritable(true, false)
442-
file.setReadable(true, false)
440+
// Preserve executable permissions on binaries (bin/*, jspawnhelper, jexec, etc.)
441+
// https://github.com/processing/processing4/issues/1537
442+
doLast {
443+
fileTree(destinationDir).files.forEach { file ->
444+
// Copy preserves the source exec bit, but some environments strip it.
445+
// Re-apply exec on files that should be executable.
446+
val sourceFile = File(Jvm.current().javaHome.absolutePath,
447+
file.relativeTo(destinationDir).path)
448+
if (sourceFile.canExecute()) {
449+
file.setExecutable(true, false)
450+
}
451+
file.setWritable(true, false)
452+
file.setReadable(true, false)
453+
}
443454
}
444455
}
445456
tasks.register<Copy>("includeSharedAssets"){
@@ -633,6 +644,10 @@ tasks.register("setExecutablePermissions") {
633644
include("**/resources/**/*.dylib")
634645
include("**/resources/**/*.so")
635646
include("**/resources/**/*.exe")
647+
// Also cover the IDE runtime (jspawnhelper, jexec, bin/*) — same issue
648+
// https://github.com/processing/processing4/issues/1537
649+
include("**/runtime/**/bin/**")
650+
include("**/runtime/**/lib/**")
636651
}.forEach { file ->
637652
if (file.isFile) {
638653
file.setExecutable(true, false)

app/src/processing/app/Platform.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ static public File getContentFile(String name) {
371371
}
372372

373373
static public File getJavaHome() {
374-
// Get the build in JDK location from the Jetpack Compose resources
374+
// Get the built-in JDK location from the Jetpack Compose resources
375375
var resourcesDir = System.getProperty("compose.application.resources.dir");
376376
if(resourcesDir != null) {
377377
var jdkFolder = new File(resourcesDir,"jdk");
@@ -381,6 +381,16 @@ static public File getJavaHome() {
381381
}
382382

383383
// If the JDK is set in the environment, use that.
384+
// if not, fall back to the java.home system property.
385+
for (String envKey : new String[] { "JAVA_HOME", "JDK_HOME" }) {
386+
String envPath = System.getenv(envKey);
387+
if (envPath != null && !envPath.isEmpty()) {
388+
File envHome = new File(envPath);
389+
if (new File(envHome, "bin/java" + (Platform.isWindows() ? ".exe" : "")).canExecute()) {
390+
return envHome;
391+
}
392+
}
393+
}
384394
var home = System.getProperty("java.home");
385395
if(home != null){
386396
return new File(home);

0 commit comments

Comments
 (0)