0

We are using e4 and Java 1.8.0.281 (to run) and AdoptOpenJDK 11 for builds with Eclipse IDE for RCP and RAP Developers Version: 2020-12 (4.18.0).

We intend to use this library https://github.com/ECF/JaxRSProviders/ in our newly to be developed RichClientPlatform Client and were able to integrate it as described at https://www.modumind.com/2020/07/23/eclipse-rcp-and-rest-jax-rs-extensions/ and the later blogposts in the series. We are also able to build the client using tycho, start it, services get discovered and we can consume out backend.

Troubles start when we try to do the same via webstart. So far we have not been able to get our client running via webstart at all. So we took a step back and implemented a minimal client. This also works fine when started on its own but does not work when started as a webstart application (via org.eclipse.equinox.launcher.WebStartMain.main(args);)

To debug the issue we created a workspace that allows to start this from eclipse using the class WebStartWrapper. What we see is that the client starts but the service injection breaks with a ClassCastException. This happens most of the time but not all the time on all machines. We have not been able to debug why it sometimes work but we have been able to debug that WHEN the error happens it is because of different classloader being used.

E.g.

class org.glassfish.jersey.inject.hk2.Hk2InjectionManagerFactory -> loaded by sun.misc.Launcher$AppClassLoader@18b4aac2 with Parent CL: sun.misc.Launcher$ExtClassLoader@4043bcaf

And

interface org.glassfish.jersey.internal.inject.InjectionManagerFactory -> loaded by
org.eclipse.osgi.internal.loader.EquinoxClassLoader@49752ef8[org.glassfish.jersey.core.jersey-common:2.30.1(id=127)] withParent org.eclipse.osgi.internal.framework.EquinoxContainer$1@2a060884

Wenn it works we see org.glassfish.jersey.internal.OsgiRegistry$OsgiServiceFinder$1@7e440207 being called when it doesn't we see org.glassfish.jersey.internal.ServiceFinder$LazyObjectIterator@6929efb4

We have tried various variation of start-levels and autostarted bundles but no dice.

But what we found out is that org.glassfish.jersey.internal.ServiceFinder has this static block:

static {
    final OsgiRegistry osgiRegistry = ReflectionHelper.getOsgiRegistryInstance();

    if (osgiRegistry != null) {
        LOGGER.log(Level.CONFIG, "Running in an OSGi environment");

        osgiRegistry.hookUp();
    } else {
        LOGGER.log(Level.CONFIG, "Running in a non-OSGi environment");
    }
}

We saw that everything works when the classloader loaded the class after the OSGI registry was available, but not when the class was loaded before (I could verify this via the logs, every time I got the "Running in an OSGi environment" message it would work). I could solve this by setting a lower startLevel (3) for the org.glassfish.jersey.core.jersey-common bundle.

Unfortunately this only solved our issues when starting the application directly via our WebStartWrapper (from Eclipse), when we try to start the app with JNLP (and the WebStartWrapper) we still get errors

ENTRY org.eclipse.ecf.osgi.services.remoteserviceadmin 4 0 2021-03-17 11:50:52.355
!MESSAGE FrameworkEvent ERROR
!STACK 0
org.osgi.framework.BundleException: Could not resolve module: org.eclipse.ecf.osgi.services.remoteserviceadmin [137]
  Unresolved requirement: Import-Package: org.eclipse.ecf.core.provider; version="[3.2.0,4.0.0)"

    at org.eclipse.osgi.container.Module.start(Module.java:463)
    at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel$2.run(ModuleContainer.java:1845)
    at org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor$1$1.execute(EquinoxContainerAdaptor.

Out of despair we tried to run the application using OpenWebStart and managed to do so with the following osgi.bundles:

<property name="jnlp.osgi.bundles"
value="org.eclipse.core.runtime@start,org.eclipse.equinox.simpleconfigurator@:start,org.apache.felix.scr@2:start,org.eclipse.ecf.osgi.services.distribution@start,org.eclipse.core.runtime@start,org.eclipse.ecf.provider.jersey.client@3:start,org.glassfish.jersey.core.jersey-common@start" />       

There is still one error in the logs but the application starts just fine and does the request correctly. The log showing the error (for good measures but, as I wrote, it does not affect the services getting discovered and requests working)

!SESSION 2021-06-16 18:10:40.311 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.8.0_282
java.vendor=AdoptOpenJDK
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=de_DE

!ENTRY org.apache.felix.scr 4 0 2021-06-16 18:10:41.754
!MESSAGE bundle org.apache.felix.scr:2.1.16.v20200110-1820 (3)Circular reference detected trying to get service {org.eclipse.ecf.remoteservice.provider.IRemoteServiceDistributionProvider}={service.id=46, service.bundleid=5, service.scope=bundle, component.name=org.eclipse.ecf.provider.jersey.client.JerseyClientDistributionProvider, component.id=0}
 stack of references: ServiceReference: {org.eclipse.ecf.remoteservice.provider.IRemoteServiceDistributionProvider}={service.id=46, service.bundleid=5, service.scope=bundle, component.name=org.eclipse.ecf.provider.jersey.client.JerseyClientDistributionProvider, component.id=0}

!STACK 0
java.lang.Exception: stack trace
    at org.apache.felix.scr.impl.ComponentRegistry.enterCreate(ComponentRegistry.java:485)
    at org.apache.felix.scr.impl.BundleComponentActivator.enterCreate(BundleComponentActivator.java:734)
    at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:881)
    at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse$1.run(ServiceFactoryUse.java:216)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse.factoryGetService(ServiceFactoryUse.java:213)
    at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse.getService(ServiceFactoryUse.java:114)
    at org.eclipse.osgi.internal.serviceregistry.ServiceConsumer$2.getService(ServiceConsumer.java:48)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.getService(ServiceRegistrationImpl.java:554)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.getService(ServiceRegistry.java:529)
    at org.eclipse.osgi.internal.framework.BundleContextImpl.getService(BundleContextImpl.java:685)
    at org.eclipse.ecf.internal.remoteservice.Activator$1.addingService(Activator.java:103)
    at org.eclipse.ecf.internal.remoteservice.Activator$1.addingService(Activator.java:1)
    at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:943)
    at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:1)
    at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
    at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183)
    at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:321)
    at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:264)
    at org.eclipse.ecf.internal.remoteservice.Activator.start(Activator.java:190)
    at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:843)
    at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:1)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:835)
    at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:792)
    at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1015)
    at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:365)
    at org.eclipse.osgi.container.Module.doStart(Module.java:605)
    at org.eclipse.osgi.container.Module.start(Module.java:468)
    at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:493)
    at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:117)
    at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:571)
    at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:346)
    at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:398)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:477)
    at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:171)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
    at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:620)
    at org.apache.felix.scr.impl.manager.AbstractComponentManager.initDependencyManagers(AbstractComponentManager.java:999)
    at org.apache.felix.scr.impl.manager.AbstractComponentManager.collectDependencies(AbstractComponentManager.java:1026)
    at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:935)
    at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:756)
    at org.apache.felix.scr.impl.manager.AbstractComponentManager.enableInternal(AbstractComponentManager.java:666)
    at org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:432)
    at org.apache.felix.scr.impl.manager.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:665)
    at org.apache.felix.scr.impl.BundleComponentActivator.initialEnable(BundleComponentActivator.java:338)
    at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:382)
    at org.apache.felix.scr.impl.Activator.access$200(Activator.java:49)
    at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:264)
    at org.apache.felix.scr.impl.AbstractExtender.createExtension(AbstractExtender.java:196)
    at org.apache.felix.scr.impl.AbstractExtender.modifiedBundle(AbstractExtender.java:169)
    at org.apache.felix.scr.impl.AbstractExtender.addingBundle(AbstractExtender.java:139)
    at org.apache.felix.scr.impl.AbstractExtender.addingBundle(AbstractExtender.java:49)
    at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:475)
    at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:1)
    at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
    at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183)
    at org.osgi.util.tracker.BundleTracker.open(BundleTracker.java:159)
    at org.apache.felix.scr.impl.AbstractExtender.startTracking(AbstractExtender.java:100)
    at org.apache.felix.scr.impl.AbstractExtender.doStart(AbstractExtender.java:92)
    at org.apache.felix.scr.impl.Activator.doStart(Activator.java:172)
    at org.apache.felix.scr.impl.AbstractExtender.start(AbstractExtender.java:72)
    at org.apache.felix.scr.impl.Activator.restart(Activator.java:139)
    at org.apache.felix.scr.impl.config.ScrConfigurationImpl.configure(ScrConfigurationImpl.java:217)
    at org.apache.felix.scr.impl.config.ScrConfigurationImpl.start(ScrConfigurationImpl.java:120)
    at org.apache.felix.scr.impl.Activator.start(Activator.java:100)
    at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:843)
    at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:1)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:835)
    at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:792)
    at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1015)
    at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:365)
    at org.eclipse.osgi.container.Module.doStart(Module.java:605)
    at org.eclipse.osgi.container.Module.start(Module.java:468)
    at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel$2.run(ModuleContainer.java:1845)
    at org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor$1$1.execute(EquinoxContainerAdaptor.java:136)
    at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1838)
    at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1781)
    at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1743)
    at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1665)
    at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:234)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:345)

!ENTRY org.eclipse.osgi 4 0 2021-06-16 18:10:42.291
!MESSAGE Bundle org.eclipse.equinox.simpleconfigurator_1.3.500.v20200211-1505 [2] is not active.

!ENTRY klv-ui 1 0 2021-06-16 18:10:44.278
!MESSAGE Create controls for HelloWorldPart

!ENTRY klv-ui 1 0 2021-06-16 18:10:46.691
!MESSAGE Controls for HelloWorldPart created

I used moongoose webserver sharing the webstart_minimal directory as root and setting in minimal.jnlp.

This Minimal client working on OpenWebstart tells me there is nothing inherentely wrong with my jnlp or build process but in the way Oracle Webstart handles things in comparison to how OpenWebstart handles things (classloading perhaps?).

Our Minimal Client can be downloaded at https://drive.evolit.com/seahub/f/7a525e80a98f4318a791/

We also opened an issue at https://github.com/ECF/JaxRSProviders/issues/39 but so far nobody could solve the issue.

If you have any questions, hints or insights getting this Minimal Application to run using Oracle Webstart with JDK 8 let me know.

4

0 回答 0