【问题标题】:Jena TDB java.lang.ExceptionInInitializerErrorJena TDB java.lang.ExceptionInInitializerError
【发布时间】:2016-04-20 21:49:28
【问题描述】:

我正在使用 Jena TDB 加载 RDF 数据集并对它进行 SPARQL 查询。我正在使用以下 Maven 依赖项:

<dependency>
    <groupId>org.apache.jena</groupId>
    <artifactId>apache-jena-libs</artifactId>
    <type>pom</type>
    <version>3.0.1</version>
</dependency>

这是我尝试创建 TDB 数据集的 java 代码:

public void loadDirectory(String outputFile){      
    Dataset dataset = TDBFactory.createDataset(directoryPath);      
    Model tdb = dataset.getDefaultModel();      
    FileManager.get().readModel(tdb, outputFile);      
    tdb.close();      
    dataset.close();      
    LOG.info("RDF dataset loaded to memory");      
}      

函数的第一行失败:TDBFactory.createDataset( directoryPath ) 并带有以下错误消息:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at org.sdw.model.JenaModel.loadDirectory(JenaModel.java:69)
    at org.sdw.Main.main(Main.java:75)
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$40(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.tdb.TDBFactory.<clinit>(TDBFactory.java:40)

【问题讨论】:

  • 只要运行该代码,该代码就可以正常工作。环境中可能还有更多。当 Jena jar 重新捆绑(例如 OSGi)或重新打包并且 META-INF/services/org.apache.jena.system.JenaSubsystemLifecycle 文件未正确合并时,通常会发生此错误。
  • 请提供一个完整的最小示例。其他人可以不加改变地运行的内容,不包含说明问题所需的内容。
  • 代码没有将数据加载到内存中。
  • @AndyS,代码在使用 eclipse 时运行良好,但在从终端启动时出现此异常。我猜 Eclipse 正在自行捆绑/解决使用终端时不会发生的事情。我尝试从不同的系统启动它,但问题仍然存在。您可以从这里重现问题github.com/gone-phishing/SDW
  • 我遇到了同样的问题,我不明白如何解决这个问题,我可以寻求帮助吗?

标签: java maven-3 jena apache-jena tdb


【解决方案1】:

POM 使用阴影插件。它需要使用 ServicesResourceTransformer 转换器来管理服务文件(META_INF/services/)。

将以下转换后的内容添加到您的 POM 文件中:

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

参见&lt;transformers&gt;,例如:https://github.com/apache/jena/blob/master/jena-fuseki2/jena-fuseki-server/pom.xml

【讨论】:

  • 我明白了,我犯了一个愚蠢的错误。感谢您帮助我:)
  • @Andys 嗨,那么解决方案是什么?我遇到了同样的问题。如何解决它。特别是我正在使用 sbt,并构建一个组装 jar。
  • 查看github.com/apache/jena/blob/master/jena-fuseki2/… -- 结合了ServiceLoader 文件的ServicesResourceTransformer。如果您需要手动执行此操作,因为 SBT 不能,则为所有 jar 连接 META_INF/services/ 下的文件。
  • 我遇到了同样的问题,我不明白如何解决这个问题,我可以寻求帮助吗?
  • @Noor 打开答案中提到的链接,并将第 78 行添加到 maven shade 插件部分的 POM 文件中,如上面的链接所示。应该可以正常工作:)
【解决方案2】:

我遇到了同样的问题,发现接受的答案通常是正确的,但并不完整(至少我花了很长时间才弄清楚如何正确应用答案的提示)。这是它的工作原理。

1) 您必须将 maven-shade 插件添加到 pom.xml 中,如示例所示。在:https://github.com/apache/jena/blob/master/jena-fuseki2/jena-fuseki-server/pom.xml

2) 更改插件配置中主类的链接。主类通过以下几行提供:

<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
          <mainClass>org.apache.jena.fuseki.cmd.FusekiCmd</mainClass>
</transformer>

你必须在mainClass 标签中添加你的主类。现在使用 maven build 命令构建项目时,您将获得一个名为 your-project-name-VERSION.jar 的 jar,这是您想要的可运行 jar。如果您以前使用过“带有依赖项的 jar”,请确保运行新的(名称中不再包含“带有依赖项”),否则您将遇到同样的问题。

【讨论】:

  • 它在 GitHub 链接的第 65 行,这是已接受答案的一部分
【解决方案3】:

接受的答案实际上缺少解决方案。 所以这里是:

链接文件为:https://github.com/apache/jena/blob/master/jena-fuseki2/jena-fuseki-server/pom.xml

当然,你应该从中得到什么?

这是您应该添加到 pom 中的完整片段:

<build>     
<plugins>     
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.1</version>

    <executions>    
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
        <configuration>
          <transformers>
            <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
              <mainClass>com.example.MainClass</mainClass>
            </transformer>
          </transformers>
        </configuration>
      </execution>
    </executions>
  </plugin>
</plugins>
</build>

记得用你的主类替换com.example.MainClass

【讨论】:

  • 我认为上面的代码是接受的答案中提到的链接的一部分。但感谢您在此处指定以供将来参考!
  • 嗯,链接上的 100 多行代码中很少有有意义的行,您需要弄清楚哪些要保留,哪些不能保留。我发现了这个问题,因为我遇到了这个问题,我花了 30 分钟,4 次试探,并在这里从其他答案和 cmets 中合并 cmets,然后才想出那个片段。所以,我认为没有代码的答案是不完整的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多