Repository navigation
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
Activity
matthiasblaesing commentedon Dec 12, 2022
Looks sane to me. If you provide a PR, I'm willing to have second look. Please ensure, that you add an entry to the
CHANGES.mdfile.Add 'uses' information to OSGI metadata in MANIFEST.MF
Add 'uses' information to OSGI metadata in MANIFEST.MF
Update dependency net.java.dev.jna:jna to v5.13.0 (mulk/mulkcms2!8)