-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Description
When multiple versions of JNA are present in a single OSGI environment, it can happen that OSGI computes an incorrect dependency chain, which can lead to exceptions like the following:
java.lang.LinkageError: loader constraint violation: when resolving interface method 'boolean com.sun.jna.platform.win32.Kernel32.ReadFile(com.sun.jna.platform.win32.WinNT$HANDLE, byte[], int, com.sun.jna.ptr.IntByReference, com.sun.jna.platform.win32.WinBase$OVERLAPPED)' the class loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @216be7ba of the current class, com/sap/adt/sapgui/ui/internal/win32/embedding/PipeHelper, and the class loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @1885dc2b for the method's defining class, com/sun/jna/platform/win32/Kernel32, have different Class objects for the type com/sun/jna/ptr/IntByReference used in the signature (com.sap.adt.sapgui.ui.internal.win32.embedding.PipeHelper is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @216be7ba, parent loader 'platform'; com.sun.jna.platform.win32.Kernel32 is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @1885dc2b, parent loader 'platform')
at com.sap.adt.sapgui.ui.internal.win32.embedding.PipeHelper.readNamedPipe(PipeHelper.java:119)
at com.sap.adt.sapgui.ui.internal.win32.embedding.WinGuiServerProxy$2.run(WinGuiServerProxy.java:133)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
This is a known issue in OSGI when metadata is insufficient and can be addressed by enriching the Export-Package metadata with ;uses="..." information:
https://spring.io/blog/2008/10/20/understanding-the-osgi-uses-directive/
A patch could look like this:
diff --git a/build.xml b/build.xml
index 93bad0971..aab63fb33 100644
--- a/build.xml
+++ b/build.xml
@@ -470,7 +470,7 @@
<attribute name="Bundle-RequiredExecutionEnvironment" value="JavaSE-1.6"/>
<attribute name="Bundle-Vendor" value="${vendor}"/>
<attribute name="Bundle-ActivationPolicy" value="lazy"/>
- <attribute name="Export-Package" value="com.sun.jna;version=${jna.major}.${jna.minor}.${jna.revision}, com.sun.jna.ptr;version=${jna.major}.${jna.minor}.${jna.revision}, com.sun.jna.win32;version=${jna.major}.${jna.minor}.${jna.revision}"/>
+ <attribute name="Export-Package" value="com.sun.jna;version=${jna.major}.${jna.minor}.${jna.revision}, com.sun.jna.ptr;version=${jna.major}.${jna.minor}.${jna.revision};uses:="com.sun.jna", com.sun.jna.win32;version=${jna.major}.${jna.minor}.${jna.revision};uses:="com.sun.jna""/>
<!-- Note that no terminal "*" is included in this list,
which will force failure on unsupported platforms.
-->
diff --git a/contrib/platform/build.xml b/contrib/platform/build.xml
index 47fa8ed33..b7f04d393 100644
--- a/contrib/platform/build.xml
+++ b/contrib/platform/build.xml
@@ -147,20 +147,20 @@
<attribute name="Require-Bundle" value="com.sun.jna;bundle-version="${osgi.version}""/>
<attribute name="Export-Package"
value="
-com.sun.jna.platform;version=${osgi.version},
-com.sun.jna.platform.dnd;version=${osgi.version},
-com.sun.jna.platform.linux;version=${osgi.version},
-com.sun.jna.platform.mac;version=${osgi.version},
-com.sun.jna.platform.unix;version=${osgi.version},
-com.sun.jna.platform.unix.aix;version=${osgi.version},
-com.sun.jna.platform.unix.solaris;version=${osgi.version},
-com.sun.jna.platform.win32;version=${osgi.version},
-com.sun.jna.platform.win32.COM;version=${osgi.version},
-com.sun.jna.platform.win32.COM.tlb;version=${osgi.version},
-com.sun.jna.platform.win32.COM.tlb.imp;version=${osgi.version},
-com.sun.jna.platform.win32.COM.util;version=${osgi.version},
+com.sun.jna.platform;version=${osgi.version};uses:="com.sun.jna,com.sun.jna.platform.win32,javax.swing",
+com.sun.jna.platform.dnd;version=${osgi.version};uses:="javax.swing",
+com.sun.jna.platform.linux;version=${osgi.version};uses:="com.sun.jna,com.sun.jna.platform.unix",
+com.sun.jna.platform.mac;version=${osgi.version};uses:="com.sun.jna,com.sun.jna.platform,com.sun.jna.platform.unix,com.sun.jna.ptr",
+com.sun.jna.platform.unix;version=${osgi.version};uses:="com.sun.jna,com.sun.jna.ptr",
+com.sun.jna.platform.unix.aix;version=${osgi.version};uses:="com.sun.jna",
+com.sun.jna.platform.unix.solaris;version=${osgi.version};uses:="com.sun.jna",
+com.sun.jna.platform.win32;version=${osgi.version};uses:="com.sun.jna,com.sun.jna.platform,com.sun.jna.platform.win32.COM,com.sun.jna.ptr,com.sun.jna.win32",
+com.sun.jna.platform.win32.COM;version=${osgi.version};uses:="com.sun.jna,com.sun.jna.platform.win32,com.sun.jna.platform.win32.COM.util,com.sun.jna.ptr,com.sun.jna.win32",
+com.sun.jna.platform.win32.COM.tlb;version=${osgi.version};uses:="com.sun.jna.platform.win32.COM.tlb.imp",
+com.sun.jna.platform.win32.COM.tlb.imp;version=${osgi.version};uses:="com.sun.jna.platform.win32,com.sun.jna.platform.win32.COM",
+com.sun.jna.platform.win32.COM.util;version=${osgi.version};uses:="com.sun.jna,com.sun.jna.platform.win32,com.sun.jna.platform.win32.COM,com.sun.jna.platform.win32.COM.util.annotation,com.sun.jna.ptr",
com.sun.jna.platform.win32.COM.util.annotation;version=${osgi.version},
-com.sun.jna.platform.wince;version=${osgi.version}
+com.sun.jna.platform.wince;version=${osgi.version};uses:="com.sun.jna,com.sun.jna.platform.win32"
"/>
</manifest>
<manifest file="@{target}" mode="update" if:true="@{module-info}">I can open a pull-request to provide a patch.
However, it's a bit fragile to keep maintaining this metadata by hand. A better solution might be to automate the generation of the MANIFEST.MF metadata with bnd:
https://bnd.bndtools.org/
Metadata
Metadata
Assignees
Labels
No labels