eclipsemaveneclipse-rcposgi-bundletycho

Maven jar dependency not found at runtime by OSGi environment


I'm building an Eclipse product that requires some external dependencies, which are not bundled as Eclipse plugins. For example javax.json-1.1.4.jar.

I'm usign a target platform file, with Maven dependency added. This is the relevant part of the .target file:

<location includeDependencyScope="compile" includeSource="true" missingManifest="generate" type="Maven">
            <dependencies>
                ......
                <dependency>
                    <groupId>org.glassfish</groupId>
                    <artifactId>javax.json</artifactId>
                    <version>1.1.4</version>
                    <type>jar</type>
                </dependency>
            </dependencies>
        </location>

The resulting bundle is included from the plugin that uses this Json implementation: this is the MANIFEST of the plugin

Require-Bundle: org.glassfish.javax.json;bundle-version="1.1.4"

The plugin compiles and run normally. The problem happens at runtime, when the Json implementation is loaded:

2022-03-11 09:44:18,166 ERROR [main]: Provider org.glassfish.json.JsonProviderImpl not found
2022-03-11 09:44:18,168 ERROR [main]: 
javax.json.JsonException: Provider org.glassfish.json.JsonProviderImpl not found
    at javax.json.spi.JsonProvider.provider(JsonProvider.java:99)
    at javax.json.Json.createReader(Json.java:225)
    at com.test.mas.rcp.hwconfigurator.sirius.core.utils.MotorDataHandler.parseMotorJsonFile(MotorDataHandler.java:64)
    at com.test.mas.rcp.hwconfigurator.sirius.core.utils.DBHandler.initMotorsDB(DBHandler.java:209)
    at com.test.mas.rcp.hwconfigurator.sirius.core.utils.DBHandler.getMotors(DBHandler.java:116)
    at com.test.mas.rcp.hwconfigurator.sirius.core.impl.FieldBusDevice.getMotors(FieldBusDevice.java:1323)
    at com.test.mas.rcp.hwconfigurator.sirius.core.impl.FieldBusDevice.createFromSiriusString(FieldBusDevice.java:1257)
    at com.test.mas.rcp.hwconfigurator.sirius.core.impl.HwConfiguratorFactoryImpl.createFieldBusDeviceFromString(HwConfiguratorFactoryImpl.java:252)
    at com.test.mas.rcp.hwconfigurator.sirius.core.impl.HwConfiguratorFactoryImpl.createFromString(HwConfiguratorFactoryImpl.java:93)
    at org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl.createFromString(XMLHelperImpl.java:1615)
    at org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl.setValue(XMLHelperImpl.java:1156)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.setFeatureValue(XMLHandler.java:2710)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.setAttribValue(XMLHandler.java:2769)
    at org.eclipse.emf.ecore.xmi.impl.SAXXMIHandler.handleObjectAttribs(SAXXMIHandler.java:79)
    at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObjectFromFactory(XMLHandler.java:2247)
Caused by: java.lang.ClassNotFoundException: org.glassfish.json.JsonProviderImpl cannot be found by javax.json-api_1.1.4
    at org.eclipse.osgi.internal.loader.BundleLoader.generateException(BundleLoader.java:516)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:511)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:403)
    at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:168)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:315)
    at javax.json.spi.JsonProvider.provider(JsonProvider.java:96)
    at javax.json.Json.createReader(Json.java:225)
    at com.test.mas.rcp.hwconfigurator.sirius.core.utils.MotorDataHandler.parseMotorJsonFile(MotorDataHandler.java:64)
    at com.test.mas.rcp.hwconfigurator.sirius.core.utils.DBHandler.initMotorsDB(DBHandler.java:209)
    at com.test.mas.rcp.hwconfigurator.sirius.core.utils.DBHandler.getMotors(DBHandler.java:116)
    at com.test.mas.rcp.hwconfigurator.sirius.core.impl.FieldBusDevice.getMotors(FieldBusDevice.java:1323)
    at com.test.mas.rcp.hwconfigurator.sirius.core.impl.FieldBusDevice.createFromSiriusString(FieldBusDevice.java:1257)
    at com.test.mas.rcp.hwconfigurator.sirius.core.impl.HwConfiguratorFactoryImpl.createFieldBusDeviceFromString(HwConfiguratorFactoryImpl.java:252)

The javax.json-1.1.4.jar is not found at runtime by the api jar javax.json-api_1.1.4.

The only way I found to make it work is to add the implementation jar to the runtime classpath settings of the plugin, in the Bundle-Classpath:

Bundle-ClassPath: .,
 lib/javax.json-1.1.4.jar,

This requires the jar in the lib folder of the plugin, while it is already included from the tartget platform. It should be enough.. Is there a configuration or something to be done to make the OSGi environment recognise the jar as a Maven dependency at runtime? I have read about Eclipse-BuddyPolicy and DynamicImport-Package but I don't know how to used them in my case, and if they are usefull.

This https://github.com/eclipse-ee4j/jsonp/issues/96 says that it "Should be fixed with javax.json:1.1.4 and jakarta.json:1.1.5" but I don't get how...


Solution

  • I managed to fix this problem, thanks to the comments in this thread:

    https://github.com/eclipse-ee4j/jax-ws-api/issues/90

    in particular the last one:

    https://github.com/eclipse-ee4j/jax-ws-api/issues/90#issuecomment-952793454

    This is related to a veri similar problem I had with the implementation of the com.sun.xml.ws.spi.ProviderImpl web service provider.

    Including the OSGi Resource Locator in the bundle manifest, and the plugin with the actual implementations, make them discoverable at runtime.

    This is the dependency in the target platform file:

    <dependency>
        <groupId>org.glassfish.hk2</groupId>
        <artifactId>osgi-resource-locator</artifactId>
        <version>2.5.0-b42</version>
        <type>jar</type>
    </dependency>
    

    In the end, for the Json problem, I switched to the Eclipse Parsson implementation which works at runtime without problems. These are the needed dependencies in the target platform:

    <dependency>
        <groupId>org.eclipse.parsson</groupId>
        <artifactId>jakarta.json</artifactId>
        <version>1.0.0</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>org.eclipse.parsson</groupId>
        <artifactId>parsson</artifactId>
        <version>1.0.0</version>
        <type>jar</type>
    </dependency>