在使用独立应用程序向HttpDepository添加数据时,RDF4J不支持RDDFormatexception

在使用独立应用程序向HttpDepository添加数据时,RDF4J不支持RDDFormatexception,exception,sesame,rdf4j,Exception,Sesame,Rdf4j,我有一个HTTPRepository,用指向存储库的URL初始化。我使用RepositoryConnection检索(天气)数据并将其添加到存储库中。数据从web服务中检索,然后转换为RDF语句,并添加到存储库中。这是由一个独立的应用程序定期完成的 当我在IntelliJ中运行此应用程序时,一切正常 为了在服务器上运行这个应用程序,我创建了一个jar文件(包含所有依赖项)。应用程序按预期启动,并且能够从存储库中检索数据 但是,当应用程序尝试将数据写入存储库时,我会得到一个不支持的dRDForma

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

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

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

但是,当应用程序尝试数据写入存储库时,我会得到一个
不支持的dRDFormatException

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(){
info(“为应用程序检索天气数据:“+ID+”);
RepositoryConnection=null;
ValueFactory vf=SimpleValueFactory.getInstance();
试一试{
connection=repository.getConnection();
//从存储库中检索位置(这里没有问题)。
列表位置=此。检索位置(连接);
列表语句=新的ArrayList();
//从每个位置检索天气数据并将其转换为报表。
对于(位置:位置){
List RetrieveWeather=weatherService.retrieveWeatherData(位置.名称,位置.纬度,位置.经度);
用于(天气:检索天气){
BNode现象=vf.createBNode();
add(vf.createStatement(location.ID,WEATHER.HAS_WEATHER,phenology,rdfStoreGraph));
addAll(weather.getStatements(现象、vf、rdfStoreGraph));
语句=此.correctOMIRIs(语句,vf);
}
}
//添加从天气API检索的数据
//这就是异常发生的地方。
add(语句、rdfStoreGraph);
}捕获(例外e){
logger.error(“无法检索天气应用程序的数据:”“+ID+”,因为找不到监视器位置。”,e);
}最后{
if(连接!=null){
connection.close();
}
}
}
httpresposition
初始化如下:

        repository = new HTTPRepository(rdfStore.toString());
        ((HTTPRepository)repository).setPreferredRDFFormat(RDFFormat.BINARY);
        ((HTTPRepository)repository).setPreferredTupleQueryResultFormat(TupleQueryResultFormat.BINARY);
我已尝试将格式更改为
TURTLE
。但这没什么区别

你能告诉我怎么解决这个问题吗

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

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

这是您的问题:您创建了一个“胖jar”,并且可能没有正确合并SPI注册表文件

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

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


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

我正在重新撰写这篇文章,因为我被这篇文章绊倒了好几个小时。最后,我可以使用具有以下配置的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>

org.apache.maven.plugins
maven阴影插件
3.2.4
*:*
META-INF/*.SF
META-INF/*.DSA
META-INF/*.RSA
包裹
阴凉处
${fully.qualified.main.class}
我将着色插件与ManifestResourceTransformer一起用于创建指示项目主类的可执行jar,并与ServicesResourceTransformer一起用于处理RDF4J包命名,以避免一个解析器重写前一个解析器。此外,我还必须包括filter部分,以避免从包签名派生的JNI错误

我希望这对某人有用


问候。

我决定换一种方式,创建了一个“精益”jar,并将依赖项输出到一个单独的目录
lib
。包含所有依赖项的类路径包含在清单中(如中所示)。谢谢