
简介geotools 18.4 相关 jar 包集合内含完整依赖与说明文档面向需要在 Java 项目中集成 GIS 能力的开发者。geotools 为开源地理空间库遵循 OGC 规范支持 Shapefile、GeoJSON、PostGIS、GML 等矢量和栅格数据读写并提供地图渲染、空间分析与坐标转换等能力也可读取 Shapefile 或消费 WMS/WFS 服务。包内共 247 个文件包括 229 个 jar覆盖 gt-* 核心模块及 sqlite-jdbc、spatialite-jdbc、grib、cdm 等扩展另有 md、txt、html 格式说明文档和 1 张示意图总大小约 87.28MB。已有 1091 人学习适合需要快速上手 geotools 的 Maven 或传统 Java 项目开发者。获取后可依据附带文档引入类路径或配置本地仓库有效规避依赖缺失和版本冲突问题节省逐一搜寻 jar 的时间。 做GIS二次开发的人几乎都绕不开一个头疼的问题GeoTools相关jar包集合到底怎么整理才不炸。GeoTools从来不是一个单一jar包而是一整套庞大的模块化GIS工具从Geometry操作、Shapefile读写、坐标参考系转换到WMS/WFS网络服务、栅格处理每个能力都被拆进不同的gt-xxx.jar里。更麻烦的是这些jar包还有一堆第三方依赖比如JTS、xmlbeans、netcdf、commons系列单独拷贝时少一个就是运行时报ClassNotFoundException。这篇我就结合自己多年在Java项目里折腾GeoTools的经验把jar包获取、整理、打包、排错这些事彻底讲透尤其会照顾到还在用IntelliJ IDEA手动打jar包、或者维护老项目只能靠本地lib目录的朋友。1. 先搞清楚GeoTools到底需要哪些jar包1.1 GeoTools的模块划分GeoTools从官网下载或者从Maven仓库引入看到的不是一个zip而是一个按模块拆分的依赖树。核心模块包括gt-main通用数据模型与Feature操作、gt-geometry几何对象底层常配合JTS使用、gt-shapefileShapefile读写、gt-referencing坐标参考系CRS解析与转换、gt-epsg-hsqlEPSG数据库实现常见坐标系识别全靠它、gt-jdbc数据库空间扩展访问、gt-geojsonGeoJSON解析、gt-wms和gt-wfsOGC服务客户端。如果你只是读一个Shapefile其实只需要其中几个jar包但实际项目里动不动就会牵连出十几个甚至几十个jar包。我的经验是GeoTools的官方命名规则是“gt-模块名”例如gt-shapefile-28.0.jar。要判断自己缺了什么最快的方法不是猜而是看异常堆栈里的包路径前缀。比如报org.geotools.data.shapefile错基本就是缺gt-shapefile报org.geotools.referencing错那就要补gt-referencing和对应的EPSG实现。1.2 版本与依赖是个大问题GeoTools每个主版本都对应特定的JTS版本和其他第三方库版本。比如GeoTools 28.x内部依赖的JTS版本和GeoTools 20.x依赖的JTS版本就不同如果你在classpath里塞了一个老版本的JTS再塞一个新版本的gt-shapefile极容易出现NoSuchMethodError或者奇怪的GIS坐标计算失败。这个问题之所以反复出现是因为GeoTools的jar包集合并不是“拿来就能直接用”的静态文件它必须跟周边依赖形成一个统一版本簇。官方Release包虽然自带lib目录但里面的jar包是针对同一版本编译好的不能随便把一个20.x的jar替换进28.x项目里。所以整理GeoTools相关jar包集合的第一原则是要么全用同一套发行版要么用Maven/Gradle等依赖管理工具统一版本绝对不要手动混搭。2. 三种常见的jar包获取与整理方式2.1 Maven自动管理最省心的方式现在的Java项目普遍用Maven或者GradleGeoTools官方也把release版本发布到了OSGeo maven仓库。只要在pom里声明仓库地址和具体依赖Maven就会自动把需要的gt-jar包和第三方依赖一起拉下来。repositories repository idosgeo/id nameOSGeo Release Repository/name urlhttps://repo.osgeo.org/repository/release//url /repository /repositories dependencies dependency groupIdorg.geotools/groupId artifactIdgt-shapefile/artifactId version28.5/version /dependency dependency groupIdorg.geotools/groupId artifactIdgt-epsg-hsql/artifactId version28.5/version /dependency /dependencies这里有个容易踩的坑只声明gt-shapefile时Maven不会帮你带出EPSG数据库。你可能代码里用到了CRS.decode(EPSG:4326)结果运行时报找不到org.geotools.referencing.factory.epsg原因就是缺少gt-epsg-hsql这个实现模块。建议直接用gt-referencing和gt-epsg-hsql组合再配合依赖管理中的版本属性保证整体版本统一。2.2 手动下载发行包并搭建离线仓库很多内网开发环境无法访问外网Maven仓库这时候只能使用离线jar包集合。去GeoTools官网下载对应版本的Release包里面会内置lib目录。注意这个lib目录只是GeoTools自身模块部分第三方依赖不一定全尤其是SQLite驱动、NetCDF、H2等可选模块。我在离线项目里一般会做成两层结构第一层是强制依赖目录比如GeoSolutions或GeoTools官方手动部署清单里列出来的基础jar第二层是按功能拆分的optional目录比如gt-geojson、gt-wms这些不常用的模块。这样既能保证主流程跑通又能按需添加而不是一股脑全部丢进lib最后冲突了都不知道谁和谁打架。2.3 基于jar包集合自行做本地复用如果你维护的是老式项目只能通过IDE手动导入jar包那么强烈建议另建一个本地“公共jar库”文件夹而不是把jar包散落在各个项目的lib目录里。原因是GeoTools的jar包集合在一定跨度内是可以复用的比如28.x系列之间可以共用一个目录20.x系列单独一个目录。每次升级时只替换整个文件夹而不是手动删掉几个jar、再补几个jar这样才能避免漏依赖。我也见过有同事把GeoTools的jar包集合做成一个zip压缩包内部保持固定目录结构在另一个项目里直接解压覆盖lib。这个做法可行但前提是把版本号写在目录名上否则半年后你根本分不清这套jar到底是哪个版本的到时候排查CRS问题会比登天还难。3. 把jar包集合用起来IDEA打包的完整流程3.1 创建Artifact把依赖一起打进去用IntelliJ IDEA手动打jar包最典型的行为就是以为“Buid Artifact”之后Spring项目就能跑结果命令行一执行就报ClassNotFoundException。原因很简单IDEA的普通Jar Artifact不会自动把所有依赖塞进去需要在“Project Structure - Artifacts - Jar - From modules with dependencies”里选择复制依赖到输出目录或者选择打包成包含依赖的Jar。关键路径是这样的打开项目结构左侧选Artifacts点加号选Jar然后选From modules with dependencies。在弹出窗口里选中主类Main ClassIDEA会生成MANIFEST.MF。此时务必勾选“Include in project build”构建项目时才会自动生成jar包。如果要依赖和代码一起打包成单个jar就在Artifacts的Output Layout面板里把所有依赖提取到根目录这样可以直接打成fat jar。3.2 Manifest主类与库路径设置即使打了fat jar也经常遇到“jar包双击没反应”或者“java -jar xxx.jar报错没有主清单属性”。这类问题九成出在MANIFEST.MF上。默认生成的文件可能是Manifest-Version: 1.0 Main-Class: com.example.Main Class-Path: lib/gt-main.jar lib/gt-shapefile.jar如果你的依赖没有打进jar包Class-Path就要指向旁边手动放置的lib目录。如果希望做成真正独立运行的jar包推荐使用Maven的shade插件或者IDEA里的fat jar方式把依赖全部合并进去。合并时要注意SPI文件特别是GeoTools的FactoryFinder机制依赖META-INF/services文件直接在IDEA里合并多个jar包时容易互相覆盖导致某些FactoryProvider找不到。3.3 打包后如何验证jar是否正常打包完永远不要直接丢给运维先自己做三件事第一用unzip -l xxx.jar看看关键类在不在第二用java -jar xxx.jar在当前环境实测一遍基本读shapefile和坐标转换功能第三观察是否出现重复的META-INF/services文件。如果发现打包后的jar里缺失resources文件夹下定义的EPSG数据库文件多半是IDEA普通Artifact没把resources复制进去导致的。我习惯在打包前先跑一遍mvn dependency:tree确认当前项目实际引了哪些GeoTools模块。如果你只是用IDEA手动导入的jar包集合那就用JD-GUI或其他反编译工具打开打包产物看一眼org.geotools包下是否有你需要的类。先把这一步习惯化后续少涨很多教训。4. 反编译jar包问题定位的救急手段4.1 常用反编译工具对比处理GeoTools相关jar包集合时难免会遇到查看jar包内部类、确认依赖版本、或者修改临时逻辑的需求。这里聊聊几个常用反编译工具。JD-GUI最直观适合快速看类结构但处理新版本Java的class文件偶尔会翻车。CFR是命令行工具稳定性好适合写脚本批量反编译。IDEA自带的Fernflower也不错直接在反编译窗口里看依赖库的源码不用额外装工具。比如你要确认某个gt-jar包内部引用的JTS版本用JD-GUI打开依赖列表搜索com.vividsolutions.jts或者org.locationtech.jts包路径马上就能鉴别是旧版还是新版。这个判断很重要因为JTS包名变化是GeoTools版本迁移中最常见的坑之一。4.2 如何从反编译结果中找版本冲突我遇到过最头疼的问题是项目里同时存在两个不同版本的gt-main.jar。由于IDEA的module设置中某个模块把老版本的gt-main加到了classpath最前面程序运行时优先加载了旧类新代码调用的新方法不存在直接抛NoSuchMethodError。用反编译工具打开两个jar包能够看到同一个类文件方法签名不一样立刻就能定位冲突。处理方案也很粗暴简单从classpath中移掉旧版本只保留和GeoTools其他jar包配套的版本。如果你不想手动维护推荐把所有GeoTools相关jar包按文件夹维度放在一起在IDEA中删除原有依赖再整体导入新的lib目录避免遗漏。4.3 改了jar包后IDEA仍提示只读的解决办法最近不少咨询我的网友提到把jar包解压、修改class文件重新放回去之后IDEA打开这个jar包里的类还是提示文件只读甚至怎么改都保存不了。这个我实际也踩过坑。原因通常是两类一类是IDEA自己的缓存和指纹记录因为jar包被外部工具修改后本地索引还是旧状态导致文件被标记为只读。另一类是解压后的文件放回后操作系统文件权限有问题尤其Windows下会出现只读属性。如果只是想快速改jar包里的某个配置或class建议不要直接对jar包做编辑。正确流程是把jar包用反编译工具处理成源码在IDEA里以Library或Module方式引用然后重新编译成class再用jar uf xxx.jar com/your/Class.class更新进去。更新完后如果IDEA还提示只读去File - Invalidate Caches并重启基本就能正常了。这是我在一个GIS工具项目中验证过的方法。5. 我在实际项目中反复踩过的坑5.1 关于GeoTools版本锁定的最终建议整理GeoTools相关jar包集合最容易犯的错就是依赖版本没人管。如果一个团队同时在多个项目中引用GeoTools建议在父POM或者依赖管理里统一锁定版本。我自己的做法是这样指定一个长期稳定版本例如GeoTools 28.x然后在所有子项目中只写groupId和artifactId不写version由父POM统一决定。这样可以避免“A模块用27、B模块用28”这种薛定谔状态。如果你还在维护一个只能靠lib目录引jar的老项目也一定要写一个依赖清单文件记录每个jar包的版本来源。最好不要只保留jar包本身一个txt描述文件在半年后会救你一命。5.2 小技巧按功能拆分或统一打包GeoTools相关jar包集合有两种常见用法第一种是为了压缩发布体积只保留真正用到的模块比如只读Shapefile就只需要核心几件套第二种是为了图省事把所有模块全部塞进去。我个人更推荐把“核心运行”和“可选扩展”分开。核心运行jar包约20MB左右可选扩展随用随加这样部署时出错概率会低很多。最后再分享一个细节当你要把项目打包成可执行jar并且还希望jar包里携带一个显示helloworld的静态HTML页面时别用new File去读取war包或jar包里的资源那样读不到。正确做法是用getClass().getResourceAsStream(/helloworld.html)这样不管你打的是fat jar还是普通jar包资源都能被正确读取。这个我会遇到是因为GeoTools项目的测试里也经常要输出临时HTML或GeoJSON调试页面算是很实用的经验了。本文还有配套的精品资源点击获取