生成Javaassist运行时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

创建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.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
是一个字符串列表,它将成为方法名称。在这种情况下,您的代码偏离了教程,因此我们需要更详细的说明。如果不知道你实际上在做什么,很难帮助你,我们所能做的就是猜测。我已经用最少的代码更新了这个问题。