-
Notifications
You must be signed in to change notification settings - Fork 190
Description
Library.isLoadable() fails when SWT-OS or SWT-Arch manifest entries are missing, with error:
Libraries for platform win32 cannot be loaded because of incompatible environment
This breaks uber JARs (where build tools lose manifest entries during merge) and universal binaries (where a single manifest can't specify multiple architectures).
I am including a proposed a simple fix to clarify the error message and work under these conditions.
To Reproduce
Scenario 1: Uber JAR
- Create Maven project with SWT dependency
- Build with maven-assembly-plugin without preserving manifest entries:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>- Run the resulting JAR (java -jar xyz-jar-with-dependencies.jar)
- Application exits with "incompatible environment" error
Scenario 2: Universal Binary
- Create macOS universal binary by combining x86_64 and aarch64 libraries with
lipo - Package with single manifest (can only specify one
SWT-Archvalue) - Run on the non-manifest architecture
- Application exits with "incompatible environment" error
Expected behavior
The check should:
- Allow when manifest entries are missing (uber JAR or universal binary scenario)
- Fail when manifest entries are present but mismatched (actual wrong platform JAR)
- Provide clear diagnostic message explaining the mismatch
This distinguishes between acceptable scenarios (missing entries) and actual errors (wrong platform).
Environment
-
Platform:
- All OS
- Windows
- Linux
- macOS
-
Additional OS info: Affects all platforms equally
-
JRE/JDK version: All versions
Version since
PR #2054 and #2026 cc @HeikoKlare
Introduced in commit 360a270 (April 23, 2025) - likely Eclipse 4.33 or later
Workaround
For uber JARs: Configure build tool to preserve manifest entries:
<archive>
<manifestEntries>
<SWT-OS>win32</SWT-OS>
<SWT-Arch>x86_64</SWT-Arch>
</manifestEntries>
</archive>For universal binaries: No workaround available (manifest can only contain single architecture)
I've been using universal binaries for Mac for a long time -- as the .classes are identical and it is pretty trivial to use lipo to merge aarch64 and intel.
Proposed Fix
Location: bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java lines 214-222
Current code:
String manifestOS = attributes.getValue("SWT-OS");
String manifestArch = attributes.getValue("SWT-Arch");
if (arch.equals(manifestArch) && os.equals(manifestOS)) {
return true;
}
return false; // Fails for both missing AND mismatchedProposed change:
String manifestOS = attributes.getValue("SWT-OS");
String manifestArch = attributes.getValue("SWT-Arch");
// Missing: allow (uber JAR or universal binary)
if (manifestOS == null || manifestArch == null) {
return true;
}
// Present but mismatched: fail with clear diagnostic
if (!arch.equals(manifestArch) || !os.equals(manifestOS)) {
System.err.println("SWT platform mismatch:");
System.err.println(" Manifest: SWT-OS=" + manifestOS + ", SWT-Arch=" + manifestArch);
System.err.println(" Runtime: os=" + os + ", arch=" + arch);
return false;
}
return true;This 5-line change:
- Fixes uber JAR and universal binary scenarios
- Still catches wrong platform JARs (e.g., Linux JAR on Windows)
- Provides clear diagnostics when actual mismatch detected
- Maintains security benefit of platform checking
Thank you SWT Team!