2016-12-01 37 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-行家))。謝謝! –