英文:
"The code for the static initializer is exceeding the 65535 bytes limit" : Message in a bottle
问题
让我解释一下我的问题。
背景:
- 将 JDK 8 迁移到 JDK 17,涉及到一个包含超过 7500 个元素的大型客户端/服务器应用程序(总代码行数约为 2.5 百万)
- 我们有一个包含所有安全权限的巨大枚举(>7500 个元素)
- 这个枚举被一个注解使用,其目标可以是类型或方法,例如:
@Access(Right.R_A30110)
public void method(...) {...}
如果我使用 JDK 8
没有问题!它可以编译并运行得很好。
使用 JDK 17
错误消息:“静态初始化程序的代码超过了 65535 字节的限制!”
a) 首先,我不明白为什么在 JDK 17 中会出现这个错误消息。我已经阅读了很多页面,我理解了错误消息,但我应该在 JDK 8 中也会遇到相同的问题吗?
b) 我需要解决这个问题 我尝试过(或想尝试的):
- 将大型枚举拆分成小部分 => 不可能,因为枚举不允许继承
- 使用 Java 5 之前的策略:创建一个类和一组常量(类似于
R_A30110=new Right("R_A30110");
)=> 不可能,因为我会遇到错误消息“注解属性 'value' 的类型无效:只允许原始类型、字符串、类、注解、枚举或其 1 维数组”
=> 风险是该解决方案可能会导致相同的问题(65535 字节限制...)
你有任何我可能忽略的想法吗?
谢谢!
英文:
Let me explain my problem.
Context :
- Migration JDK 8 > JDK 17 of a 2.5M LOC client/server application
- We have a huge enumeration (>7500 elements) that contains all security rights
- This enumeration is used by an annotation which target can be a type or a method, ex :
@Access(Right.R_A30110)
public void method(...) {...}
If I work with JDK 8
No problem ! It compiles and runs perfectly.
With JDK 17
Error message The code for the static initializer is exceeding the 65535 bytes limit !
a) First, I don't understand why I have this error message with JDK 17. I've read a lot of pages, I understand the error message but I should have the same with JDK 8 ??
b) I need to solve the problem What I tried (or wanted to try) :
- split the big enumeration into small parts => not possible because inheritance is not allowed for Enums
- use the pre-java 5 strategy : create a class and a set of constants (something like
R_A30110=new Right("R_A30110");
=> not possible because the I'll have the error invalid type for the annotation attribute 'value' : only primitive type, String, Class, annotation, enumeration are permitted or 1-dimensional arrays thereof
=> The risk is that solution may lead to the same problem (65535 bytes limitation...=
Do you have any idea I missed ?
Thank you !
答案1
得分: 1
让我们先不考虑在这个问题的评论中提到的顾虑:虽然它们是正确的,但它们引发了不同的问题。
您正在使用枚举是因为您希望在使用不存在的访问权限时,编译器可以提前警告您。否则,您也可以将字符串用作注释的值...
但因为您正在使用注释,您可以使用字符串,并在编译时通过编写注释处理器来检查@Access
注释值(现在是一个字符串)与有效值列表是否匹配,如果不匹配,注释处理器将引发异常并停止编译,否则它不做任何操作。
唯一的缺点是IDE在应用值时不会帮助您。
但稍微付出更多的努力,您可以扩展注释处理器以执行一些额外的检查,例如给定位置是否可行的访问权限,或者是否多次应用相同的访问权限(或从不应用)等等... 请考虑一下。
英文:
Let's put aside the concerns mentioned in the comments to this question: although they are correct, they raise different issues.
You are using the enum because you want to have already the compiler warning you when using an access right that does not exist. Otherwise you could also use a string as the value for the annotation …
But because you are using an annotation, you can use a string and get the compiler to warn you if the given access right does not exist: write an annotation processor that checks the @Access
annotation value (now a string) against a list of valid ones at compile time. If not matching, the annotation processor throws an exception and stops the compilation, otherwise it does nothing.
Only drawback is that the IDE won't help you when applying the value.
But with a little bit more effort you can extend the annotation processor to do some additional checks, like whether the given access right is feasible at the given location, or if the same access right is applied more than once (or never) or … think about.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论