Jena-osgi 3.0.1 ExceptionInInitializerError processGlobalSystemProperties

Jena-osgi 3.0.1 ExceptionInInitializerError processGlobalSystemProperties

jena-osgi 3.0.1 ModelFactory.createDefaultModel() 当我们在 Eclipse 的 JUNIT (4.11) 环境中 运行 以下代码时抛出 ExceptionInInitializerError:

 // Convert the XML to RDF model
 StringReader stringReader = new StringReader(xml);
 Model model = ModelFactory.createDefaultModel();
 model.read(stringReader, null, RDFLanguages.RDFXML.getLabel());

堆栈跟踪如下:

java.lang.ExceptionInInitializerError
...
Caused by: java.lang.NullPointerException
    at org.apache.jena.tdb.sys.EnvTDB.processGlobalSystemProperties(EnvTDB.java:33)
    at org.apache.jena.tdb.TDB.init(TDB.java:250)
    at org.apache.jena.tdb.sys.InitTDB.start(InitTDB.java:29)
    at org.apache.jena.system.JenaSystem.lambda$init(JenaSystem.java:114)
    at java.util.ArrayList.forEach(ArrayList.java:1249)
    at org.apache.jena.system.JenaSystem.forEach(JenaSystem.java:179)
    at org.apache.jena.system.JenaSystem.forEach(JenaSystem.java:156)
    at org.apache.jena.system.JenaSystem.init(JenaSystem.java:111)
    at org.apache.jena.rdf.model.ModelFactory.<clinit>(ModelFactory.java:49)
    ... 25 more

如果我们使用 jena-tdb 3.0.1 而不是 jena-osgi 3.0.1,同样的代码也可以工作。我们需要在 OSGi 环境 (Servicemix) 中 运行 我们的代码,因此让 OSGi 部分正常工作至关重要。

我在 Stack overflow 中看到过类似的错误报告,但 none 已经解决了我们的问题。我在想也许我们缺少图书馆?这些是我们使用 Maven 导入的 jar:

  1. org.apache.jena:jena-osgi:3.0.1
  2. org.apache.servicemix.bundles:org.apache.servicemix.bundles.xerces:2.11.0_1
  3. com.github.andrewoma.dexx:dexx-collections:0.2
  4. commons-cli:commons-cli:1.3
  5. 公共编解码器:公共编解码器:1.6
  6. commons-io:commons-io:2.4
  7. org.apache.httpcomponents:httpclient-cache:4.2.5
  8. xml-apis:xml-apis:1.4.01

注意:我们尝试使用 Jena 3.1.0 OSGi,它确实有效,但是当 junit 在 maven 中为 运行 时,JSON-LD 变得很奇怪(xml 名称空间前缀被剥离),但在 Eclipse 中工作正常。

您的问题很可能与 Jena 系统初始化有关。它依赖于 ServiceLoader 机制,因此,如果您没有正确的 META-INF/services/ 资源,则只有系统的一部分将被设置,并且像 TDB 这样依赖于其他组件的组件可能无法初始化为结果。

您似乎遇到了与以下邮件列表主题中所述相同的问题 - [http://mail-archives.apache.org/mod_mbox/jena-users/201603.mbox/%3C56E8817D.8080308@apache.org%3E]

建议的解决方案如下:

The default is to use ServiceLoader which looks for META-INF/services/org.apache.jena.system.JenaSubsystemLifecycle

If your setup is a single jar then the contents of this from all modules needs to be combined:

For example, Fuseki, which is a combined jar, has:

org.apache.jena.tdb.sys.InitTDB 
org.apache.jena.riot.system.InitRIOT
org.apache.jena.sparql.system.InitARQ
org.apache.jena.system.InitJenaCore
org.apache.jena.query.text.InitJenaText
org.apache.jena.query.spatial.InitJenaSpatial

It's done in the POM during shading with:

<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"  />

@RobV 的回答提供了正确打包 OSGi 包以包含所有 ServiceLoader 文件的解决方案。

升级到 Jena 3.1.0(专门针对 JENA-1164)是关于在不同 OSGi 框架中查找 ServiceLoader 文件的 jena-osgi 问题的修复。