Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't start RCP application due to OSGi bundle dependency issue

We are using both spring-web and spring-websocket in our RCP application, which are both converted into bundles through the p2-maven-plugin. Below is the MANIFEST.MF file of our application.

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Todo
Bundle-SymbolicName: com.example.e4.rcp.todo;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: EXAMPLE
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: org.apache.commons.logging;bundle-version="1.2.0",
 org.springframework.spring-aop;bundle-version="4.3.3",
 org.springframework.spring-beans;bundle-version="4.3.3",
 org.springframework.spring-context;bundle-version="4.3.3",
 org.springframework.spring-core;bundle-version="4.3.3",
 org.springframework.spring-expression;bundle-version="4.3.3",
 org.springframework.spring-web;bundle-version="4.3.3",
 org.eclipse.e4.ui.css.swt;bundle-version="0.12.0",
 org.eclipse.e4.ui.css.swt.theme;bundle-version="0.10.0",
 org.eclipse.e4.ui.workbench.addons.swt;bundle-version="1.2.0",
 org.eclipse.e4.ui.workbench.renderers.swt;bundle-version="0.13.0",
 org.eclipse.e4.ui.workbench.swt;bundle-version="0.13.0",
 org.eclipse.swt;bundle-version="3.104.1",
 org.eclipse.e4.ui.di;bundle-version="1.1.0",
 org.eclipse.e4.core.services;bundle-version="2.0.100",
 org.eclipse.osgi.services;bundle-version="3.5.100",
 org.eclipse.e4.core.di.annotations;bundle-version="1.5.0",
 org.springframework.spring-websocket;bundle-version="4.3.2",
 org.springframework.spring-messaging;bundle-version="4.3.2",
 javax.inject;bundle-version="1.0.0",
 javax.annotation;bundle-version="1.2.0",
 org.apache.tomcat.embed.tomcat-embed-core;bundle-version="8.5.4",
 org.apache.tomcat.embed.tomcat-embed-websocket;bundle-version="8.5.4"

When I start the application, it popups the following error:

 !SESSION 2016-11-10 09:48:03.750 -----------------------------------------------
 eclipse.buildId=unknown
 java.version=1.8.0_101
 java.vendor=Oracle Corporation
 BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=en_US
 Framework arguments:  -product com.example.e4.rcp.todo.product clearPersistedState
 Command-line arguments:  -product com.example.e4.rcp.todo.product -data > :\Users\wangzen\Console_prototype/../runtime-todo.product -dev > ile:C:/Users/wangzen/Console_prototype/.metadata/.plugins/org.eclipse.pde.core/to> o.product/dev.properties -os win32 -ws win32 -arch x86_64 -consoleLog > clearPersistedState

 !ENTRY org.eclipse.equinox.app 0 0 2016-11-10 09:48:04.703
 !MESSAGE Product com.example.e4.rcp.todo.product could not be found.

 !ENTRY com.example.e4.rcp.todo 2 0 2016-11-10 09:48:04.786
 !MESSAGE Could not resolve module: com.example.e4.rcp.todo [491]
   Bundle was not resolved because of a uses contraint violation.
   org.osgi.service.resolver.ResolutionException: Uses constraint violation. nable>  to resolve resource com.example.e4.rcp.todo [osgi.identity;>  sgi.identity="com.example.e4.rcp.todo"; type="osgi.bundle";>  ersion:Version="1.0.0.qualifier"; singleton:="true"] because it is exposed to>  ackage 'javax.servlet' from resources rg.apache.tomcat.embed.tomcat-embed-core>  [osgi.identity; type="osgi.bundle"; ersion:Version="8.5.4";>  sgi.identity="org.apache.tomcat.embed.tomcat-embed-core"] and javax.servlet>  osgi.identity; type="osgi.bundle"; version:Version="3.1.0.v201410161800";>  sgi.identity="javax.servlet"] via two dependency chains.

 Chain 1:
   com.example.e4.rcp.todo [osgi.identity; sgi.identity="com.example.e4.rcp.todo";>  type="osgi.bundle"; ersion:Version="1.0.0.qualifier"; singleton:="true"]
     require:>  &(osgi.wiring.bundle=org.apache.tomcat.embed.tomcat-embed-core)(bundle-versio> >=8.5.4))
      |
     provide: osgi.wiring.bundle: org.apache.tomcat.embed.tomcat-embed-core
   org.apache.tomcat.embed.tomcat-embed-core [osgi.identity; ype="osgi.bundle";>  version:Version="8.5.4";>  sgi.identity="org.apache.tomcat.embed.tomcat-embed-core"]

 Chain 2:
   com.example.e4.rcp.todo [osgi.identity; sgi.identity="com.example.e4.rcp.todo";>  type="osgi.bundle"; ersion:Version="1.0.0.qualifier"; singleton:="true"]
     require:>  &(osgi.wiring.bundle=org.springframework.spring-web)(bundle-version>=4.3.3))
      |
     provide: osgi.wiring.bundle; bundle-version:Version="4.3.3.RELEASE";>  sgi.wiring.bundle="org.springframework.spring-web"
   org.springframework.spring-web [osgi.identity; type="osgi.bundle";>  ersion:Version="4.3.3.RELEASE"; osgi.identity="org.springframework.spring-web"]
     import: (osgi.wiring.package=javax.servlet)
      |
     export: osgi.wiring.package: javax.servlet
   javax.servlet [osgi.identity; type="osgi.bundle";>  ersion:Version="3.1.0.v201410161800"; osgi.identity="javax.servlet"]

 !ENTRY org.eclipse.osgi 4 0 2016-11-10 09:48:04.787
 !MESSAGE Application error
!STACK 1
java.lang.RuntimeException: No application id has been found.
    at org.eclipse.equinox.internal.app.EclipseAppContainer.startDefaultApp(EclipseAppContainer.java:242)
    at org.eclipse.equinox.internal.app.MainApplicationLauncher.run(MainApplicationLauncher.java:29)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1519)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1492)
gogo: InterruptedException: sleep interrupted
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at org.apache.felix.gogo.shell.Activator.run(Activator.java:72)
    at java.lang.Thread.run(Thread.java:745)
An error has occurred. See the log file
C:\Users\wangzen\runtime-todo.product\.metadata\.log.

It seems the problem is caused by both org.apache.tomcat.embed.tomcat-embed-core and org.springframework.spring-web have dependency chain to javax.servlet. However after I removed the tomcat libraries, it tells me another error as below:

java.lang.NoClassDefFoundError: org/apache/tomcat/InstanceManagerBindings
    at org.apache.tomcat.websocket.WsSession.<init>(WsSession.java:187)
    at org.apache.tomcat.websocket.WsWebSocketContainer.connectToServer(WsWebSocketContainer.java:403)
    at org.springframework.web.socket.client.standard.StandardWebSocketClient$1.call(StandardWebSocketClient.java:150)
    at org.springframework.web.socket.client.standard.StandardWebSocketClient$1.call(StandardWebSocketClient.java:147)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: org.apache.tomcat.InstanceManagerBindings cannot be found by org.apache.tomcat.embed.tomcat-embed-websocket_8.5.4
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:448)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:361)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:353)
    at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

UPDATE

What I've tried:

  • By checking the dependencies from Plug-in Dependencies tool offered by Eclipse, which shows as following screenshot, I found that org.apache.tomcat.embed.tomcat-embed-core and org.apache.tomcat.embed.tomcat-embed-websocket might not be necessary for my application, so I removed these two bundles and restart my application.

enter image description here

However there comes another error message as below:

java.lang.NoClassDefFoundError: org/apache/tomcat/InstanceManagerBindings
    at org.apache.tomcat.websocket.WsSession.<init>(WsSession.java:187)
    at org.apache.tomcat.websocket.WsWebSocketContainer.connectToServer(WsWebSocketContainer.java:403)
    at org.springframework.web.socket.client.standard.StandardWebSocketClient$1.call(StandardWebSocketClient.java:150)
    at org.springframework.web.socket.client.standard.StandardWebSocketClient$1.call(StandardWebSocketClient.java:147)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: org.apache.tomcat.InstanceManagerBindings cannot be found by org.apache.tomcat.embed.tomcat-embed-websocket_8.5.4
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:448)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:361)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:353)
    at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 6 more
  • Also I tried replacing Require-Bundle with Import-Package when importing these third party libraries as following:

    Manifest-Version: 1.0
    Bundle-ManifestVersion: 2
    Bundle-Name: Todo
    Bundle-SymbolicName: com.example.e4.rcp.todo;singleton:=true
    Bundle-Version: 1.0.0.qualifier
    Bundle-Vendor: EXAMPLE
    Bundle-RequiredExecutionEnvironment: JavaSE-1.8
    Require-Bundle: org.eclipse.e4.ui.css.swt;bundle-version="0.12.0",
     org.eclipse.e4.ui.css.swt.theme;bundle-version="0.10.0",
     org.eclipse.e4.ui.workbench.addons.swt;bundle-version="1.2.0",
     org.eclipse.e4.ui.workbench.renderers.swt;bundle-version="0.13.0",
     org.eclipse.e4.ui.workbench.swt;bundle-version="0.13.0",
     org.eclipse.swt;bundle-version="3.104.1",
     org.eclipse.e4.ui.di;bundle-version="1.1.0",
     org.eclipse.e4.core.services;bundle-version="2.0.100",
     org.eclipse.osgi.services;bundle-version="3.5.100",
     org.eclipse.e4.core.di.annotations;bundle-version="1.5.0",
     javax.inject;bundle-version="1.0.0",
     javax.annotation;bundle-version="1.2.0"
    Import-Package: org.apache.tomcat,
     org.springframework.http,
     org.springframework.http.client,
     org.springframework.http.client.support,
     org.springframework.messaging.converter,
     org.springframework.messaging.simp.stomp,
     org.springframework.scheduling,
     org.springframework.scheduling.concurrent,
     org.springframework.util,
     org.springframework.web.client,
     org.springframework.web.socket.client,
     org.springframework.web.socket.client.standard,
     org.springframework.web.socket.messaging,
     org.springframework.web.socket.sockjs.client
    

However it still popup the same error notify me that org.apache.tomcat.InstanceManagerBindings cannot be found by org.apache.tomcat.embed.tomcat-embed-websocket_8.5.4

like image 968
kenshinji Avatar asked Nov 10 '16 02:11

kenshinji


1 Answers

You are facing several problems here. The first one is that you use require bundle all over the place. The problem with require bundle is that you are always exposed to all packages a bundle offers. This will increase the probability of uses chain contraint violations. You should try to use Import-Package instead.

The other problem is that spring does not support OSGi anymore. So using spring libraries in OSGi is very likely to create problems as they simply do not test their code in OSGi.

If you need websocket support then a better choice might be pax web. It runs with tomcat or jetty and wraps them in an OSGi compatbile way.

Unfortunately there is no example for pax-web or plain jetty in eclipse. To see what bundles you need you can start apache karaf and install the http feature. Then you can look into the bundles it installs and use the same in eclipse rcp.

like image 155
Christian Schneider Avatar answered Sep 30 '22 06:09

Christian Schneider