问题描述
我有一个遗留应用程序,其中一个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每个类的大小限制。
你能做什么?好吧,这取决于情况:
-
将类分解为较小的部分,并通过自动测试进行重构,以确保分解后的内容与以前相同。是否为旧版,代码就是代码,您可以对其进行修改。
-
如果出于任何原因,您太害怕,不熟练或懒惰以至于无法重构和幸运,以至于怪物类实际上不需要任何方面的建议,您可以将切入点修改为不那么全局,而更多具体来说,不包括怪物类,甚至不包括更大一部分的旧版软件包,具体取决于您的用例。