java - 使用反射调用外部 JAR/CLASS 上包含 Hibernate 事务的方法 (Java EE)

标签 java hibernate reflection glassfish-4

美好的一天!我在使 hibernate 在外部 jar 上工作时遇到问题,该外部 jar 通过反射加载到我的 EJB 上。 到目前为止,我已经尝试了三个选项,但这些选项都不起作用,只是给了我错误。

这是我尝试过的代码片段。 我还对每个选项中发生错误的行添加了注释。

选项 1. 通过 HashMap/Map 将 session 从 EJB 传递到外部 JAR

我的 session Bean 类

public Object processRequest(Map parameters) {
    String runnerClass = (String) parameters.get("runnerClass");
    String value = (String) parameters.get("value");
    String jarPath = "csys.runner.jar";
    Object returnObj = null;
    try {
        parameters.put("sessionEjb", getSession());
        File f = new File(jarPath);
        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{f.toURL()},
                System.class.getClassLoader());
        Class c = urlClassLoader.loadClass(runnerClass);
        Method m = c.getMethod("performService", new Class[]{String.class, Map.class});
        returnObj = m.invoke(c.newInstance(), new Object[]{value, parameters});
    } catch (MalformedURLException | ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
        Logger.getLogger(CSysSessionBean.class.getName()).log(Level.SEVERE, null, ex);
        throw new RuntimeException(ex);
    }
    return returnObj;
}

外部JAR方法

public Object performService(String value, Map<Object, Object> parameters) {
    this.session = (Session) parameters.get("sessionEjb");  // ERROR IN THIS PART ClassCastException
    return null;

它给了我这个错误。

java.lang.ClassCastException: org.hibernate.internal.SessionImpl cannot be cast to org.hibernate.Session

选项 2. 通过方法的参数将 session 从 EJB 传递到外部 JAR 我的 session Bean 类

public Object processRequest(Map parameters) {
    String runnerClass = (String) parameters.get("runnerClass");
    String value = (String) parameters.get("value");
    String jarPath = "csys.runner.jar";
    Object returnObj = null;
    try {
        File f = new File(jarPath);
        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{f.toURL()},
                System.class.getClassLoader());
        Class c = urlClassLoader.loadClass(runnerClass);
        Method m = c.getMethod("performService", new Class[]{String.class, Map.class, org.hibernate.Session.class}); //ERROR IN THIS PART NoSuchMethodException
        returnObj = m.invoke(c.newInstance(), new Object[]{value, parameters, getSession()});
    } catch (MalformedURLException | ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
        Logger.getLogger(CSysSessionBean.class.getName()).log(Level.SEVERE, null, ex);
        throw new RuntimeException(ex);
    }
    return returnObj;
}

外部JAR方法

public Object performService(String value, Map<Object, Object> parameters, org.hibernate.Session session) {
    this.session = session;  
    return null;
}

现在它向我抛出这个错误。

java.lang.NoSuchMethodException: csys.server.main.runner.ProjectRunner.performService(java.lang.String, java.util.Map, org.hibernate.Session)

选项 3. 在外部 JAR 中创建 session

我的 session Bean 类

public Object processRequest(Map parameters) {
    String runnerClass = (String) parameters.get("runnerClass");
    String value = (String) parameters.get("value");
    String jarPath = "csys.runner.jar";
    String configPath = "D:/config/hibernate.cfg.xml";
    Object returnObj = null;
    try {
        File f = new File(jarPath);
        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{f.toURL()},
                System.class.getClassLoader());
        Class c = urlClassLoader.loadClass(runnerClass);
        Method m = c.getMethod("performService", new Class[]{String.class, Map.class, String.class}); 
        returnObj = m.invoke(c.newInstance(), new Object[]{value, parameters, configPath});
    } catch (MalformedURLException | ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
        Logger.getLogger(CSysSessionBean.class.getName()).log(Level.SEVERE, null, ex);
        throw new RuntimeException(ex);
    }
    return returnObj;
}

外部JAR方法

public Object performService(String value, Map<Object, Object> parameters, String configPath) {
    Configuration configuration = new Configuration();
    configuration.configure(new File(configpath)); //ERROR IN THIS PART, COULD NOT PARSE CONFIGURATION
    SessionFactory sessionFactory = configuration.buildSessionFactory();
    this.session = sessionFactory.openSession();  
    return null;
} 

现在它又抛出了另一个错误。

org.hibernate.HibernateException: Could not parse configuration: D:\config\hibernate.cfg.xml
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2163)
at org.hibernate.cfg.Configuration.configure(Configuration.java:2133)
Caused by: org.dom4j.DocumentException: org.dom4j.DocumentFactory cannot be cast to org.dom4j.DocumentFactory Nested exception: org.dom4j.DocumentFactory cannot be cast to org.dom4j.DocumentFactory

请注意,在我的 EJB 项目中执行 hibernate 事务运行良好,只是从外部 jar 执行时会出现错误。

最佳答案

已经找到修复方法。 问题出在我的类加载器上。

System.class.getClassLoader()

应该是

this.getClass().getClassLoader()

关于java - 使用反射调用外部 JAR/CLASS 上包含 Hibernate 事务的方法 (Java EE),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49043986/

相关文章:

java - 对象关系映射的缺点

java - Jackson 数据绑定(bind)模型解码对象数组

c# - 无法删除集合 : [NHibernate. Exceptions.GenericADOException]

java - 如何使用 Hibernate 在两个实体(不相关的实体)之间进行联接

java - 类型安全代理创建

java - 使用 GSON 反序列化嵌套的通用类时的奇怪行为

c# - 有没有一种简单的方法可以将对象属性转换为字典<string, string>

java - 我如何检测 JasperViewer 处理报告时间

java - 不区分大小写的 RegEx 模式

java - hibernate 外键未在 SaveOrUpdate 上更新