Java 8和缺失的必需能力 Require-Capability: osgi.ee; filter="(&(osgi.ee=JavaSE)(version=1.8))"

43

我正在使用带有Java 8的Eclipse Luna win32.x86_64。

帮助菜单 > 关于 > 安装详情 > 配置选项卡中得到以下信息:

java.runtime.version=1.8.0_05-b13
java.version=1.8.0_05

我已经创建了一个新的插件项目,请求执行环境为JavaSE-1.8

Plug-in Editor. JavaSE-1.8 as Execution Environment

myplugin/META-INF/MANIFEST.MF文件中,我当然有:

 Bundle-RequiredExecutionEnvironment: JavaSE-1.8

我在产品文件中使用了这个插件。当我尝试对其进行验证时,会出现以下错误:

从产品文件编辑器打开的验证对话框

当然,如果我启动产品,我会得到:

!ENTRY org.eclipse.osgi 2 0 2014-07-10 08:14:22.042
!MESSAGE One or more bundles are not resolved because the following root constraints are not resolved:
!SUBENTRY 1 org.eclipse.osgi 2 0 2014-07-10 08:14:22.043
!MESSAGE Bundle update@********/myplugin/ was not resolved.
!SUBENTRY 2 myplugin 2 0 2014-07-10 08:14:22.044
!MESSAGE Missing required capability Require-Capability: osgi.ee; filter="(&(osgi.ee=JavaSE)(version=1.8))".
我尝试了很多验证方式:
Preferences > Java > Installed JREs 已安装的JRE Preferences > Java > Installed JREs > Execution Environments 执行环境 Preferences > Java > Compiler: JDK Compliance > 编译器兼容级别 编译器 当我启动产品时,在“启动”选项卡中检查使用jre8作为执行环境。
我甚至尝试在“运行配置”对话框中更改Java Runtime Environment: Java运行时环境 我尝试了不同的设置,但都没有起作用。
有什么问题吗?
这是已知问题吗?
8个回答

24
该错误意味着您的捆绑包在其清单中具有“Require-Capability:osgi.ee; filter =“(&(osgi.ee = JavaSE)(version = 1.8))””条目。这意味着当存在提供此功能的捆绑包时,捆绑包将开始运行。
在osgi.ee功能的情况下,应该是OSGi框架(Equinox)提供此功能。显然它没有这样做。
因此,一种方法是从捆绑包清单中删除标题。 另一个方法是使equinox导出该功能。也许您可以尝试最新的equinox版本。不确定这是否有所帮助。 您还可以尝试设置框架属性(使用-D): org.osgi.framework.system.capabilities = osgi.ee; osgi.ee =“JavaSE”; version:List =“1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8”
请参见:

1
谢谢您... 您说得对,我的目标平台上有一台旧的Juno Equinox。 - Jmini
我有Mars.1 Release (4.5.1) Build id: 20150924-1200,但仍然出现这个错误。有效的方法是Christian提到的第一个选项:打开META-INF/MANIFEST.MF,在“Execution Environments”下删除JavaSE-1.8或将其替换为JavaSE-1.7,之后导出(“hello world”)应用程序,它就可以正常启动了。 - nidalpres
2
我在使用Java10时遇到了问题。框架属性应该在哪里设置?是在Eclipse应用程序的运行配置中吗? - Stefan

19
分享我的经验,将基于Juno 3.8.2的目标平台改造成可以使用Bundle-RequiredExecutionEnvironment(“BREE”)JavaSE-1.8运行JUnit插件测试。
失败的方法1:片段
创建一个片段到org.eclipse.osgi,并在清单中使用Provide-Capability头。
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: FrwJava8Support
Bundle-SymbolicName: frwJava8Support
Bundle-Version: 1.0.0.qualifier
Fragment-Host: org.eclipse.osgi;bundle-version="3.8.2"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Provide-Capability: osgi.ee;osgi.ee="JavaSE";version:List="1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8"

这个能力从未被使用。

失败的方法2:启动参数

使用Christian的答案中概述的-Dorg.osgi.framework.system.capabilities

首先,必须正确引用该参数:

-Dorg.osgi.framework.system.capabilities="osgi.ee; osgi.ee=\"JavaSE\";version:List=\"1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8\""

这种方法可能适用于除 pde.junit 之外的任何其他用例。但我仍然收到了这个(略有不同的)异常:
!MESSAGE Bundle com.XXX.tst.frw.common_1.0.0.qualifier [92] was not   resolved.
!SUBENTRY 2 com.XXX.tst.frw.common 2 0 2015-04-18 13:43:55.336
!MESSAGE Missing Constraint: Bundle-RequiredExecutionEnvironment: JavaSE-1.8
!SUBENTRY 1 org.eclipse.osgi 2 0 2015-04-18 13:43:55.336
!MESSAGE Bundle com.XXX.tst.frw.common.test_1.0.0.qualifier [101] was not resolved.
!SUBENTRY 2 com.XXX.tst.frw.common.test 2 0 2015-04-18 13:43:55.336
!MESSAGE Missing host com.XXX.tst.frw.common_1.0.0.

!ENTRY org.eclipse.osgi 4 0 2015-04-18 13:43:55.336
!MESSAGE Application error
!STACK 1
java.lang.IllegalArgumentException: Bundle "com.XXX.tst.frw.common" not found. Possible causes include missing dependencies, too restrictive version ranges, or a non-matching required execution environment.
    at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.getClassLoader(RemotePluginTestRunner.java:77)

工作方法3:修补Equinox

org.eclipse.osgi bundle进行修补,以包括Luna的JavaSE-1.8.profile

  1. 将文件<LUNA>\plugins\org.eclipse.osgi_3.10.1.v20140909-1633.jar\JavaSE-1.8.profile复制到目标平台bundle池中的org.eclipse.osgi bundle中。
    (例如:<myworkspace>\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.eclipse.osgi_3.8.2.v20130124-134944.jar\JavaSE-1.8.profile

  2. profile.list中引用profile(实际上,这似乎是可选的):
    JavaSE-1.8.profile,\添加到.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.eclipse.osgi_3.8.2.v20130124-134944.jar\profile.list

然而,这个解决方案需要托管自己的P2存储库,其中包含org.eclipse.osgi捆绑包或者对每个工作区的捆绑包池应用补丁。
讨论
尽管如此,仍然存在将BREE保持在与现有的org.eclipse.osgi 3.8.2版本兼容的"JavaSE-1.7"的可能性。
我目前知道两个缺点:
通过PDE直接从Eclipse导出插件,如果代码中使用了Java 8语法(例如lambda表达式),则会失败。
日志包含编译器错误,并且编译结果实际上与使用JavaSE-1.8 BREE编译的捆绑包大小不同。
据推测,PDE评估BREE并相应地设置编译器源级别,这将导致Java 8源的"1.7"。其他PDE功能(特性导出、产品导出)可能会出现同样的问题。

使用Eclipse Tycho,可以手动覆盖javac源级别,而不是评估包的BREE(选择要编译的JDK)。然而,Tycho仍会匹配给定的源级别与BREE,并拒绝编译Java 8代码(使用Tycho 0.22进行测试)。

此外,第二种方法很可能无法与PDE的捆绑包导出一起使用,至少我不知道有任何传递VM参数的可能性。

2015年5月29日更新

我们采用了第三种方法,成功地修补了我们的目标平台,使其与Eclipse 3.8一起使用Java 8。

由于我们已经维护了自己的带有所有基于3.8的Eclipse插件的P2存储库,因此我们需要:

  • 创建一个更新的org.eclipse.osgi副本(还需要从bundle中去掉签名信息)
  • 创建一个功能补丁,使用更新的org.eclipse.osgi bundle来修补org.eclipse.rcp功能
  • 发布新的基于3.8的P2存储库,供我们的工作站和构建服务器使用。

摘要

如果您维护自己的P2仓库来为自定义目标平台提供服务,而不是使用任何基于Eclipse.org的更新站点,则可以使Eclipse 3.8与Java 8配合使用。
参考文献:Eclipse Bug to support osgi.ee

对于传统产品而言,这是比移除必需的头文件并希望一切顺利或者调整启动参数更好的解决方案。 - hiergiltdiestfu
1
谢谢你的回答!我也使用了第三种方法,并且它适用于基于3.8.2的RCP应用程序的命令行PDE构建。但是,对我来说,更新profile.list文件是必需的。 - Ivan Senic
1
有一个问题,我们遵循了第三种方法,但现在PDE构建无法编译Java 1.8源代码级别的文件(例如lambda表达式)。似乎PDE构建属性javacSource=1.8和javacTarget=1.8完全被忽略了。对此有什么建议吗? - Ivan Senic
抱歉,我们正在使用Maven Tycho进行构建。 您尝试在MANIFEST.MF中将bundle的BREE(Bundle Required Execution Environment)设置为1.8了吗? - Henrik Steudel
我们试过了,不起作用。我猜可能需要在某个地方打补丁,但是我们找不到合适的位置。还有其他的想法吗? - Ivan Senic
1
对我们有效!我已经上传了一个修补过的3.8.2 osgi库:https://github.com/hacki11/osgi-3.8.2-jre1.8 - Juergen

4

一个简单的解决方法是包含org.eclipse.equinox.ds(equinox声明式服务)。该运行时bundle导出所需的osgi.extender,并似乎不会触发任何额外的依赖项。


这里的 org.eclipse.equinox.ds 依赖于 org.apache.felix.scr。添加后者解决了问题。 - ocroquette
除了org.eclipse.equinox.ds之外,必须手动添加org.eclipse.equinox.event - lolung
“Add Required Plug-ins” 似乎出错了:https://bugs.eclipse.org/bugs/show_bug.cgi?id=494913 - lolung

3
我找到了一个配置,只需少量工作就可以正常运行。您需要在产品文件、项目设置和构建路径中选择Java 8。重要的是清单文件。在这里,您必须同时选择Java 8和Java 7。这里的顺序也很重要。Java 8必须位于顶部。
我认为此配置有效的原因是编译器选择第一个JRE,因此可以处理Java 8的新语法。Eclipse捆绑包会检查是否有所需的Java 7条目,并且也会满足要求。

非常感谢您的提示。我认为这可能是我正在寻找的答案! - atom88

1
我在Felix 5.6.10版本中发现了导致我的问题的问题所在:
"Missing required capability Require-Capability: osgi.ee; filter="(&(osgi.ee=JavaSE)(version=1.8))"
这是创建问题的代码。 它在ExtensionManager的构造函数中。
String pkgextra =
        "true".equalsIgnoreCase(configProps.getProperty(FelixConstants.USE_PROPERTY_SUBSTITUTION_IN_SYSTEMPACKAGES)) ?
            Util.getPropertyWithSubs(configProps, FelixConstants.FRAMEWORK_SYSTEMPACKAGES_EXTRA) :
            configProps.getProperty(FelixConstants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
    syspkgs = ((pkgextra == null) || (pkgextra.trim().length() == 0))
        ? syspkgs : syspkgs + (pkgextra.trim().startsWith(",") ? pkgextra : "," + pkgextra);

将最后一行修改为:
    syspkgs = ((pkgextra == null) || (pkgextra.trim().length() == 0))
        ? syspkgs : syspkgs + (pkgextra.trim().startsWith(",") ? pkgextra.substring(1) : pkgextra);

问题的原因在于,在构造函数的稍后部分,我们找到了以下代码:
try
{
    ManifestParser mp = new ManifestParser(
        m_logger, m_configMap, m_systemBundleRevision, m_headerMap);
    List<BundleCapability> caps = aliasSymbolicName(mp.getCapabilities());
    caps.add(buildNativeCapabilites());
    appendCapabilities(caps);
}
catch (Exception ex)
{

没有进行更正的话,ManifestParser构造函数调用会抛出异常,抱怨导出的能力不能为空。在syspkgs中多余的逗号让解析器认为缺少某些能力。
一旦您在try块中失败,就无法将主机osgi.ee功能添加到框架中,这意味着您无法解决像(&(osgi.ee=JavaSE)(version=1.8))这样的请求。
只是为了明确起见,我指的是具体版本:
org.apache.felix:org.apache.felix.framework:5.6.10

这个问题只会在你的配置中添加了额外的系统功能(就像我一样)时才会出现。这可能解释了为什么有些人遇到这个问题,而其他人则没有。
我已经应用了修补程序,过滤器再次正常工作。

1

那对我来说就是这样了。 - Ayman Salah

0

我在liferay dxp中遇到了这个错误。我已经更改了liferay工作区,现在它可以正常工作。


0

我有同样的问题:缺少必需的能力 Require-Capability: osgi.ee; filter="(&(osgi.ee=JavaSE)(version=1.8))

我正在使用 Felix 5.6.10

这是我发现的一个有趣的事情: 我创建了两个包含以下 MANIFEST.MF 的 test.jar 包

test1.jar Manifest-Version: 1.0 Bundle-Description: 用于测试的捆绑软件 Bundle-SymbolicName: com.phinneyridge.testbundle Bundle-Version: 0.0.1 Bundle-Name: testbundle Bundle-ManifestVersion: 2 Require-Capability: osgi.ee=JavaSE; version="1.8" Created-By: 1.8.0_131 (Oracle Corporation)

test2.jar: Manifest-Version: 1.0 Bundle-Description: 用于测试的捆绑软件 Bundle-SymbolicName: com.phinneyridge.testbundle Bundle-Version: 0.0.2 Bundle-Name: testbundle Bundle-ManifestVersion: 2 Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version 1.8))" Created-By: 1.8.0_131 (Oracle Corporation)

正如您所看到的,这两个捆绑包仅在Bundle-Version和所需功能的指定方式上有所不同。

结果是: test1.jar可以很好地安装 当您尝试安装test2.jar时,会出现缺少要求的消息。

因此,在我的Felix OSGi框架中使用Require-Capability头中的过滤器存在问题。它是否不受支持?还是我需要配置一些内容以启用过滤器?显然,这并不是因为我的框架未配置所需的osgi.ee功能(test1.jar有效)。

显然,这意味着如果我纠正了故障捆绑包中的Require-Capability头,我就有了一个解决方法。(如果您从开放存储库安装捆绑包,则不是一个好的解决方案。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接