GraalVM开启Nashorn兼容后Java枚举与字符串比较结果不匹配问题
解决方案
这个差异的根本原因是Nashorn默认实现了Java枚举与字符串做相等比较时的隐式转换,会自动调用枚举的
name()方法获取枚举名后再做对比,但GraalVM现有js.nashorn-compat兼容模式暂未覆盖这个隐式转换场景。
方案1:JS代码侧适配(适合JS代码量少的场景)
直接修改JS中的比较逻辑,显式调用枚举的name()或者toString()方法再做比较:
// 把原来的 color == 'GREEN' 改成以下任意一种 color.name() == 'GREEN' color.toString() == 'GREEN'
修改后无需调整Java侧的GraalJS配置,即可得到和Nashorn一致的结果。
方案2:Java侧全局配置兼容(无需修改JS代码,完全对齐Nashorn行为)
自定义HostAccess规则,为所有Java枚举类型注册到字符串的隐式转换逻辑,替换原来的HostAccess.ALL即可:
HostAccess nashornAlignHostAccess = HostAccess.newBuilder(HostAccess.ALL) // 配置所有枚举类型转字符串时默认返回枚举名,对齐Nashorn行为 .targetTypeMapping(Enum.class, String.class, enumObj -> true, Enum::name) .build(); ScriptEngine lEngine = GraalJSScriptEngine.create( null, Context.newBuilder("js").allowHostClassLookup((s) -> true) // 替换为自定义的HostAccess .allowHostAccess(nashornAlignHostAccess) .allowExperimentalOptions(true) .option("js.nashorn-compat", "true") );
配置完成后,原有JS代码中的color == 'GREEN'语句会直接返回true,和Nashorn执行结果完全一致。
内容的提问来源于stack exchange,提问作者Sébastien Bouat
相关产品推荐
相关产品推荐

