在运行时创建 Pojo,并在将 pojo 保存到磁盘后抛出错误 class pruned?
Create Pojo at runtime and after saving pojo on to the disk throwing an error as class pruned?
参考以下link,我在运行时创建了classes,http://blog.javaforge.net/post/31913732423/howto-create-java-pojo-at-runtime-with-javassist.I之前或对使用了cc.writeFile("//path")
在您调用 cc.toClass()
之后,class 已存储在指定的位置。
但在 cc.writeFile().
后抛出如下错误无法继续
线程中出现异常 "main" java.lang.RuntimeException:toBytecode():EmployeeEntity 已被 p运行ed。
当查看 the source code 时,问题似乎是由于 wasChanged
和 pruned
都是 true
.
实际上,自动修剪应该默认关闭,至少在最近的版本中是这样。但是如果 class 文件已经被修剪过,它应该不允许后续修改。这导致得出结论,您不能在中间修改 CtClass
对象,因此错误不在您这边。在文件中搜索出现的 wasChanged
会发现忘记将其设置为 false
.
所以发生的事情是
- 你设置了建设中的class,将
wasChanged
变为true
。
- 您调用
toClass()
,后者又调用 toBytecode
,后者会将 pruned
和 frozen
设置为 true
,不允许进一步修改,但忘记了将 wasChanged
设置为 false
.
- 你调用
writeFile
,它也会调用 toBytecode
,它现在检测到文件已被修改,根据它永不重置的标志,并抛出异常,作为 class 已被修剪。
如果交换 toClass()
和 writeFile
,逻辑保持不变,因为两者都在内部调用 toBytecode
,不能调用两次,给定上述行为。
您有多种选择。
您可以在 调用 toClass()
之前调用 debugWriteFile(path)
,因为 debugWriteFile
被记录为“不修剪或冻结” class 写入 class 文件后。
您可以在调用writeFile
或toClass
之前调用stopPruning(true)
。如上所述,默认情况下修剪应该是均匀的。
您可以自己直接调用toBytecode()
,并且只调用一次。然后……
一旦你有了字节数组,你可以简单地将它写入一个文件(例如Files.write(Paths.get(pathString), byteArray)
.
要使用此现有字节数组创建 class,您可以使用自己的 class 加载程序或使用 MethodHandles.lookup().defineClass(array)
,如果您在 Java 9 或更高版本并在您自己的包中创建一个 class。
这可能有点复杂,但由于只构建一次 class 文件字节,因此它是最有效的解决方案。
参考以下link,我在运行时创建了classes,http://blog.javaforge.net/post/31913732423/howto-create-java-pojo-at-runtime-with-javassist.I之前或对使用了cc.writeFile("//path")
在您调用 cc.toClass()
之后,class 已存储在指定的位置。
但在 cc.writeFile().
线程中出现异常 "main" java.lang.RuntimeException:toBytecode():EmployeeEntity 已被 p运行ed。
当查看 the source code 时,问题似乎是由于 wasChanged
和 pruned
都是 true
.
实际上,自动修剪应该默认关闭,至少在最近的版本中是这样。但是如果 class 文件已经被修剪过,它应该不允许后续修改。这导致得出结论,您不能在中间修改 CtClass
对象,因此错误不在您这边。在文件中搜索出现的 wasChanged
会发现忘记将其设置为 false
.
所以发生的事情是
- 你设置了建设中的class,将
wasChanged
变为true
。 - 您调用
toClass()
,后者又调用toBytecode
,后者会将pruned
和frozen
设置为true
,不允许进一步修改,但忘记了将wasChanged
设置为false
. - 你调用
writeFile
,它也会调用toBytecode
,它现在检测到文件已被修改,根据它永不重置的标志,并抛出异常,作为 class 已被修剪。
如果交换 toClass()
和 writeFile
,逻辑保持不变,因为两者都在内部调用 toBytecode
,不能调用两次,给定上述行为。
您有多种选择。
您可以在 调用
toClass()
之前调用debugWriteFile(path)
,因为debugWriteFile
被记录为“不修剪或冻结” class 写入 class 文件后。您可以在调用
writeFile
或toClass
之前调用stopPruning(true)
。如上所述,默认情况下修剪应该是均匀的。您可以自己直接调用
toBytecode()
,并且只调用一次。然后……一旦你有了字节数组,你可以简单地将它写入一个文件(例如
Files.write(Paths.get(pathString), byteArray)
.要使用此现有字节数组创建 class,您可以使用自己的 class 加载程序或使用
MethodHandles.lookup().defineClass(array)
,如果您在 Java 9 或更高版本并在您自己的包中创建一个 class。
这可能有点复杂,但由于只构建一次 class 文件字节,因此它是最有效的解决方案。