使用 Maven 程序集插件时找不到 Geotools 数据存储
Cannot find Geotools datastores when using maven assembly plugin
我想使用 Geotools (v. 17.1) 访问不同的 Geotools 数据存储。在我的 POM 中,我使用 Maven 程序集插件 (v. 3.0.0) 来聚合我的项目输出:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archive>
<manifest>
<mainClass>de.my.project.MainClass</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
我的 geotools 依赖项:
dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-shapefile</artifactId>
<version>17.1</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geopkg</artifactId>
<version>17.1</version>
</dependency>
...
问题是我只能访问 Shapefile。在测试中 class 我写了这段代码来确定是否可以找到数据存储:
Iterator gtIterator = DataStoreFinder.getAvailableDataStores();
while(gtIterator.hasNext()){
System.out.println(gtIterator.next().toString());
}
// results in:
/*
org.geotools.data.postgis.PostgisNGJNDIDataStoreFactory@25a65b77
org.geotools.data.postgis.PostgisNGDataStoreFactory@55ca8de8
org.geotools.geopkg.GeoPkgDataStoreFactory@8b96fde
org.geotools.data.mysql.MySQLJNDIDataStoreFactory@5d47c63f
org.geotools.data.oracle.OracleNGOCIDataStoreFactory@105fece7
org.geotools.data.shapefile.ShapefileDataStoreFactory@1dd92fe2
org.geotools.data.mysql.MySQLDataStoreFactory@275710fc
org.geotools.data.oracle.OracleNGDataStoreFactory@35083305
org.geotools.data.csv.CSVDataStoreFactory@6f3b5d16
org.geotools.data.shapefile.ShapefileDirectoryFactory@4f9a3314
org.geotools.data.oracle.OracleNGJNDIDataStoreFactory@2145433b
*/
如果我 运行 使用生成的 JAR 的相同代码,我会得到:
//org.geotools.data.shapefile.ShapefileDataStoreFactory@1188e820
//org.geotools.data.shapefile.ShapefileDirectoryFactory@40f08448
有什么可能导致此问题的想法吗?
Geotools 使用 Java 的服务基础设施来加载 类 实现某些接口,例如 DataStores。 Java 的服务基础设施与位于 /META-INF/services/ jar 文件中的文本文件一起工作。
构建带有依赖项的 jar 时,您将多个 jar 文件合并为一个。最有可能的是,当多个 jar 文件为同一接口提供实现时,/META-INF/services/ 中的文本文件会相互覆盖。
您可以通过查看创建的 "fat-jar" 中的服务目录来验证这一点,尤其是在 /META-INF/services/org.geotools.data.DataStoreFactorySpi 条目处。几个原始的 Geotools jar 文件会有这样一个内容不同的条目,但是 "fat-jar" 将只包含一个随机的内容(在你的情况下是 ShapeFiles 的那个)。
我不太熟悉 maven-shade-plugin,但是关于 SO 的其他问题(比如 Maven shade + resteasy Could find writer for content-type 建议使用额外的转换器:
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
还可以使用 GeoTools 查看类似的 SO 问题:Geotools cannot find HSQL EPSG DB, throws error: NoSuchAuthorityCodeException
我想使用 Geotools (v. 17.1) 访问不同的 Geotools 数据存储。在我的 POM 中,我使用 Maven 程序集插件 (v. 3.0.0) 来聚合我的项目输出:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archive>
<manifest>
<mainClass>de.my.project.MainClass</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
我的 geotools 依赖项:
dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-shapefile</artifactId>
<version>17.1</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geopkg</artifactId>
<version>17.1</version>
</dependency>
...
问题是我只能访问 Shapefile。在测试中 class 我写了这段代码来确定是否可以找到数据存储:
Iterator gtIterator = DataStoreFinder.getAvailableDataStores();
while(gtIterator.hasNext()){
System.out.println(gtIterator.next().toString());
}
// results in:
/*
org.geotools.data.postgis.PostgisNGJNDIDataStoreFactory@25a65b77
org.geotools.data.postgis.PostgisNGDataStoreFactory@55ca8de8
org.geotools.geopkg.GeoPkgDataStoreFactory@8b96fde
org.geotools.data.mysql.MySQLJNDIDataStoreFactory@5d47c63f
org.geotools.data.oracle.OracleNGOCIDataStoreFactory@105fece7
org.geotools.data.shapefile.ShapefileDataStoreFactory@1dd92fe2
org.geotools.data.mysql.MySQLDataStoreFactory@275710fc
org.geotools.data.oracle.OracleNGDataStoreFactory@35083305
org.geotools.data.csv.CSVDataStoreFactory@6f3b5d16
org.geotools.data.shapefile.ShapefileDirectoryFactory@4f9a3314
org.geotools.data.oracle.OracleNGJNDIDataStoreFactory@2145433b
*/
如果我 运行 使用生成的 JAR 的相同代码,我会得到:
//org.geotools.data.shapefile.ShapefileDataStoreFactory@1188e820
//org.geotools.data.shapefile.ShapefileDirectoryFactory@40f08448
有什么可能导致此问题的想法吗?
Geotools 使用 Java 的服务基础设施来加载 类 实现某些接口,例如 DataStores。 Java 的服务基础设施与位于 /META-INF/services/ jar 文件中的文本文件一起工作。
构建带有依赖项的 jar 时,您将多个 jar 文件合并为一个。最有可能的是,当多个 jar 文件为同一接口提供实现时,/META-INF/services/ 中的文本文件会相互覆盖。
您可以通过查看创建的 "fat-jar" 中的服务目录来验证这一点,尤其是在 /META-INF/services/org.geotools.data.DataStoreFactorySpi 条目处。几个原始的 Geotools jar 文件会有这样一个内容不同的条目,但是 "fat-jar" 将只包含一个随机的内容(在你的情况下是 ShapeFiles 的那个)。
我不太熟悉 maven-shade-plugin,但是关于 SO 的其他问题(比如 Maven shade + resteasy Could find writer for content-type 建议使用额外的转换器:
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
还可以使用 GeoTools 查看类似的 SO 问题:Geotools cannot find HSQL EPSG DB, throws error: NoSuchAuthorityCodeException