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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)相关的知识,希望对你有一定的参考价值。

美好的一天!我有问题使hibernate在外部jar上工作,这个jar通过我的EJB反射加载。截至目前,我已经尝试了三个选项,但这些都没有,只是给了我错误。

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

选项1.将会话从EJB传递到外部JAR THRU HashMap / Map

我的会话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.通过方法的参数将会话从EJB传递到外部JAR我的会话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中创建会话

我的会话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:confighibernate.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执行给我错误。

答案

找到了解决方案。问题出在我的ClassLoader上。

System.class.getClassLoader()

应该

this.getClass().getClassLoader()

以上是关于使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)的主要内容,如果未能解决你的问题,请参考以下文章

Axios - 防止在外部 api 调用上发送 JWT 令牌

打包springboot在外部tomcat运行

一个项目软件的大小基本都占用在外部引用的jar包上了。

spring boot项目将配置文件打包在外部

如何在外部网页上自动填充表单数据?

在外部样式表中查找 CSS 类的定义