
简介一套GeoTools 28.2版本的完整依赖jar包集合面向需要在Java项目中实现地理数据读写与GIS功能开发的工程师。资源包含该版本核心及周边模块的所有必需依赖覆盖矢量数据Shapefile、GeoJSON、KML等、栅格数据GeoTIFF等处理、坐标参考系统转换、空间过滤与渲染以及对OGC标准WMS、WFS等的支持可帮助快速搭建GeoTools开发环境免去逐一下载依赖并匹配版本的繁琐过程。压缩包共279个文件其中266个jar包构成完整的运行与构建依赖另有12个html文档和1个java示例文件便于查看许可说明、API文档或进行基础验证。整体大小约95MB适合已具备Java基础、希望直接引入GeoTools 28.2构建地理空间应用的中高级开发者也适合在使用Maven或手动配置构建路径时作为依赖缺失时的补充参考。目前已有819人学习下载能有效节省依赖搜集时间并降低版本冲突风险。 搞GIS的Java后端项目里第一次引入geotools 28.2的时候十有八九会在依赖这关卡一下。明明只是想在代码里读写一个Shapefilepom.xml里加了geotools的jar包坐标结果mvn compile一跑直接拉出几十个依赖时不时还报个“找不到类”“版本冲突”之类的错误甚至仓库直接404。这篇文章我把geotools 28.2所有jar包的获取方式、核心依赖坐标、传递依赖关系、离线环境怎么收集依赖以及打包集成时那些坑一次性讲清楚。内容适合两类人一类是刚接触geotools想在Spring Boot项目里用JTS几何运算、Shapefile读写这些能力的新手另一类是已经跑通基础流程但卡在私服部署、依赖冲突、打包失败这些环节需要排查思路的老手。1. geotools 28.2的定位与依赖管理难点1.1 一套jar包撑起来的GIS工具集geotools在Java GIS圈子里几乎是绕不开的选择。28.2是28.x系列里的一个稳定小版本它把空间几何模型JTS那套、坐标参考系、栅格与矢量数据读写、空间关系运算这些能力全部拆成了独立模块每个模块对应一个gt-开头的jar包。严格来说“geotools 28.2所有jar包”这个说法不太严谨——官方没有提供一个所谓的全家桶jar而是一堆按功能划分的模块。你也不应该把几十个gt-*.jar全部塞进项目里正确做法是按需引入。这个版本线跑在Java 11及以上环境内部大量使用流式API和Optional老项目如果还停留在Java 8建议先评估升级成本。另外geotools的模块命名比较规律核心模块是gt-main和gt-metadata几乎所有功能模块都会间接依赖这两个读写矢量数据的模块是gt-shapefile、gt-geojson、gt-dxf处理坐标系的模块是gt-referencing和gt-epsg-hsql空间数据库扩展是gt-jdbc及其下面的gt-postgis、gt-mysql等。1.2 为什么geotools依赖这么难管理抛开代码本身不谈这个库的依赖管理确实有几个让无数人头疼的根因。第一发布仓库不在Maven中央仓库的主路径上。geotools长期通过OSGeo的仓库发布构件28.2虽然已有部分构件同步到中央仓库但很多子模块、POM文件和父级依赖依然只在OSGeo仓库里。如果你没有在pom.xml里额外配置OSGeo仓库地址maven解析依赖时大概率会报“找不到org.geotools:gt-shapefile:jar:28.2”。第二传递依赖树非常深。你只引入一个gt-shapefile它内部会依赖gt-main、gt-metadata、gt-referencing、gt-render等多个模块而这些模块又分别依赖JTS、CommonMath、Xerces、Jackson等第三方库。实测下来一个最小可用的geotools项目最终会拉进来几十个jar包项目里但凡有其他重量级框架比如Spring Boot本身就很容易撞版本。第三迭代速度快、API变动频繁。网上很多教程是20.x甚至18.x时代的写法依赖坐标、类名、方法签名都对不上照抄过来第一步就可能编译失败。这也是我推荐锁定固定版本、统一由依赖BOM管理的原因。2. 核心jar包坐标与依赖全景图2.1 常用模块坐标清单geotools 28.2的groupId统一是org.geotoolsartifactId按功能划分。下面是我在实际项目里用得最多的一组坐标直接整理成表方便复制。功能场景artifactId说明核心几何与通用功能gt-main最核心的模块包含Geometry、Feature等基础类型元数据与过滤器gt-metadata被大量模块间接依赖一般不用直接引用坐标参考系gt-referencing坐标系定义与转换EPSG数据库gt-epsg-hsql内置EPSG坐标库通常作为gt-referencing的数据源Shapefile读写gt-shapefile读写Shapefile文件GeoJSON读写gt-geojson基于Jackson的GeoJSON解析、生成空间数据库gt-jdbcJDBC数据访问抽象用PostGIS时基本必选PostGIS方言gt-postgisPostGIS专用数据访问实现需配合gt-jdbc渲染与样式gt-render地图渲染、符号化做动态出图时才需要Swing控件gt-swing桌面端地图控件纯Web项目别引入以读写Shapefile为例标准做法是引入gt-shapefile和gt-epsg-hsql两个artifact。注意不是引入gt-shapefile就完事了读写带坐标系信息的Shapefile时如果没有EPSG数据源到运行时解析坐标系会报错。2.2 外部强依赖与版本约束geotools虽然内部模块众多但它并不会把第三方依赖全部打成fat jar而是正常声明传递依赖。也就是说你引入gt-main之后maven会自动带上JTS、CommonMath、Xerces、json、sqlite-jdbc等第三方库。问题是这些库的版本和Spring Boot等框架自带的版本经常不一致。这里我单独说几个容易踩的版本点JTSgeotools 28.2内部使用1.19.0版本的JTSlocationtech.jts项目里如果还手动引用了旧版jts-core就会同时存在两套几何类报java.lang.NoSuchMethodError的概率非常高。PostGIS驱动gt-postgis本身不包含数据库驱动需要单独引入org.postgresql:postgresql建议用项目统一版本避免和Spring Boot数据源冲突。Jacksongt-geojson依赖Jackson 2.x如果项目里已有其他Jackson版本要看下是否兼容冲突通常表现为序列化时方法找不到。日志框架geotools部分模块用java.util.logging和Spring Boot的Logback不在一个体系虽然不会编译报错但日志输出风格不统一排查问题时会有点别扭。2.3 用一条命令看清完整依赖树与其在网上搜“geotools 28.2所有jar包依赖”的现成清单不如在自己的项目里直接看实际依赖树最准确也最直观。maven项目里执行mvn dependency:tree -Dverbose如果只想看geotools相关的依赖路径可以加上includes参数过滤mvn dependency:tree -Dincludesorg.geotools还可以指定只看某个模块的具体依赖来源mvn dependency:tree -Dincludesorg.geotools:gt-shapefile这个命令输出会清楚显示每个jar包的版本以及是谁传递依赖进来的。排查版本冲突时-Dverbose参数会额外显示被忽略的依赖项非常有用。我第一次用这个命令时发现项目里同时存在两个不同版本的gt-main就是靠它定位到的。3. 收集所有jar包与离线环境部署3.1 用dependency:copy-dependencies导出jar包很多内网环境的服务器是无法访问外网仓库的这时就需要在能联网的机器上把geotools 28.2相关依赖一次性收集齐全。maven自带的dependency插件就能干这件事不需要额外装工具。在项目根目录执行mvn dependency:copy-dependencies -DoutputDirectory./lib -DincludeScoperuntime执行完成后项目下会出现一个lib目录里面就是当前项目所有runtime级别的jar包包括geotools的所有模块和它们传递依赖的第三方库。如果想连编译期依赖一起导出把includeScope改成compile即可。这里有个细节直接拷贝lib目录虽然能让大部分Java命令跑起来但它丢失了maven的依赖坐标信息。如果你是想把整套依赖搬到另一个maven项目里复用更推荐的做法是直接复制本地仓库.m2/repository下相关目录。3.2 离线环境从本地仓库迁移依赖本地仓库迁移的思路很简单在联网机器上先执行一次完整的mvn dependency:go-offline让maven把所有依赖下载到本地仓库然后把本地仓库打包传到内网环境解压替换即可。实操时如果只针对geotools相关依赖可以只复制.m2/repository/org/geotools目录、.m2/repository/org/locationtech/jts目录再加上gt模块传递依赖的第三方库目录。但手工挑目录很容易漏我建议直接执行mvn dependency:go-offline这个命令会把当前项目涉及的所有插件和依赖一次性下载下来本地仓库就齐了。之后把整个.m2目录打包带走内网机器上配置好settings.xml指向这个仓库目录离线构建基本没问题。3.3 构建Nexus私服托管依赖如果你的团队有多个项目都在用geotools每次都靠拷贝.m2目录不是长久之计配置一个Nexus私有仓库是更正规的方案。做法分两步。第一步在Nexus上创建一个maven2代理仓库代理地址填OSGeo仓库https://repo.osgeo.org/repository/release/同时再创建一个代理仓库指向Maven中央仓库两个仓库都加入同一个公开仓库组。第二步在项目的pom.xml中配置仓库地址指向私服或者修改settings.xml统一管理repositories repository idmy-nexus/id urlhttp://your-nexus-ip/repository/maven-public//url /repository /repositories私服搭建之后开发者不需要每个人都去联网拉geotools依赖首次解析速度会快很多版本也统一。另外提醒一句Nexus的代理仓库默认有缓存策略geotools发新版本后如果拉不到最新jar记得在Nexus后台执行一次“刷新缓存”或手动清理缓存。4. 版本冲突排查与Spring Boot打包集成4.1 高频冲突清单与排除方法geotools和Spring Boot一起用是我见过冲突最多的情况。整理几个最常见的版本冲突场景和对应处理办法。JTS版本冲突是最典型的。Spring Boot本身并不直接依赖JTS但项目里一旦用了其他空间库比如Hibernate Spatial就可能引入不同版本的jts-core。geotools 28.2要求JTS 1.19.0如果你的项目里被拉进了1.18甚至更早的版本运行时会报类似java.lang.NoSuchMethodError: org.locationtech.jts.geom.Geometry.xxx。解决办法是在pom.xml里显式声明dependency groupIdorg.locationtech.jts/groupId artifactIdjts-core/artifactId version1.19.0/version /dependencyPostgreSQL驱动冲突也很常见。gt-postgis通过JDBC访问数据库如果你的项目用的是Spring Boot的DataSource自动配置postgresql驱动版本和数据库服务端不匹配时表现是连接报错或者SQL语句解析失败。建议postgresql驱动统一用你连接的PostgreSQL主版本对应驱动。还有一种容易忽略的是xerces冲突。geotools某些模块会依赖xercesImpl而Java自带JAXP实现两个解析器同时存在时会出现XML解析行为不一致。如果不是确有需要可以把xercesImpl用exclusion排除掉让geotools走JDK内置解析器。4.2 打包时jar包冲突与META-INF/services合并用Spring Boot的spring-boot-maven-plugin打包fat jar时geotools有个很经典的坑多个gt模块的jar包中都有META-INF/services目录下的SPI配置文件如果这些配置没有正确合并运行时会报“找不到某个GeoTools操作”但编译期完全正常。解决方案是给spring-boot-maven-plugin指定需要合并的路径plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId configuration requiresUnpack dependency groupIdorg.geotools/groupId artifactIdgt-main/artifactId /dependency /requiresUnpack /configuration /pluginrequiresUnpack配置的作用是让Spring Boot启动时把指定jar解压到临时目录避免嵌套jar场景下SPI文件加载失败。这个配置最好把你实际用到的所有gt-*模块都加上尤其是gt-referencing、gt-shapefile这些。我在项目里第一次打包后运行报“Unable to find service”就是通过这个方式解决的。如果用的不是Spring Boot而是普通可执行jar记得在打包时手动合并META-INF/services否则同样会遇到类似问题。4.3 使用mvn dependency:tree定位冲突源版本冲突的排查思路其实很固定就是先找到冲突jar包是从哪条路径传递进来的再看是否值得排除。执行mvn dependency:tree -Dverbose -Dincludesorg.geotools:gt-main输出里会看到类似这样的信息[INFO] - org.geotools:gt-shapefile:jar:28.2:compile [INFO] - org.geotools:gt-main:jar:28.2:compile [INFO] - org.geotools:gt-referencing:jar:28.2:compile如果同一坐标出现多个版本说明存在冲突可以定位到是哪个父级依赖带进来的。之后在父级依赖上加exclusion去掉不需要的版本exclusions exclusion groupIdorg.geotools/groupId artifactIdgt-referencing/artifactId /exclusion /exclusions排除之后务必重新执行dependency:tree确认最终生效的版本是你想要的那个。这个流程虽然简单但我见过很多人一上来就直接排除坐标结果把真正需要的模块也排掉了越搞越乱。5. 常见问题排查与避坑实录5.1 典型问题速查表问题现象可能原因处理办法下载jar包时404找不到org.geotools构件缺少OSGeo仓库配置或版本号写错在pom中配置https://repo.osgeo.org/repository/release/仓库核对版本号运行时抛出NoSuchMethodErrorJTS或jackson版本冲突用dependency:tree定位冲突源显式声明geotools所需版本打好的jar包启动后报“Could not find service”META-INF/services未正确合并spring-boot-maven-plugin增加requiresUnpack或手动合并SPI文件项目编译正常运行读取Shapefile时报坐标系错误缺少gt-epsg-hsql或EPSG数据库未初始化引入gt-epsg-hsql确认坐标参考系模块在classpath中本地仓库有残留的.lastUpdated文件导致依赖一直下载失败maven解析失败后缓存了错误状态删除repository/org/geotools目录下的.lastUpdated文件执行mvn -U私有仓库配置后还是从中央仓库拉依赖settings.xml仓库源顺序不对检查settings.xml把私服仓库组的id和镜像配置调整到优先位置5.2 值得记住的几个细节坑先说本地仓库的.lastUpdated文件问题。maven下载依赖失败后会在本地仓库生成以.lastUpdated结尾的临时文件并且默认缓存一段时间。这个文件存在时哪怕你修复了网络或仓库地址maven依然不会重新下载。遇到“明明改好了还是报下载失败”的情况优先排查这个文件。再说Windows环境下打包geotools项目的一个坑geotools依赖树很深本地仓库路径如果很长maven在拷贝文件名时会报“文件名或扩展名太长”。处理办法是修改maven的本地仓库路径为短目录比如C:\m2repo同时把项目路径也放到短路径下这个问题基本就不会再出现。还有一个我踩过的坑是IDEA里的maven仓库源顺序。IDEA的maven配置如果同时存在多个settings.xml和全局级仓库配置可能导致geotools走的是中央仓库而不是OSGeo仓库然后下载失败。排查时先把自定义settings.xml中的镜像配置简化确认仓库源是否被镜像拦截。另外如果你公司内网有统一maven镜像但镜像没有同步OSGeo仓库即使配置了私服也可能拉不到geotools构件这时候要在镜像配置的mirrorOf里排除OSGeo仓库或者确保镜像支持透传。最后给一个实战小建议geotools的依赖虽然复杂但解决方案几乎都可以靠mvn dependency:tree和合理的exclusion策略搞定。不要看到一个冲突就直接排除先搞清楚这个坐标是谁带进来的、被排除后会不会导致其他模块功能缺失。把依赖树看明白了geotools 28.2的jar包管理一点都不神秘。本文还有配套的精品资源点击获取