Felix GoGo Shell抛出MalformedURLException:未知协议:Equinox中的bundle



我正在编写一个名为ZAP的Java应用程序的扩展。扩展是一个fat/uber jar,它内联了Equinox bundle(org.eclipse.osgi)。另外的bundle也包含在这个jar中的子目录bundles中。OSGi框架正在启动,如How To Embed OSGi中所述。

按照Eclipse的"控制台外壳"文档中概述的步骤,我正在尝试让Felix GoGo外壳正常工作。它指定了以下所需的捆绑包:

  • org.apache.felix.gogo.command
  • org.apache.felix.gogo.runtime
  • org.apache.felix.gogo.shell
  • org.eclipse.equinox.console

除了春分/org.eclipse.osgi。由于Equinox不在类路径上,我将org.osgi.framework.system.packages.extra配置设置为Equinox的bundle指定的Export-Package值,在这里可见。

一旦框架处于ACTIVE状态,我就会在Eclipse中看到以下堆栈跟踪(或通过Eclipse外部的命令行):

Starting OSGi framework...
OSGi framework state: 32
gogo: MalformedURLException: unknown protocol: bundleresource
java.net.MalformedURLException: unknown protocol: bundleresource
  at java.net.URL.<init>(URL.java:593)
  at java.net.URL.<init>(URL.java:483)
  at java.net.URL.<init>(URL.java:432)
  at java.net.URI.toURL(URI.java:1089)
  at org.apache.felix.gogo.shell.Shell.readScript(Shell.java:209)
  at org.apache.felix.gogo.shell.Shell.source(Shell.java:192)
  at org.apache.felix.gogo.shell.Shell.gosh(Shell.java:109)
  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:497)
  at org.apache.felix.gogo.runtime.Reflective.invoke(Reflective.java:137)
  at org.apache.felix.gogo.runtime.CommandProxy.execute(CommandProxy.java:82)
  at org.apache.felix.gogo.runtime.Closure.executeCmd(Closure.java:477)
  at org.apache.felix.gogo.runtime.Closure.executeStatement(Closure.java:403)
  at org.apache.felix.gogo.runtime.Pipe.run(Pipe.java:108)
  at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:183)
  at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:120)
  at org.apache.felix.gogo.runtime.CommandSessionImpl.execute(CommandSessionImpl.java:89)
  at org.apache.felix.gogo.shell.Activator.run(Activator.java:75)
  at java.lang.Thread.run(Thread.java:745)

GoGo似乎没有使用Equinox URL处理程序。我注意到以下与它们相关的软件包不在Equinox的Export-Package:中

  • org.eclipse.osgi.storage.url
  • org.eclipse.osgi.storage.url.bundleresource
  • org.eclipse.osgi.storage.url.bundleentry

因此,我也将它们包含在org.osgi.framework.system.packages.extra包列表中。那也无济于事。

捆绑包的安装和启动没有任何明显的错误。

如何让GoGo利用Equinox的自定义URL处理程序?

更新1:也许是红鲱鱼

在随机故障排除中,我想执行这里概述的最后一个着色jar。我在同一目录中复制了原始的org.eclipse.osgi捆绑包和带阴影的jar。有一个configuration/config.ini指定要加载的捆绑包。

执行库存捆绑会弹出控制台:

$ java -cp ~/.p2/pool/plugins/org.eclipse.osgi_3.11.0.v20160121-2005.jar org.eclipse.core.runtime.adaptor.EclipseStarter -console
osgi> ss
"Framework is launched."

id  State       Bundle
0 ACTIVE      org.eclipse.osgi_3.11.0.v20160121-2005
1 ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036
2 ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215
3 ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605
4 ACTIVE      org.eclipse.equinox.console_1.1.200.v20150929-1405
osgi> exit
Really want to stop Equinox? (y/n; default=y)

执行阴影罐子,不那么多:

java -cp semiotics-alpha-1.zap org.eclipse.core.runtime.adaptor.EclipseStarter -console
java.lang.NullPointerException: A null service reference is not allowed.
  at org.eclipse.osgi.internal.framework.BundleContextImpl.getService(BundleContextImpl.java:617)
  at org.eclipse.core.runtime.adaptor.EclipseStarter.startup(EclipseStarter.java:299)
  at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:231)
  at org.eclipse.core.runtime.adaptor.EclipseStarter.main(EclipseStarter.java:208)

这可能完全是转移注意力。。。我对OSGi非常无知,这是我第一次使用它。然而,我希望着色jar的执行方式与股票Equinox jar没有什么不同。既然我不明白为什么会有区别,我就去挖那里,因为没有更好的地方可以挖。。。

更新2:Equinox关于Classpath工作解决问题

我通过其lib目录将Equinox捆绑包添加到ZAP的类路径中,并将其从内联到扩展jar中删除。这样做并将ServiceLoader.load调用调整为不包括类加载器(默认为系统类加载器)有效:

Starting bundle: org.apache.felix.gogo.shell_0.10.0.v201212101605 [1]
Starting bundle: org.eclipse.equinox.console_1.1.100.v20141023-1406 [2]
Starting bundle: org.apache.felix.gogo.command_0.10.0.v201209301215 [3]
Starting bundle: org.eclipse.emf.ecore_2.11.2.v20160208-0816 [4]
Starting bundle: org.eclipse.emf.common_2.11.1.v20160208-0816 [5]
Starting bundle: org.apache.felix.gogo.runtime_0.10.0.v201209301036 [6]
osgi> ss
"Framework is launched."

id  State       Bundle
0 ACTIVE      org.eclipse.osgi_3.11.0.v20160121-2005
1 ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605
2 ACTIVE      org.eclipse.equinox.console_1.1.100.v20141023-1406
3 ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215
4 ACTIVE      org.eclipse.emf.ecore_2.11.2.v20160208-0816
5 ACTIVE      org.eclipse.emf.common_2.11.1.v20160208-0816
6 ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036
osgi> 

潜在的问题可能是jar是如何内联的,可能与MANIFEST.MF文件有关。可能相关,我现在不需要提供org.osgi.framework.system.packages.extra的值。

我将不回答这个问题,因为最初的目的是将OSGi库作为一个着色工件来包含。也许bndtools能帮上忙?

好吧,似乎缺乏描述性的META-INF/MANIFEST.MF是罪魁祸首:

  • 删除(jar uM...),然后更新(jar um...)阴影jar的MANIFEST.MF,使其成为Equinox清单的副本,修改Bundle-Version编号,使其以1766结束,而不是以1700结束
  • 从ZAP的类路径中删除了Equinox

然后我按原样加载扩展。GoGo shell启动:

osgi> 13177 [AWT-EventQueue-0] INFO org.parosproxy.paros.control.Control  - New Session
ss
"Framework is launched."

id  State       Bundle
0 ACTIVE      org.eclipse.osgi_3.10.102.v20160118-1766
1 ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036
2 ACTIVE      org.eclipse.emf.common_2.11.1.v20160208-0816
3 ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605
4 ACTIVE      org.eclipse.equinox.console_1.1.100.v20141023-1406
5 ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215
6 ACTIVE      org.eclipse.emf.ecore_2.11.2.v20160208-0816
osgi> 

我看到系统捆绑包以相同的修改版本号结束,所以它是为了纪念添加的MANIFEST.MF。因此,根本问题是一个不完整的系统捆绑包清单。复制现有的一个(Equinox的)就足够了。它也适用于直接的命令行测试:

$ java -cp semiotics-alpha-1.zap org.eclipse.core.runtime.adaptor.EclipseStarter -console
osgi> exit
Really want to stop Equinox? (y/n; default=y)  y

不知道我是否会使用这种方法。如果我想使用这种方法,至少我知道我需要做什么。

相关内容

  • 没有找到相关文章

最新更新