参考以下链接,我在运行时创建了这些类,http://blog.javaforge.net/post/31913732423/howto-create-java-pojo-at-runtime-with-javassist.I在调用cc.writeFile("//path")
之前或之后立即使用cc.toClass()
,该类已存储在该位置指定。
但是在cc.writeFile()之后无法继续抛出以下错误。
线程“ main”中的异常java.lang.RuntimeException:toBytecode():修剪了EmployeeEntity。
答案 0 :(得分:0)
看the source code时,问题似乎是由于wasChanged
和pruned
两者都是true
造成的。
实际上,默认情况下,自动修剪功能应该处于关闭状态,至少在最新版本中是这样。但是,如果类文件已被修剪,则不应允许后续修改。这样得出的结论是,您不能在两者之间修改CtClass
对象,因此该错误不在您身边。搜索文件中wasChanged
的出现表明,将其设置为false
已被忘记。
那么会发生什么事
wasChanged
变为true
。toClass()
,这反过来又调用toBytecode
,这会将pruned
和frozen
设置为true
,不允许进行进一步修改,但忘记设置wasChanged
至false
。writeFile
,它也会调用toBytecode
,它现在根据从未重置的标志检测到文件已被修改,并抛出异常,因为该类已被删除。修剪。如果您交换toClass()
和writeFile
,则逻辑保持不变,因为这两种情况都是在内部调用toBytecode
的事实,鉴于此行为,不能调用两次如上所述。
您有几种选择。
您可以先调用debugWriteFile(path)
,然后再调用toClass()
,因为debugWriteFile
被记录为“在编写类文件后不修剪或冻结类” ”。
您可以先致电stopPruning(true)
,然后再致电writeFile
或toClass
。如上所述,默认情况下,修剪应保持关闭状态。
您可以直接自己打toBytecode()
,并且只能打一次。然后...
拥有字节数组后,您只需将其写入文件即可(例如Files.write(Paths.get(pathString), byteArray)
。
要使用此现有字节数组创建类,如果您使用的是Java 9或更高版本,则可以使用自己的类加载器或使用MethodHandles.lookup().defineClass(array)
,并在自己的包中创建一个类。 / p>
这可能有点复杂,但是由于它仅构造一次类文件字节,因此是最有效的解决方案。