You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

URLClassLoader加载多版本JAR遇UnsupportedClassVersionError问题排查

问题描述

我使用URLClassLoader为基于OpenJDK15编译的应用动态加载JDBC驱动,因部分驱动存在兼容问题无法升级JDK版本。其中一款驱动依赖的truffle-api-22.2.0.jar包含META-INF/versions/11和17两个版本目录,加载该JAR时抛出如下异常:

java.lang.UnsupportedClassVersionError: META-INF/versions/17/module-info has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 59.0
java.lang.UnsupportedClassVersionError: META-INF/versions/17/module-info has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 59.0
  at java.base/java.lang.ClassLoader.defineClass1(Native Method)
  at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
  at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151)
  at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:825)
  at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:723)
  at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:646)
  at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604)
  at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
  at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:576)
  at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
  at com.wisecoders.dbs.dbms.driver.model.a.a(DriverClassLoader.java:132)
  at com.wisecoders.dbs.dbms.driver.model.a.b(DriverClassLoader.java:110)
  at com.wisecoders.dbs.dbms.driver.model.a.a(DriverClassLoader.java:88)
  at com.wisecoders.dbs.dbms.driver.model.a.a(DriverClassLoader.java:66)
  at com.wisecoders.dbs.dbms.driver.model.a.<init>(DriverClassLoader.java:34)

加载代码如下:

urlClassLoader = new URLClassLoader( urlsArray, OneClassFromMyCode.class.getClassLoader() );
urlClassLoader.loadClass( className );

按URLClassLoader文档说明,它应该支持多版本JAR,请问问题原因可能是什么?

问题原因分析
  • 多版本JAR模块信息处理逻辑缺陷:JDK 9+的多版本JAR规范要求,META-INF/versions/N下的module-info.class仅在运行时JDK版本≥N时才会被加载,但OpenJDK15(类文件版本59.0)却尝试加载了JDK17(类文件版本61.0)对应的module-info。本质是URLClassLoader在处理模块信息时,未正确过滤高于当前运行时版本的module-info文件,错误地将所有版本目录下的该文件纳入加载流程。
  • 类加载委托机制干扰:创建URLClassLoader时指定了应用类加载器作为父加载器,当加载truffle-api相关资源时,父加载器(AppClassLoader)会优先执行类查找逻辑,而AppClassLoader对多版本JAR的处理存在缺陷,误读取了高版本目录下的module-info文件。
  • 目标JAR的多版本格式不规范:truffle-api-22.2.0.jar的版本目录结构可能不符合规范,比如META-INF/versions/17下的module-info未正确关联仅JDK17及以上才需加载的类,导致低版本JDK扫描JAR时误触发了该文件的加载操作。

内容的提问来源于stack exchange,提问作者DbSchema

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 17:48:30