使用独立应用程序将数据添加到 HTTPRepository 时出现 RDF4J RIO UnsupportedRDFormatException
RDF4J RIO UnsupportedRDFormatException when adding data to an HTTPRepository using a stand-alone application
我有一个 HTTPRepository
使用 URL 初始化到存储库。我使用 RepositoryConnection
检索(天气)数据并将其添加到存储库。数据从 Web 服务中检索,然后转换为 RDF 语句,并添加到存储库中。这是由独立应用程序定期完成的。
当我在 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[=10=](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)。
To run this application on a server I created a jar file (containing all dependencies).
这是您的问题:您创建了 "fat jar" 并且可能没有正确合并 SPI 注册表文件。
RDF4J 的 Rio 解析器(以及其他几个模块)使用 Java 的服务提供者接口 (SPI) 机制来注册自己。此机制依赖于 jar 文件中 META-INF\services
中的文本文件,其中包含每个解析器实现的完全限定名称。
合并 jar 时会出现问题:每个 Rio 解析器 jar 都有一个名称相同但内容不同的注册表文件。如果您使用类似 maven 程序集插件的东西来创建 fat jar,每个注册表文件都会被下一个覆盖。结果是最后RDF4J只能找到一个解析器——注册文件最后添加到fat jar的那个。
解决方案是根本不创建 fat jar,或者如果必须,使用不同的技术来创建它,合并注册表文件而不是覆盖它们。 maven shade plugin has a good config option for this: the ServicesResourceTransformer.
我正在重新浮动这个 post 因为我被这个困住了几个小时。最后,我可以使用具有以下配置的 maven shade 插件生成可执行 jar:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<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>${fully.qualified.main.class}</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
我使用带有 ManifestResourceTransformer 的阴影插件来创建指示我项目的主要 class 的可执行 jar,并使用 ServicesResourceTransformer 来处理 RDF4J 包命名以避免一个解析器覆盖前一个。此外,我必须包括过滤器部分以避免从包签名派生的 JNI 错误。
我希望这对某人有用。
你好。
我有一个 HTTPRepository
使用 URL 初始化到存储库。我使用 RepositoryConnection
检索(天气)数据并将其添加到存储库。数据从 Web 服务中检索,然后转换为 RDF 语句,并添加到存储库中。这是由独立应用程序定期完成的。
当我在 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[=10=](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)。
To run this application on a server I created a jar file (containing all dependencies).
这是您的问题:您创建了 "fat jar" 并且可能没有正确合并 SPI 注册表文件。
RDF4J 的 Rio 解析器(以及其他几个模块)使用 Java 的服务提供者接口 (SPI) 机制来注册自己。此机制依赖于 jar 文件中 META-INF\services
中的文本文件,其中包含每个解析器实现的完全限定名称。
合并 jar 时会出现问题:每个 Rio 解析器 jar 都有一个名称相同但内容不同的注册表文件。如果您使用类似 maven 程序集插件的东西来创建 fat jar,每个注册表文件都会被下一个覆盖。结果是最后RDF4J只能找到一个解析器——注册文件最后添加到fat jar的那个。
解决方案是根本不创建 fat jar,或者如果必须,使用不同的技术来创建它,合并注册表文件而不是覆盖它们。 maven shade plugin has a good config option for this: the ServicesResourceTransformer.
我正在重新浮动这个 post 因为我被这个困住了几个小时。最后,我可以使用具有以下配置的 maven shade 插件生成可执行 jar:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<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>${fully.qualified.main.class}</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
我使用带有 ManifestResourceTransformer 的阴影插件来创建指示我项目的主要 class 的可执行 jar,并使用 ServicesResourceTransformer 来处理 RDF4J 包命名以避免一个解析器覆盖前一个。此外,我必须包括过滤器部分以避免从包签名派生的 JNI 错误。
我希望这对某人有用。
你好。