2016-12-01 25 views
3

我有一个HTTPRepository用存储库的URL初始化。我使用RepositoryConnection来检索和添加(天气)数据到存储库。数据从Web服务中检索,然后转换为RDF语句,并添加到存储库中。这是由独立应用程序定期完成的。RDF4J RIO UnsupportedRDFormatException当使用独立应用程序将数据添加到HTTPRepository

当我在IntelliJ中运行此应用程序时,一切工作正常。

要在服务器上运行此应用程序,我创建了一个jar文件(包含所有依赖项)。该应用程序按预期启动,并且能够从存储库中检索数据

然而,当应用程序试图写入数据到存储库我得到一个UnsupportedRDFormatException

org.eclipse.rdf4j.rio.UnsupportedRDFormatException: Did not recognise RDF format object BinaryRDF (mimeTypes=application/x-binary-rdf; ext=brf) 
    at org.eclipse.rdf4j.rio.Rio.lambda$unsupportedFormat$0(Rio.java:568) ~[weatherData-1.0-SNAPSHOT-jar-with-dependencies.jar:na] 
    at java.util.Optional.orElseThrow(Optional.java:290) ~[na:1.8.0_111] 
    at org.eclipse.rdf4j.rio.Rio.createWriter(Rio.java:134) ~[weatherData-1.0-SNAPSHOT-jar-with-dependencies.jar:na] 
    at org.eclipse.rdf4j.rio.Rio.write(Rio.java:371) ~[weatherData-1.0-SNAPSHOT-jar-with-dependencies.jar:na] 
    at org.eclipse.rdf4j.rio.Rio.write(Rio.java:324) ~[weatherData-1.0-SNAPSHOT-jar-with-dependencies.jar:na] 
    at org.eclipse.rdf4j.repository.http.HTTPRepositoryConnection.addModel(HTTPRepositoryConnection.java:588) ~[weatherData-1.0-SNAPSHOT-jar-with-dependencies.jar:na] 
    at org.eclipse.rdf4j.repository.http.HTTPRepositoryConnection.flushTransactionState(HTTPRepositoryConnection.java:662) ~[weatherData-1.0-SNAPSHOT-jar-with-dependencies.jar:na] 
    at org.eclipse.rdf4j.repository.http.HTTPRepositoryConnection.commit(HTTPRepositoryConnection.java:326) ~[weatherData-1.0-SNAPSHOT-jar-with-dependencies.jar:na] 
    at org.eclipse.rdf4j.repository.base.AbstractRepositoryConnection.conditionalCommit(AbstractRepositoryConnection.java:366) ~[weatherData-1.0-SNAPSHOT-jar-with-dependencies.jar:na] 
    at org.eclipse.rdf4j.repository.base.AbstractRepositoryConnection.add(AbstractRepositoryConnection.java:431) ~[weatherData-1.0-SNAPSHOT-jar-with-dependencies.jar:na] 
    at nl.wur.fbr.data.weather.WeatherApp.retrieveData(WeatherApp.java:122) ~[weatherData-1.0-SNAPSHOT-jar-with-dependencies.jar:na] 
    at nl.wur.fbr.data.weather.WeatherData$WeatherTask.run(WeatherData.java:105) [weatherData-1.0-SNAPSHOT-jar-with-dependencies.jar:na] 
    at java.util.TimerThread.mainLoop(Timer.java:555) [na:1.8.0_111] 
    at java.util.TimerThread.run(Timer.java:505) [na:1.8.0_111] 

在发生错误的源代码是:

public void retrieveData(){ 
     logger.info("Retrieving data for weather for app: "+ID+" "); 
     RepositoryConnection connection = null; 
     ValueFactory vf = SimpleValueFactory.getInstance(); 
     try { 
      connection = repository.getConnection(); 

      // Retrieving the locations from the repository (no problem here). 
      List<Location> locations = this.retrieveLocations(connection); 
      List<Statement> statements = new ArrayList<>(); 

      // Retrieving weather data from each location and transforming it to statements. 
      for(Location location : locations){ 
       List<Weather> retrievedWeather = weatherService.retrieveWeatherData(location.name,location.latitude,location.longitude); 
       for(Weather weather : retrievedWeather){ 
        BNode phenomenon = vf.createBNode(); 
        statements.add(vf.createStatement(location.ID,WEATHER.HAS_WEATHER,phenomenon,rdfStoreGraph)); 
        statements.addAll(weather.getStatements(phenomenon,vf,rdfStoreGraph)); 
        statements = this.correctOMIRIs(statements,vf); 
       } 
      } 

      // Adding data retrieved from the weather API 
      // This is where the exception happens. 
      connection.add(statements,rdfStoreGraph); 

     } catch (Exception e) { 
      logger.error("Could not retrievedata for weather app: '"+ID+"' because no monitor locations could be found.",e); 
     } finally { 
      if(connection != null){ 
       connection.close(); 
      } 
     } 
    } 

HTTPRespository是初始化为:

 repository = new HTTPRepository(rdfStore.toString()); 
     ((HTTPRepository)repository).setPreferredRDFFormat(RDFFormat.BINARY); 
     ((HTTPRepository)repository).setPreferredTupleQueryResultFormat(TupleQueryResultFormat.BINARY); 

我试过将格式更改为TURTLE。但它没有区别。

你能告诉我如何解决这个问题吗?

注意: RDF4J服务器和库都有版本2.0.1(rdf4j)。

回答

4

要在服务器上运行此应用程序,我创建了一个jar文件(包含所有依赖项)。

存在您的问题:您创建了一个“胖罐子”,可能没有正确合并SPI注册表文件。

RDF4J的Rio解析器(以及其他一些模块)使用Java的服务提供者接口(SPI)机制来注册自己。此机制依赖于包含每个解析器实现的完全限定名的jar文件中META-INF\services中的文本文件。

问题出现在合并罐子时:每个Rio解析器jar都有一个注册表文件,其名称相同,但内容不同。如果你正在使用类似maven assembly插件的东西来创建fat jar,那么每个注册表文件都会被下一个注册表文件覆盖。结果是,最后,RDF4J只能找到一个解析器 - 它的注册表文件最后添加到胖罐中。

解决方案是根本不创建一个胖jar或者如果你必须使用不同的技术来创建它,它合并注册表文件而不是覆盖它们。 maven shade plugin对此有一个很好的配置选项:ServicesResourceTransformer

+1

我决定采取另一种方式,创建一个“精益”jar并将依赖关系输出到一个单独的目录lib中。包含所有依赖项的类路径包含在清单中(如[本问题]中所示)(http://stackoverflow.com/questions/8325819/how-can-i-create-an-executable-jar-without-dependencies-using-行家))。谢谢! –