Skip to content

OSGI metadata in MANIFEST.MF is missing 'uses:' information #1487

@sratz

Description

@sratz

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:=&quot;com.sun.jna&quot;, com.sun.jna.win32;version=${jna.major}.${jna.minor}.${jna.revision};uses:=&quot;com.sun.jna&quot;"/>
               <!-- 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=&quot;${osgi.version}&quot;"/>
                 <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:=&quot;com.sun.jna,com.sun.jna.platform.win32,javax.swing&quot;,
+com.sun.jna.platform.dnd;version=${osgi.version};uses:=&quot;javax.swing&quot;,
+com.sun.jna.platform.linux;version=${osgi.version};uses:=&quot;com.sun.jna,com.sun.jna.platform.unix&quot;,
+com.sun.jna.platform.mac;version=${osgi.version};uses:=&quot;com.sun.jna,com.sun.jna.platform,com.sun.jna.platform.unix,com.sun.jna.ptr&quot;,
+com.sun.jna.platform.unix;version=${osgi.version};uses:=&quot;com.sun.jna,com.sun.jna.ptr&quot;,
+com.sun.jna.platform.unix.aix;version=${osgi.version};uses:=&quot;com.sun.jna&quot;,
+com.sun.jna.platform.unix.solaris;version=${osgi.version};uses:=&quot;com.sun.jna&quot;,
+com.sun.jna.platform.win32;version=${osgi.version};uses:=&quot;com.sun.jna,com.sun.jna.platform,com.sun.jna.platform.win32.COM,com.sun.jna.ptr,com.sun.jna.win32&quot;,
+com.sun.jna.platform.win32.COM;version=${osgi.version};uses:=&quot;com.sun.jna,com.sun.jna.platform.win32,com.sun.jna.platform.win32.COM.util,com.sun.jna.ptr,com.sun.jna.win32&quot;,
+com.sun.jna.platform.win32.COM.tlb;version=${osgi.version};uses:=&quot;com.sun.jna.platform.win32.COM.tlb.imp&quot;,
+com.sun.jna.platform.win32.COM.tlb.imp;version=${osgi.version};uses:=&quot;com.sun.jna.platform.win32,com.sun.jna.platform.win32.COM&quot;,
+com.sun.jna.platform.win32.COM.util;version=${osgi.version};uses:=&quot;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&quot;,
 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:=&quot;com.sun.jna,com.sun.jna.platform.win32&quot;
 "/>
             </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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions