gpt4 book ai didi

java - Hibernate 5 + Spring + JDBC 瘦客户端 UCP 接口(interface)对类加载器不可见

转载 作者:行者123 更新时间:2023-11-30 05:48:34 25 4
gpt4 key购买 nike

我已经升级了以下库:

  • Spring 3.2.0 -> 4.3.22
  • hibernate 4.1.1 -> 5.1.11

值得注意的是,我还使用 JDBC 瘦客户端库

  • OJDBC 7
  • ucp 12.1.0
  • 12.1.0

我正在开发一个 Axis2 服务,该服务最终部署在 WSO2 应用程序服务器中。初始化的一部分是加载 hibernate session 工厂。定义如下。

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name = "dataSource" ref = "dataSource"></property>
</bean>

当我初始化 bean 时,我通过 ClassPathXmlApplicationContext 来完成它,该上下文指向带有我的 hibernate session 工厂定义的文件。

final ClassLoader classLoader = service.getClassLoader();
ClassPathXmlApplicationContext appCtx = new ClassPathXmlApplicationContext(new String[] {"repository/conf/pda/applicationContext_dataInventory.xml"}, false)
appCtx.setClassLoader(classLoader);
appCtx.refresh(); // <--- Causes error

当我打电话appCtx.refresh()时,我收到一个异常,说明

Caused by: java.lang.IllegalArgumentException: interface oracle.ucp.jdbc.LabelableConnection is not visible from class loader
at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:616)
at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:592)
at java.lang.reflect.WeakCache$Factory.get(WeakCache.java:244)
at java.lang.reflect.WeakCache.get(WeakCache.java:141)
at java.lang.reflect.Proxy.getProxyClass0(Proxy.java:455)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:738)
at oracle.ucp.jdbc.proxy.ConnectionProxyFactory.createConnectionProxy(ConnectionProxyFactory.java:79)
at oracle.ucp.jdbc.PoolDataSourceImpl.getConnection(PoolDataSourceImpl.java:1046)
at com.xxx.espds.cim.dataMgmt.hibernate.FailoverPoolDataSource.getConnection(FailoverPoolDataSource.java:519)
at com.xxx.espds.cim.dataMgmt.hibernate.FailoverPoolDataSource.getConnection(FailoverPoolDataSource.java:497)
at com.xxx.espds.cim.dataMgmt.hibernate.FailoverPoolDataSource.getConnection(FailoverPoolDataSource.java:492)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.internal.SessionFactoryImpl$3.obtainConnection(SessionFactoryImpl.java:677)
at org.hibernate.hql.spi.id.IdTableHelper.executeIdTableCreationStatements(IdTableHelper.java:67)
at org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy.finishPreparation(GlobalTemporaryTableBulkIdStrategy.java:125)
at org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy.finishPreparation(GlobalTemporaryTableBulkIdStrategy.java:42)
at org.hibernate.hql.spi.id.AbstractMultiTableBulkIdStrategyImpl.prepare(AbstractMultiTableBulkIdStrategyImpl.java:88)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:471)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:422)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:711)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:727)
at org.springframework.orm.hibernate5.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:511)
at org.springframework.orm.hibernate5.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:495)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1689)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1627)

如果我在刷新调用之前通过调用 appCtx.getClassLoader().loadClass("oracle.ucp.jdbc.LabelableConnection"); 手动加载类那么这个特定的错误就会消失,但我最终会在类加载器不可见的另一个接口(interface)上出现错误。我的想法是,这与 Spring/Hibernate 没有使用与我给ClassPathXmlApplicationContext相同的类加载器有关。 。

为什么 UCP 类在 session 工厂初始化时不可见?

最佳答案

通过将线程类加载器设置为用于 ClassPathXmlApplicationContext 的 ClassLoader 解决了该问题。 oracle JDBC 最终尝试使用 Thread.currentThread().getContextClassLoader(); 从 UCP 依赖项加载一些它自己的类。 。下面详细说明了修复的代码

// Get current thread ClassLoader and reset it after we do the initial load. While we previously set the
// Spring ClassLoader, when we initialize the UCP ConnectionPool via the hibernate sessionFactory the jdbc
// thin client attempts to load classes using the currentThread().getContextClassLoader(). To get around this,
// we need to set the threads ClassLoader to the one that has information on the JDBC libraries, and since we
// always package up the libraries in each service, that would be the service.getClassLoader()
final ClassLoader classLoader = service.getClassLoader();
ClassPathXmlApplicationContext appCtx = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml"}, false);
appCtx.setClassLoader(classLoader);
ClassLoader threadLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
appCtx.refresh();
Thread.currentThread().setContextClassLoader(threadLoader);

关于java - Hibernate 5 + Spring + JDBC 瘦客户端 UCP 接口(interface)对类加载器不可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54408435/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com