生成Javaassist运行时POJO时发生异常
创建POJO时出现以下错误:生成Javaassist运行时POJO时发生异常,java,exception,pojo,javassist,Java,Exception,Pojo,Javassist,创建POJO时出现以下错误: java.lang.RuntimeException: act_ge_bytearray: frozen class (cannot edit) at javassist.ClassPool.checkNotFrozen(ClassPool.java:587) ~[javassist-3.25.0-GA.jar:na] at javassist.ClassPool.makeClass(ClassPool.java:829) ~[javassist-3
java.lang.RuntimeException: act_ge_bytearray: frozen class (cannot edit)
at javassist.ClassPool.checkNotFrozen(ClassPool.java:587) ~[javassist-3.25.0-GA.jar:na]
at javassist.ClassPool.makeClass(ClassPool.java:829) ~[javassist-3.25.0-GA.jar:na]
at javassist.ClassPool.makeClass(ClassPool.java:806) ~[javassist-3.25.0-GA.jar:na]
我以以下方式创建POJO:
Class clazz=null;
试一试{
clazz=PojoGenerator.generate(“net.javaforge.blog.javassist.Pojo$Generated”,props);
}捕获(未发现异常){
e、 printStackTrace();
}捕获(不能编译异常e){
e、 printStackTrace();
}
选择特定表后将创建对象。在第一次尝试中,它起作用,但任何其他尝试都失败
例如,在选择对象foo
后的第一次尝试中,POJO创建得很好,但在选择另一项后,问题出现了
编辑
我根据以下教程创建了POJO生成器类:
编辑2
我使用Vaadin在Web应用程序中表示PostgreSQL表的模式
下面的代码获取所选表的每一列,并为给定名称创建属性
、获取者
和设置者
。然后在所选表中创建尽可能多的对象和is记录
package pl.registers.spring.view;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
import javassist.CannotCompileException;
import javassist.NotFoundException;
import pl.registers.spring.service.DbService;
import pl.registers.spring.test.DatabaseTableModel;
import pojo.PojoGenerator;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Route("")
public class TablesView extends VerticalLayout {
private List<String> tables;
public TablesView() {
Connection con=null;
try {
con = DriverManager.getConnection("jdbc:postgresql://localhost:5432/process-engine", "postgres",
"postgres");
} catch (SQLException e) {
e.printStackTrace();
}
ComboBox tablesCombo = new ComboBox();
try {
tables = DbService.getInstance().getTableNames(con);
} catch (SQLException e) {
e.printStackTrace();
}
Map<String, Class<?>> props = new HashMap<String, Class<?>>();
List items = new ArrayList();
Grid grid = new Grid();
try {
tablesCombo.setItems(DbService.getInstance().getTableNames(con));
} catch (SQLException e) {
e.printStackTrace();
}
tablesCombo.addValueChangeListener(table -> {
items.clear();
try {
DatabaseTableModel dP = new DatabaseTableModel(DriverManager.getConnection("jdbc:postgresql://localhost:5432/process-engine", "postgres",
"postgres"), table.getValue());
//get column names
for(int i = 0; i < dP.getColumnCount(); i++) {
props.put(dP.getColumnName(i), String.class);
}
//get records
System.out.println("data vector: " + dP.getDataVector());
//generate Class schema
Class<?> clazz = null;
try {
clazz = PojoGenerator.generate(
"net.javaforge.blog.javassist.Pojo$Generated", props);
// table.getValue().toString(), props);
} catch (NotFoundException e) {
e.printStackTrace();
} catch (CannotCompileException e) {
e.printStackTrace();
}
//create as many objects as many records
try {
for(int i = 0; i < dP.getDataVector().size(); i++) {
items.add(clazz.newInstance());
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
List dataVectorCastedToList = dP.getDataVector();
//set objects values
for(int i = 0; i <= items.size()-1; i++) {
try {
clazz.getMethod("Constructor", java.util.List.class).invoke(items.get(i), dataVectorCastedToList.get(i));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
List<String> getters = new ArrayList<>();
//get methods
for(int i = 0; i < clazz.getMethods().length-1; i++){
String methodName = clazz.getMethods()[i].getName();
if(methodName.contains("get")) {
getters.add(methodName);
}
}
//remove getClass method
if(getters.contains("getClass"))
getters.remove("getClass");
System.out.println("getters" + getters);
grid.setItems(items);
//set columns
getters.forEach(item -> {
grid.addColumn(column -> {
try {
return
column.getClass().getMethod(item).invoke(column);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}).setHeader(item);
});
} catch (SQLException e) {
e.printStackTrace();
}
});
//add to layout
add(tablesCombo, grid);
}
}
很抱歉代码很难看,但它只是一个最小版本
有谁能就如何解决这个问题提供一些指导吗?实际上,这是Javassist库所做的一项检查,因为Java中不能有两个相同的类名和包:
Class<?> clazz = PojoGenerator.generate( "net.javaforge.blog.javassist.Pojo$Generated", props);
Class<?> clazz2 = PojoGenerator.generate( "net.javaforge.blog.javassist.Pojo$Generated", props);
我从您的完整示例中看到,这是通过一些外部调用以友好方式生成的,因此,为了解决这个问题,您可能需要找到一种方法来存储表生成的结果(即本地映射),并仅在缺少该结果时才调用generate。可能是这样的:
Map<String, Class<?>> cache = new HashMap<String, Class<?>>();
...
Class<?> clazz = null;
try {
if (cache.containsKey("your.package.yourTableName$Generated")) {
clazz = cache.get("your.package.yourTableName$Generated");
} else {
clazz = PojoGenerator.generate( "your.package.yourTableName$Generated", props);
cache.put("your.package.yourTableName$Generated", clazz);
}
}...
Map>();
...
类clazz=null;
试一试{
if(cache.containsKey(“your.package.yourTableName$Generated”)){
clazz=cache.get(“your.package.yourTableName$Generated”);
}否则{
clazz=PojoGenerator.generate(“your.package.yourTableName$Generated”,props);
cache.put(“your.package.yourTableName$Generated”,clazz);
}
}...
实际上,这是由Javassist库完成的检查,因为Java中不能有两个相同的类名和包:
Class<?> clazz = PojoGenerator.generate( "net.javaforge.blog.javassist.Pojo$Generated", props);
Class<?> clazz2 = PojoGenerator.generate( "net.javaforge.blog.javassist.Pojo$Generated", props);
我从您的完整示例中看到,这是通过一些外部调用以友好方式生成的,因此,为了解决这个问题,您可能需要找到一种方法来存储表生成的结果(即本地映射),并仅在缺少该结果时才调用generate。可能是这样的:
Map<String, Class<?>> cache = new HashMap<String, Class<?>>();
...
Class<?> clazz = null;
try {
if (cache.containsKey("your.package.yourTableName$Generated")) {
clazz = cache.get("your.package.yourTableName$Generated");
} else {
clazz = PojoGenerator.generate( "your.package.yourTableName$Generated", props);
cache.put("your.package.yourTableName$Generated", clazz);
}
}...
Map>();
...
类clazz=null;
试一试{
if(cache.containsKey(“your.package.yourTableName$Generated”)){
clazz=cache.get(“your.package.yourTableName$Generated”);
}否则{
clazz=PojoGenerator.generate(“your.package.yourTableName$Generated”,props);
cache.put(“your.package.yourTableName$Generated”,clazz);
}
}...
请不要使用评论,而是通过添加其他信息到您的问题中。您要传递的道具是什么?我假设这是一个地图,根据教程,但它包含什么?理想情况下,您应该提供一个。props
是一个字符串列表,它将成为方法名称。在这种情况下,您的代码偏离了教程,因此我们需要更详细的说明。在不知道您实际在做什么的情况下,很难提供帮助,我们所能做的就是猜测。我已经用最少的代码更新了问题。请不要使用注释,而是通过添加其他信息到您的问题中。您传递的道具是什么?我假设这是一个地图,根据教程,但它包含什么?理想情况下,您应该提供一个。props
是一个字符串列表,它将成为方法名称。在这种情况下,您的代码偏离了教程,因此我们需要更详细的说明。如果不知道你实际上在做什么,很难帮助你,我们所能做的就是猜测。我已经用最少的代码更新了这个问题。