有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

由于OSGi捆绑包依赖性问题,java无法启动RCP应用程序

我们在RCP应用程序中同时使用了spring-webspring-websocket,它们都通过p2-maven-plugin转换为bundle。下面是清单。MF我们申请的文件

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"

启动应用程序时,会弹出以下错误:

 !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.

问题似乎是由org.apache.tomcat.embed.tomcat-embed-coreorg.springframework.spring-web都有到javax.servlet的依赖链引起的。但是,在我删除tomcat库之后,它告诉我另一个错误,如下所示:

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)

更新

我所尝试的:

  • 通过检查Eclipse提供的插件依赖项工具中的依赖项(如下面的屏幕截图所示),我发现org.apache.tomcat.embed.tomcat-embed-coreorg.apache.tomcat.embed.tomcat-embed-websocket对我的应用程序可能不是必需的,所以我删除了这两个捆绑包并重新启动了我的应用程序

enter image description here

但是,会出现另一条错误消息,如下所示:

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
  • 此外,在导入这些第三方库时,我还尝试将Require Bundle替换为Import Package,如下所示:

    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
    

但是它仍然会弹出相同的错误通知我org.apache.tomcat.InstanceManagerBindings cannot be found by org.apache.tomcat.embed.tomcat-embed-websocket_8.5.4


共 (2) 个答案

  1. # 1 楼答案

    将版本信息添加到javax.servlet导入包中,以便OSGi可以决定使用哪个依赖链

    javax.servlet;version="3.1.0"
    
  2. # 2 楼答案

    你在这里面临着几个问题。第一个是,您在所有地方都使用requirebundle。require bundle的问题是,您总是暴露于bundle提供的所有包。这将增加违反使用链约束的可能性。您应该尝试改用导入包

    另一个问题是spring不再支持OSGi。因此,在OSGi中使用spring库很可能会产生问题,因为它们根本不在OSGi中测试代码

    如果您需要websocket支持,那么更好的选择可能是pax web。它与tomcat或jetty一起运行,并以OSGi兼容的方式包装它们

    不幸的是,eclipse中没有PaxWeb或普通jetty的示例。要查看您需要什么捆绑包,可以启动ApacheKaraf并安装http功能。然后您可以查看它安装的捆绑包,并在EclipseRCP中使用相同的捆绑包