ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

GeoTools 28.2依赖管理全攻略:jar包、Maven坐标与常见坑

GeoTools 28.2依赖管理全攻略:jar包、Maven坐标与常见坑 简介GeoTools 28.2版本依赖包是面向Java平台的开源地理空间库的完整依赖集合主要为地理数据处理开发者服务可直接用于解决GIS项目中逐一查找、匹配和引入对应jar包的麻烦适合需要构建矢量栅格数据读写、坐标转换、空间分析等功能的Maven或普通工程。压缩包共279个文件其中266个jar为各模块核心依赖涵盖数据存储、数据渲染、坐标参考系统以及JAI、JTS等第三方库另有12个html文档页和1个java示例分别用于查看许可说明与快速上手。资源包大小约95.09MB目前已有819人浏览学习下载后可直接按目录核对依赖版本减少版本冲突风险省去手工维护依赖的精力。借助这份整理好的依赖集合开发者可快速搭建GeoTools运行环境并利用其内置EPSG数据库和OGC标准支持将重点放到具体业务逻辑上从而让复杂的空间数据操作变得更可控、更高效。geotools 28.2 版本 所有jar包 依赖做Java GIS开发的朋友十有八九都跟GeoTools打过交道。这玩意功能是真的强从WMS/WMTS服务对接、Shapefile读写到坐标系转换、空间拓扑分析基本上GIS后端该有的能力它都包圆了。但你要说它有什么让人头疼的地方依赖管理绝对能排前三——jar包又多又碎版本还动不动就变啥时候引入的传递依赖缺了、冲突了排查起来能让人血压升高。我这篇文章就围绕GeoTools 28.2这个版本把它的jar包构成、Maven依赖坐标、仓库配置、离线导入这些事彻底聊透。不管你是刚接触GeoTools的新手还是被依赖问题折磨过的老手照着这篇文章的思路走一遍基本能少踩一半的坑。1. GeoTools 28.2版本的整体认知1.1 为什么是28.2这个版本GeoTools的版本号策略比较有规律大版本28对应的是2023年发布的系列而28.2是这个系列里的一个维护版本。这个版本属于支持JDK 8的版本线打包方式用的还是传统的jar包形式没有走JPMS模块化那一套所以对很多还在用Spring Boot 2.x、JDK 8/11的老项目来说兼容性反而是最舒服的。我当时给一个数据治理平台做升级原来用的是22.x一堆自定义的FeatureType处理逻辑要迁移。查了一圈之后锁定了28.2理由很实在它修复了不少关于Shapefile读写和坐标参考系统CRS解析的bug而且社区里相关的资料比较多出了问题也好搜。选版本这事真的不是越新越好关键是稳定性和你项目里其他框架的兼容性。1.2 28.2的模块化特点GeoTools和Spring Boot的思路有点像它不是一个单独的jar而是一组按功能拆分的模块。比如gt-shapefile管矢量数据读写gt-geojson管GeoJSON解析gt-referencing管坐标系gt-main是核心数据模型gt-api是接口定义。这意味着你引入依赖的时候不需要“把所有jar包都拉下来”而是按需引入。但问题也出在这——很多初学者不知道某个功能对应哪个模块干脆全加一遍然后Maven就给你搞出一堆传递依赖冲突。28.2版本共有上百个模块jar我需要做的第一件事就是理清楚每个场景到底该引哪些。模块功能定位常用场景gt-main核心数据模型与要素接口所有项目必引gt-data数据存储抽象层数据读取通用入口gt-shapefileShapefile读写本地矢量数据处理gt-geojsonGeoJSON解析与生成Web端数据交互gt-referencing坐标系定义与转换投影转换、EPSG码查询gt-epsg-hsqlEPSG坐标系数据库HSQL版CRS解析gt-wmsWeb地图服务客户端对接WMS服务gt-geometry几何对象操作旧版常用空间关系判断2. Maven依赖坐标与仓库配置2.1 核心BOM依赖GeoTools官方提供了一个BOMBill of Materials叫geotools-bom用来统一管理所有模块的版本号。你只要在dependencyManagement里声明一次后面引入具体模块的时候就不用写版本号了避免你自己拍脑袋写错版本导致一堆NoSuchMethodError。dependencyManagement dependencies dependency groupIdorg.geotools/groupId artifactIdgeotools-bom/artifactId version28.2/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement用BOM的好处除了版本统一还有个隐藏优势它把模块之间的内部依赖版本都锁好了能把很多隐性的版本错配问题扼杀在编译阶段。2.2 常用模块的Maven坐标下面是我在实际项目中经常用到的几个坐标组合可以直接抄。注意gt-geojson这个模块在28.x版本里包名和依赖范围有些调整如果你从旧版本升上来最好检查一下相关类的import路径。!-- 核心数据模型 -- dependency groupIdorg.geotools/groupId artifactIdgt-main/artifactId /dependency !-- 数据访问抽象层 -- dependency groupIdorg.geotools/groupId artifactIdgt-data/artifactId /dependency !-- Shapefile 读写 -- dependency groupIdorg.geotools/groupId artifactIdgt-shapefile/artifactId /dependency !-- GeoJSON 解析 -- dependency groupIdorg.geotools/groupId artifactIdgt-geojson/artifactId /dependency !-- 坐标系参考与转换 -- dependency groupIdorg.geotools/groupId artifactIdgt-referencing/artifactId /dependency !-- EPSG 坐标系库 -- dependency groupIdorg.geotools/groupId artifactIdgt-epsg-hsql/artifactId /dependency如果你的项目需要用到WMS、WFS这类OGC服务对接再补一个gt-wms和gt-wfs。需要提醒的是gt-wms在28.x系列里对应的底层HTTP客户端已经逐步向Java 11的java.net.http靠拢如果你的运行环境是JDK 8得留意一下是否能正常工作。2.3 osgeo仓库的配置GeoTools的jar包不在Maven中央仓库里人家在自家的OSGeo仓库发布。所以光加依赖坐标不够还得在pom.xml的repositories节点里声明仓库地址。repositories repository idosgeo/id nameOSGeo Release Repository/name urlhttps://repo.osgeo.org/repository/release//url /repository /repositories这里有个坑OSGeo仓库还区分release和snapshot两个仓库。如果你不小心把snapshot仓库配到了生产构建里某些依赖会拉到不稳定的快照版本构建结果看起来能用但过几天再构建可能就是另一套代码了。所以生产环境构建、打正式包尽量只保留release仓库快照仓库单独留一个profile给开发环境用。3. 获取全部jar包的实操方法3.1 用Maven依赖树梳理完整的jar包列表虽然我前面说按需引入是个好习惯但现实中总有特殊场景比如做离线部署、写二次开发SDK、或者把GeoTools打包成胖jar给下游用这时候就需要把整个依赖链上的所有jar包完整导出来。第一步是构建出一个“全量”的依赖清单。我通常的做法是维护一个独立工程把可能用到的模块坐标全部列进去然后执行Maven的依赖树命令mvn dependency:tree -Dverbose -Dincludesorg.geotools执行完之后Maven会像一棵树一样展示每个模块下面挂了哪些子依赖。你会发现很多gt-*模块又依赖了jt-*系列的包比如jt-utils、jt-epsg这些是GeoTools底层封装的Java Topology Suite相关工具库缺了它们很多几何运算会直接崩。3.2 离线导出所有jar包如果你需要把所有jar包导出到一个目录里最省事的方法是Maven的dependency:copy-dependencies插件mvn dependency:copy-dependencies -DoutputDirectory./libs这个命令会把当前工程所有依赖包括传递依赖的jar包复制到你指定的目录下。导出的目录结构里就是平铺的jar包文件没有多余的层级。如果你还想把source包、javadoc包一起拉下来加上-Dclassifiersources或者-Dclassifierjavadoc就行。不过实际来看sources包通常只在调试时用生产环境没必要占那个空间。3.3 打包产物里的lib目录结构如果你做的是传统的war包或者独立应用想让最终产物自带所有依赖建议看一下打包后的lib目录是否完整。以Spring Boot项目为例spring-boot-maven-plugin默认会把所有依赖打进BOOT-INF/lib但GeoTools里面有个别模块存在SPI的配置文件合并问题直接打包可能丢服务定义。稳妥的做法是在pom.xml里要用maven-shade-plugin做一个fat jar并配置ServicesResourceTransformer把META-INF/services下的SPI文件合并否则运行时会报类似“No suitable driver found”或“Factory is null”的错。4. 核心依赖的底层解析与版本坑4.1 常见的传递依赖冲突GeoTools 28.2的核心依赖里有几个高频冲突源我列一下大家感受会更深org.locationtech.jts:jts-core这个包是几何算法的基础。很多项目会直接引JTS如果版本号低于GeoTools要求的版本运行时会出现TopologyException或者类转换异常。org.apache.commons:commons-lang3GeoTools内部大量用到commons工具包如果你项目里其他框架引的commons版本特别老也会冲突。com.fasterxml.jackson.core:jackson-databind处理GeoJSON时必定用到版本一旦不一致轻则序列化报错重则直接抛InvalidDefinitionException。org.hsqldb:hsqldb这个只有在用gt-epsg-hsql的时候才会出现如果不用它可以把模块排除掉减小依赖体积。4.2 JDK版本与坐标参照库的兼容性GeoTools 28.2对JDK 8的兼容做得还可以但有个地方要注意gt-referencing模块在解析EPSG坐标库的时候会加载一些内置的数据库和属性文件如果JDK的--add-opens没配好在高版本JDK11上运行有概率出现模块访问限制报错。我在本地用JDK 11跑过28.2当时启动参数里加了这些--add-opens java.base/java.langALL-UNNAMED --add-opens java.base/java.utilALL-UNNAMED --add-opens java.desktop/java.awt.geomALL-UNNAMED如果你用JDK 8一般不用管这些。用JDK 17的兄弟就要特别注意前两个--add-opens大概率得加否则程序启动时会有IllegalAccessError。4.3 与Spring Boot的兼容性实操结合前一节提到的jar包需求在Spring Boot项目里引入GeoTools 28.2需要额外注意依赖版本控制。我建议直接在pom.xml里用一个profile来管理GeoTools相关依赖避免影响Spring Boot自己的BOMprofiles profile idgeotools/id dependencyManagement dependencies dependency groupIdorg.geotools/groupId artifactIdgeotools-bom/artifactId version28.2/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement /profile /profiles配置好之后在集成测试里写一个最简单的数据读取验证FileDataStore store FileDataStoreFinder.getDataStore(new File(your.shp)); SimpleFeatureSource featureSource store.getFeatureSource(); SimpleFeatureCollection features featureSource.getFeatures(); System.out.println(feature count features.size()); store.dispose();能正常输出feature数量说明你的jar包依赖和SPI配置基本是健康的。这一步能验证gt-shapefile、gt-main、gt-data以及JTS相关的jar包都正确加载了。5. 常见问题与排查技巧实录5.1 问题速查表下面这些情况都是我在实际项目里和社区里高频见到的归纳成表方便大家对照排查。现象可能原因解决办法运行时报NoClassDefFoundError: org/locationtech/jts/...JTS版本冲突或未引入用BOM锁版本统一升级到GeoTools要求的JTS版本找不到org.geotools.data.FileDataStoreFindergt-data模块没引入增加gt-data依赖报Factory is null或“No bean named ... available”SPI配置文件缺失确认使用shade插件合并META-INF/services资源坐标转换报FactoryRegistry相关异常gt-epsg-hsql或gt-epsg-wkt未引入引入对应EPSG模块或检查HSQLDB依赖运行时提示版本冲突、NoSuchMethodError多个jar包版本不一致执行mvn dependency:tree检查排除低版本遗留依赖5.2 缺少gt-*.jar时的定位思路如果你报错信息里出现了gt-开头的类名,比如org.geotools.referencing.CRS但类找不到定位思路很简单用类名反查模块。GitHub上搜类名、或者在IDE里按类名检索依赖库先确认这个类属于哪个模块再回到pom.xml里补坐标。我以前最常犯的错是把gt-referencing记成gt-crs名字完全不一样怎么可能搜得到。还有gt-epsg-hsql和gt-epsg-wkt的区别前者用一个内嵌的HSQL数据库存EPSG定义内存占用更大但查询灵活后者用WKT格式定义存储轻量但EPSG覆盖范围少。28.2版本里如果你只做几个常用坐标系的转换gt-epsg-wkt就够了能省不少体积。5.3 私有仓库与离线环境的依赖方案企业内部开发经常遇到外网受限的情况Maven依赖拉不下来或者说OSGeo仓库在公司内网不可达。我的建议是准备一台内部私服比如Nexus或Artifactory先从外网机器上把所有GeoTools相关的依赖jar包拉下来然后批量上传到私服。具体的操作可以通过Nexus的REST API或者Web页面上传上传完毕后把pom里的仓库地址直接换成私服地址其他同事构建的时候就能走内网了。更省事的方法是用mvn dependency:go-offline在能联网的机器上先把本地仓库填充好然后把整个~/.m2/repository目录打成tar包同步到内网在离线环境里配置settings.xml里的localRepository指向这些本地文件。我就是这么做的那些org/geotools、org/locationtech目录下的jar包全在本地仓库里速度比在线拉取还快。5.4 排查过程中的独家心得排查GeoTools依赖问题我有个个人习惯先跑一个最小可复现的demo工程只保留必要模块。如果这样能跑通再逐步往正式项目里加东西问题就缩小在某个模块的冲突上。这里有个容易忽略的点就是gt-geojson模块在28.x里依赖了com.fasterxml.jackson.core的2.13版本而你项目里Spring Boot自带的可能是2.11这时候GeoTools处理中文GeoJSON字段时会出现乱码或者序列化异常单纯靠排除依赖还不够得把jackson的整体版本对齐。另外排查的时候多利用IDE的Maven面板IDEA里右键依赖列表就可以看到哪几个jar包存在版本冲突可以直接跳到pom文件里按冲突位置处理。我见过不少同事把这个功能忽略掉真的挺可惜的。6. 进阶思考与额外扩展实际项目中我还有一个小技巧在正式发布应用之前跑一遍mvn dependency:analyze它能把“声明了但没用到”的依赖和“用到但没声明”的依赖都列出来。GeoTools这种模块较多的库很容易出现冗余依赖清理之后部署包能小不少启动速度也会快一些。如果后续想把GeoTools 28.2的依赖彻底固化另一个思路是直接把geotools-bom单独打成一份pom放到私服然后项目里统一引用私服上的这份BOM。这样一来多个微服务之间用GeoTools的版本完全一致升级的时候也只需要改私服里那一份BOM的版本号不用每个服务都去动pom。至于GeoTools后面更新的版本有些模块比如gt-geojson还在持续演进如果你不是非要追新功能28.2作为一个维护版本其实已经很够用了。等到项目里需要JDK 17的完整虚拟线程支持、或者想用上更新的OGC API标准时再考虑升级也不迟。切记升级前对比官方文档里标注的Breaking Changes把jar包变化和API变化列个清单按计划替换大概就是这个项目的依赖管理最稳的路子。本文还有配套的精品资源点击获取
返回列表