为了账号安全,请及时绑定邮箱和手机立即绑定

内联类在 openJdk 上生成奇怪的名字

内联类在 openJdk 上生成奇怪的名字

HUWWW 2021-12-22 19:01:31
Hej,我正在用 kotlin 构建一个 Spring Boot 应用程序,并想使用内联类。我做了一个 spring 数据存储库,它有一个方法如下: fun getBy(name: GameName)其中 GameName 是一个内联类 inline class GameName(val value: String)一切都在本地运行,我正在运行 jdk 1.8.0_181-b13。但是当我将它部署到谷歌云时,spring boot 应用程序没有启动。谷歌云似乎正在运行 openjdk 1.8.0_181。当我在本地反编译代码时,它看起来像这样: public GameConfigurationEntity getBy_00UsoVY/* $FF was: getBy-00UsoVY*/(@NotNull String gameName, @NotNull UUID id) { ... }但是在谷歌云上我收到以下错误: Caused by: java.lang.ClassFormatError: Illegal method name "getByName-MZoZWhM"因此,它似乎在本地使用,_而在谷歌云上使用,-并且-在方法名称中不是有效字符。其他人有这个吗?完整的堆栈跟踪: [INFO] GCLOUD: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gameConfigurationService' defined in URL [jar:file:/app.jar!/BOOT-INF/classes!/com/hexigames/configurationservice/domain/game/GameConfigurationService.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class com.hexigames.configurationservice.domain.game.GameConfigurationService: Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null[INFO] GCLOUD:  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:581) ~[spring-beans-5.0.10.RELEASE.jar!/:5.0.10.RELEASE][INFO] GCLOUD:  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.10.RELEASE.jar!/:5.0.10.RELEASE][INFO] GCLOUD:  at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]
查看完整描述

2 回答

?
jeck猫

TA贡献1909条经验 获得超7个赞

关键点在堆栈跟踪的底部:


org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:336) ~[spring-core-5.0.10.RELEASE.jar!/:5.0.10.RELEASE]

[INFO] GCLOUD:  ... 43 common frames omitted

[INFO] GCLOUD: Caused by: java.lang.ClassFormatError: Illegal method name "createConfiguration-tQynZQ0" in class com/hexigames/configurationservice/domain/game/GameConfigurationService$$EnhancerBySpringCGLIB$$76757398

[INFO] GCLOUD:  at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_181]

[INFO] GCLOUD:  at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_181]

换句话说,Spring 使用自定义类加载器按需生成类。此类使用带有 - 的方法名称。defineClass1类加载器中的方法会阻塞它。由于类加载器用于加载任何类,我唯一的假设是谷歌云以某种方式使用了调整后的类加载器。由于类加载器对安全性非常敏感,这是有道理的,但显然您的 Kotlin 代码对安全性不敏感。


根据 JVM 规范,该-字符不是 JVM 级别方法名称中的非法字符:https : //docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.2。 2 . 因此,这似乎是谷歌云平台中的一个错误。顺便提一句。该字符在 Java 中是非法的,但 JVM 宽松得多。


查看完整回答
反对 回复 2021-12-22
?
侃侃无极

TA贡献2051条经验 获得超10个赞

发生这种情况是由于 kotlin 编译器进行了名称修改。接受内联类的函数不能从 Java 调用。(官方文档


查看完整回答
反对 回复 2021-12-22
  • 2 回答
  • 0 关注
  • 198 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信