Geotools cannot find HSQL EPSG DB, throws error: NoSuchAuthorityCodeException

安稳与你 提交于 2019-11-30 12:54:35
cello

Geotools uses Java's Service infrastructure to load the class responsible for EPSG lookups. The original gt-epsg-hsql.jar has entries in /META-INF/services/ which specify which interfaces are implemented by the jar-file, and which can be dynamically loaded at runtime.

When building a uber-jar, you combine multiple jar files into one. Most likely, another jar file implements the same interfaces as well (for example gt-referencing.jar) and has thus files with the same names in its /META-INF/services/. When putting everything into one jar file, those entries will very likely be overwritten (at least I couldn't find any reference that the maven-shade-plugin merges such services files).

You could verify that by looking at the services-directory in the created uber-jar, especially at the entry /META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory. Both gt-epsg-hsql.jar and gt-referencing.jar have such a file (and other jar-files from GeoTools probably as well), and most likely, only the content of one will be in your uber-jar, resulting in all the other classes not being found/loaded at runtime.

I'm not really familiar with the maven-shade-plugin, but other questions on SO (like [1]) suggest to use an additional transformer:

<transformer
   implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />

[1] Maven shade + resteasy Could find writer for content-type

I also ran into this problem. Instead of banging your head against the wall, there is a workaround you could use which is to create the CRS from WKT instead of using decode:

private static final String EPSG4326 = "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]]";
    CoordinateReferenceSystem worldCRS = CRS.parseWKT(EPSG4326);

One tip is that if you use this method, the resulting CRS will store the longitude first in the WKT followed by the latitude. Using the ServicesResourceTransformer gives WKT that has latitude followed by longitude. More on this issue at this link http://docs.geotools.org/latest/userguide/library/referencing/order.html

GeoTools uses a factory based plugin system to provide multiple referencing databases, but you have to choose one of them. gt-referencing provides the interfaces and the factory. The actual authorities are in the EPSG plugins (choose only one to prevent conflict):

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!