Geotools在Spring Native GraalVM环境中Picocontainer报错排查
在Spring Boot Native(GraalVM)中使用GeoTools的Picocontainer错误解决
问题背景
在基于GraalVM的Spring Boot Native项目中引入GeoTools库后,运行时触发Picocontainer相关的InternalError,常规Java 21环境下运行完全正常。
错误信息
java.lang.InternalError: org.picocontainer.Startable.start() org.picocontainer.defaults.ImmutablePicoContainerProxyFactory.<clinit>(ImmutablePicoContainerProxyFactory.java:44) org.picocontainer.defaults.DefaultPicoContainer.<init>(DefaultPicoContainer.java:127) org.picocontainer.defaults.DefaultPicoContainer.makeChildContainer(DefaultPicoContainer.java:535) org.geotools.xsd.Configuration.setupContext(Configuration.java:520) org.geotools.xsd.impl.ParserHandler.startDocument(ParserHandler.java:299) java.xml@21.0.2/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startDocument(AbstractSAXParser.java:294) java.xml@21.0.2/com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.startDocument(XMLDTDValidator.java:622) java.xml@21.0.2/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.startEntity(XMLDocumentScannerImpl.java:545) java.xml@21.0.2/com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.startDocumentParsing(XMLVersionDetector.java:136) java.xml@21.0.2/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:875)[...]
复现代码
@Test void convertKmlToGeojson() throws ParseException, IOException, ParserConfigurationException, SAXException { String kml = "<kml xmlns=\"http://www.opengis.net/kml/2.2\"><Document>\n" + "<Placemark>\n" + "<ExtendedData></ExtendedData>\n" + " <Polygon>\n" + "<outerBoundaryIs>\n" + " <LinearRing><coordinates>22.615720840984466,-2.6129992627326004\n" + "22.615720840984466,-3.8632171769875328\n" + "24.49774574644212,-3.8632171769875328\n" + "24.49774574644212,-2.6129992627326004\n" + "22.615720840984466,-2.6129992627326004</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark></Document></kml>"; ByteArrayInputStream kmlInputStream = new ByteArrayInputStream(kml.getBytes()); Parser parser = new Parser(new KMLConfiguration()); SimpleFeature f = (SimpleFeature) parser.parse(kmlInputStream); Collection collection = (Collection) f.getAttribute("Feature"); System.out.println(collection); }
执行./gradlew nativeTest或./gradlew nativeCompile后运行均可触发错误。
版本信息
Java 21.0.2-graalce id 'org.springframework.boot' version '3.1.9' id 'io.spring.dependency-management' version '1.1.4' id 'org.graalvm.buildtools.native' version '0.9.28' implementation 'org.locationtech.jts.io:jts-io-common:1.19.0' implementation 'org.geotools:gt-main:29.1' implementation 'org.geotools:gt-geojson:29.1' implementation 'org.geotools.xsd:gt-xsd-kml:29.1'
已尝试方案
使用-Pagent收集反射元数据配置,但问题未解决。
解决方案
错误根源是GraalVM原生镜像编译时,Picocontainer的动态代理类和反射调用未被正确纳入元数据,需手动补充配置:
1. 添加GraalVM元数据配置文件
在项目src/main/resources/META-INF/native-image目录下创建以下两个文件:
reflect-config.json
[ { "name": "org.picocontainer.Startable", "allDeclaredMethods": true, "allPublicMethods": true }, { "name": "org.picocontainer.defaults.DefaultPicoContainer", "allDeclaredConstructors": true, "allPublicConstructors": true, "allDeclaredMethods": true, "allPublicMethods": true }, { "name": "org.geotools.xsd.Configuration", "allDeclaredMethods": true, "allPublicMethods": true } ]
proxy-config.json
[ { "interfaces": [ "org.picocontainer.PicoContainer", "org.picocontainer.Startable" ] } ]
2. 重新编译并运行
执行./gradlew nativeCompile重新构建原生镜像,或运行./gradlew nativeTest验证测试用例。
补充说明
如果仍有问题,需确保agent收集过程覆盖了所有代码路径:运行./gradlew -Pagent nativeTest时,保证测试用例完整执行,再将生成的元数据文件合并到上述手动配置中。
内容的提问来源于stack exchange,提问作者Lucas Gabriel
相关产品推荐
相关产品推荐

