geotools 20.5 error: Provider org.geotools.referencing.factory.epsg.CartesianAuthorityFactory could not be instantiated

geotools 20.5 error: Provider org.geotools.referencing.factory.epsg.CartesianAuthorityFactory could not be instantiated

我正在开展一个 java 项目,该项目需要将 WGS84 转换为 UMT。我使用 geotools v20.5 通过以下代码创建了一个转换:

transform = CRS.findMathTransform(
              CRS.decode("EPSG:4326", true),
              CRS.decode("EPSG:3857", true),
              false);

在 geotools 更改其存储库之前,它一直在正常工作。 目前当我运行这个程序时,我会得到一个警告:

WARNING: Can't load a service for category "CRSAuthorityFactory". Cause is "ServiceConfigurationError: org.opengis.referencing.crs.CRSAuthorityFactory: Provider org.geotools.referencing.factory.epsg.CartesianAuthorityFactory could not be instantiated".

然后出现以下错误:

Caused by: java.lang.NoSuchFieldError: ONE
Execution failed for task ':Application.main()'.
> Process 'command '/usr/lib/jvm/java-8-openjdk-amd64/bin/java'' finished with non-zero exit value 255

我的环境:Ubuntu 20.04 with OpenJDK 8 (64bit) 我用其他 Windows 机器测试过,它遇到了同样的错误。 这是我使用的来自 org.geotools

的库
def geotoolsVersion=20.5

    compile group: 'org.geotools', name: 'gt-opengis', version: geotoolsVersion
    compile group: 'org.geotools', name: 'gt-referencing', version: geotoolsVersion
    compile group: 'org.geotools', name: 'gt-epsg-wkt', version: geotoolsVersion
    compile group: 'org.geotools', name: 'gt-geometry', version: geotoolsVersion

正如您可能注意到的那样,我正在使用 gt-epsg-wkt 而不是那些带有 db 的,因为我可能没有对生产中的某些目录的写权限。但是我用 db 测试了其他插件,仍然遇到同样的错误。 我试图调试 geotools 中的哪部分代码导致了该错误,我发现了。 错误开始于 Units.autoCorrect(...) [=59= 中以下代码的最后一行] class 在 gt-referencing 库中。

    /**
     * Parses an "UNIT" element. This element has the following pattern:
     *
     * <blockquote>
     *
     * <code>
     * UNIT["<name>", <conversion factor> {,<authority>}]
     * </code>
     *
     * </blockquote>
     *
     * @param parent The parent element.
     * @param unit The contextual unit. Usually {@link SI#METRE} or {@link SI#RADIAN}.
     * @return The "UNIT" element as an {@link Unit} object.
     * @throws ParseException if the "UNIT" can't be parsed.
     * @todo Authority code is currently ignored. We may consider to create a subclass of {@link
     *     Unit} which implements {@link IdentifiedObject} in a future version.
     */
    @SuppressWarnings("unchecked")
    private <T extends Quantity<T>> Unit<T> parseUnit(final Element parent, final Unit<T> unit)
            throws ParseException {
        final Element element = parent.pullElement("UNIT");
        final String name = element.pullString("name");
        final double factor = element.pullDouble("factor");
        final Map<String, ?> properties = parseAuthority(element, name);
        element.close();
        Unit<T> finalUnit = (factor != 1) ? unit.multiply(factor) : unit;
        return Units.autoCorrect(finalUnit);
    }

然后我走进去,在gt-referencing lib

中的DefaultUnitParser.javaclass中找到了下面的方法
DefaultUnitParser.getInstance() 
//this method returns null, with error said org.geotools.measure.units failed to instantialize.

我现在完全迷路了,为什么在他们更改了远程仓库后它可以正常工作却突然不工作?! 如果您需要我提供更多信息,请发表评论,我仍在等待解决方案,因为我无法轻易更改 geotools 库。 谢谢大家

顺便说一句,我确认它通过代码获得了正确的 WKT:EPSG:4326 或 EPSG:3857

更新 我将 geotools 版本更改为 12.5 ,该版本写在他们的网站 https://geotools.org/about.html 上,并将 JTS lib 切换为 com.vividsolutions.jts 然后它现在可以工作了。我想我可能需要就他们的 github.

提出一个问题

解决此类问题的诀窍是使用 gradle -q dependencies 查看 gradle 作为依赖引入的是什么 - 如果您的构建构建良好,您应该会看到类似以下内容:

+--- org.locationtech.jts:jts-core:1.16.1
+--- org.geotools:gt-opengis:23.1
|    +--- commons-pool:commons-pool:1.5.4
|    +--- systems.uom:systems-common-java8:0.7.2
|    |    +--- tec.uom:uom-se:1.0.8
|    |    |    +--- javax.measure:unit-api:1.0
|    |    |    \--- tec.uom.lib:uom-lib-common:1.0.2
|    |    |         \--- javax.measure:unit-api:1.0
|    |    +--- si.uom:si-quantity:0.7.1
|    |    |    \--- javax.measure:unit-api:1.0
|    |    \--- si.uom:si-units-java8:0.7.1
|    |         +--- javax.measure:unit-api:1.0
|    |         +--- tec.uom:uom-se:1.0.8 (*)
|    |         \--- si.uom:si-quantity:0.7.1 (*)
|    \--- javax.media:jai_core:1.1.3
+--- org.geotools:gt-epsg-wkt:23.1
|    +--- org.geotools:gt-referencing:23.1
|    |    +--- org.ejml:ejml-ddense:0.34
|    |    |    \--- org.ejml:ejml-core:0.34
|    |    +--- commons-pool:commons-pool:1.5.4
|    |    +--- org.geotools:gt-metadata:23.1

如果您看到类似的内容:

+--- org.locationtech.jts:jts-core:1.16.1
+--- org.geotools:gt-opengis:23.1
+--- org.geotools:gt-epsg-wkt:23.1
+--- org.geotools:gt-geometry:23.1
+--- org.geotools:gt-referencing:23.1
+--- org.geotools:gt-main:23.1
\--- org.geotools:gt-metadata:23.1

那么出事了。从我对 gradle 的(简短)实验来看,您似乎需要这样的东西:

repositories {
     maven { url "http://download.java.net/maven/2" }
     maven { url "https://repo.osgeo.org/repository/release/" }
     maven { url "http://maven.geo-solutions.it/" }
     maven { url "https://repo.maven.apache.org/maven2" }
}

确保 gradle 可以找到您(和 GeoTools)需要的所有依赖项。请注意,如果您使用 GeoTools 的快照,则需要 https://repo.osgeo.org/repository/snapshot/ 而不是 https://repo.osgeo.org/repository/release/