
背景概述这段时间使用gdal的时候出现了一个找不到方法的的问题具体报错内容如下java.lang.NoSuchMethodError:intorg.gdal.gdal.Dataset.FlushCache() atit.geosolutions.imageio.gdalframework.GDALImageWriter.write(GDALImageWriter.java:357)问题解决通过定位这个错误是Dataset报出来的我们知道对GDAL的调用最终要走到native,具体方法定义下// Dataset 中的方法publicvoidFlushCache(){gdalJNI.Dataset_FlushCache(swigCPtr,this);}// native 方法publicfinalstaticnativevoidDataset_FlushCache(longjarg1,Datasetjarg1_);我们可以看到它最终是要去调用一个void的方法。由于我本地用的gdal是3.9.0ldd /usr/lib/x86_64-linux-gnu/libgdalalljni.so|grepgdal# 结果为 libgdal.so.39 或 libgdal.so.3.9.x在3.9的时候c的方法FlushCache的返回值已经被修改了返回的是一个int ,这样在调用的时候JVM 在链接 JNI 方法时发现签名不匹配我需要的是一个void方法找到的确实一个int,我没有int方法与之匹配所以就爆出了上面这个错误。这里可能存在一些误解我们可能会认为难道不是应该报错java.lang.NoSuchMethodError: ‘void org.gdal.gdal.Dataset.FlushCache()’ 因为是这个方法找不到但是其实原因如下JVM在解析调用 Dataset.FlushCache() 时严格依据调用方GDALImageWriter.write的字节码来查找被调用的方法。GDALImageWriter.write 方法在编译时其字节码中记录的调用目标是 返回类型为int的 FlushCache 方法。JVM在类 Dataset 中查找方法时发现只有一个名为 FlushCache、返回类型为 void 的方法。因为找不到字节码所要求的 int 返回类型的 FlushCache 方法所以JVM抛出 NoSuchMethodError并明确指出缺少的是 int 返回值版本。因此报错信息中的 int其实反映的是调用者GDALImageWriter.write的预期而非底层native库的直接“要求”。只不过在这个JNI场景下这个预期恰好与更高版本的native库实现一致。