springboot LaunchedURLClassLoader引发的错误类超出了JVM支持的最大类大小常量池太大

问题描述

我有一个遗留应用程序,其中一个Java文件的行数约为280000。我有一个用于引导服务的spring boot应用程序,其中一项服务称为此巨大的JAVA文件。当我在不使用Aspectjweaver的情况下加载应用程序时,该应用程序运行良好,但在Java选项中指定javaagent时,该应用程序失败。我已经尝试了JVM堆,但没有帮助。

以下是错误堆栈跟踪:

[LaunchedURLClassLoader@7cbd213e] error at MYCLASS.java::0 The class MYCLASS exceeds the maximum class size supported by the JVM (constant pool too big).
Aug 14,2020 3:42:01 PM org.aspectj.weaver.tools.Jdk14Trace error
SEVERE: MYCLASS 
java.lang.RuntimeException: key not found in wovenClassFile
        at org.aspectj.weaver.WeaverStateInfo.findEndOfKey(WeaverStateInfo.java:408)
        at org.aspectj.weaver.WeaverStateInfo.replaceKeyWithDiff(WeaverStateInfo.java:364)
        at org.aspectj.weaver.bcel.LazyClassGen.getJavaClassBytesIncludingReweavable(LazyClassGen.java:711)
        at org.aspectj.weaver.bcel.BcelWeaver.getClassFilesFor(BcelWeaver.java:1448)
        at org.aspectj.weaver.bcel.BcelWeaver.weaveAndNotify(BcelWeaver.java:1410)
        at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1188)
        at org.aspectj.weaver.tools.WeavingAdaptor.getWovenBytes(WeavingAdaptor.java:527)
        at org.aspectj.weaver.tools.WeavingAdaptor.weaveClass(WeavingAdaptor.java:363)
        at org.aspectj.weaver.loadtime.Aj.preProcess(Aj.java:121)
        at org.aspectj.weaver.loadtime.ClassPreProcessorAgentAdapter.transform(ClassPreProcessorAgentAdapter.java:54)
        at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
        at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:94)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.getDeclaredConstructors0(Native Method)
        at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
        at java.lang.Class.getDeclaredConstructors(Class.java:2020)
        at com.fasterxml.jackson.databind.util.ClassUtil.getConstructors(ClassUtil.java:1162)
        at com.fasterxml.jackson.databind.introspect.AnnotatedCreatorCollector._findPotentialConstructors(AnnotatedCreatorCollector.java:101)
        at com.fasterxml.jackson.databind.introspect.AnnotatedCreatorCollector.collect(AnnotatedCreatorCollector.java:56)

解决方法

AspectJ转换原始字节码,并向其添加其他指令和数据。因此,您的怪物类-谁会写这么疯狂的大类而又不以称呼自己是程序员为耻? -变得太大了,因为开始时可能接近JVM每个类的大小限制。

你能做什么?好吧,这取决于情况:

  • 将类分解为较小的部分,并通过自动测试进行重构,以确保分解后的内容与以前相同。是否为旧版,代码就是代码,您可以对其进行修改。

  • 如果出于任何原因,您太害怕,不熟练或懒惰以至于无法重构和幸运,以至于怪物类实际上不需要任何方面的建议,您可以将切入点修改为不那么全局,而更多具体来说,不包括怪物类,甚至不包括更大一部分的旧版软件包,具体取决于您的用例。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...