在 WebSphere 服务器上使用 JNDI 的 Spring 自定义数据源连接 [英] Spring Custom DataSource Connection with JNDI on WebSphere server

查看:47
本文介绍了在 WebSphere 服务器上使用 JNDI 的 Spring 自定义数据源连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有与帖子中指定的相同要求,即将用户 ID 作为客户端标识符传递以进行审核.使用 Hibernate 在 syscontext/connection 上传递 ClientInfo/ClientIdentifier用于审计目的

I have a same requirement as specified in post to pass user id as client identifier for audit purposes. Passing ClientInfo/ClientIdentifier on syscontext/connection with Hibernate for audit purposes

我采用了与8.2.自定义数据源连接准备器的配置中提到的相同的方法http://docs.spring.io/spring-data/jdbc/docs/current/reference/html/orcl.connection.html

I have followed the same approach as mentioned in 8.2.Configuration of a Custom DataSource Connection Preparer http://docs.spring.io/spring-data/jdbc/docs/current/reference/html/orcl.connection.html

下面是我拥有的一段代码:

Below is the piece of code which I have :

@Aspect
public class ClientIdentifierConnectionPreparer {

@AfterReturning(pointcut= "execution(* javax.sql.DataSource.getConnection(..))",
        returning = "connection")
public Connection setClientIdentifier(Connection connection) throws SQLException {
    CallableStatement cs=connection.prepareCall("{call DBMS_SESSION.SET_IDENTIFIER('XXXX')}");
    cs.execute();
    cs.close();
    return connection;
}

}

我已经配置了aop autoaspect proxy,如下所示.

I have configured aop autoaspect proxy as shown below.

<aop:aspectj-autoproxy />

    <bean id="connectionPreparer" 
        class="xx.xxxx.xxxx.xxxx.xxxx.ClientIdentifierConnectionPreparer" />

我正在websphere 服务器中部署我的网络服务.一切正常如果我使用 apache dbcp BasicDataSource 配置数据源:

I am deploying my web service in websphere server. Everything is working fine If I configure data source using apache dbcp BasicDataSource:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

代码在上述配置下运行良好.返回连接后,我可以将值设置为客户端标识符,并能够使用审计触发器从 syscontext 中检索它.

Code is working fine with the above configuration. Once connection is returned, I am able to set value to client identifier and able to retrieve it from syscontext with audit trigger.

但是我们有如下图所示的实际数据源配置:

But We have actual data source configuration as shown below:

 <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
       <property name="jndiName" value="jdbc/myDS"></property>

我无法更改此配置,因为它被多个应用程序使用,我必须遵循相同的操作.使用上述配置在部署时,我在创建数据源 bean 时遇到空指针异常.以下是我得到的例外:

I cannot change this configuration as it is used by multiple applications and I have to follow the same. With the above configuration While deploying I am getting null pointer exception while creating data source bean. Below is the exception that I am getting:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [beans.xml]: Invocation of init method failed; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
... 121 more
Caused by: java.lang.NullPointerException
at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:511)
at org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:141)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcServicesImpl.java:242)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:117)
at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:159)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1818)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1776)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1861)
at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:343)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:431)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:416)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)    

以前有没有人遵循过这种方法.如果有人可以提供有关如何进一步解决此错误的说明,将会很有帮助.有没有其他推荐的方法来遵循这种方法.提前致谢!

has anyone followed this approach before. It would be helpful if some one can provide instructions on how to proceed further to to resolve this error. is there any other recommended way to follow this approach. Thanks in advance!

更新::

我已尝试使用以下答案中指定的 ProxyInterface 类型.我能够解决空指针异常,但我在使用 cglib 代理时遇到错误.

I have tried with using ProxyInterface type as specified in below answer. I am able to resolve null pointer exception but I am getting errors with cglib proxies.

    DEBUG - Creating instance of bean 'sessionFactory'
DEBUG - Eagerly caching bean 'sessionFactory' to allow for resolving potential circular references
DEBUG - Returning cached instance of singleton bean 'dataSource'
DEBUG - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG - Returning cached instance of singleton bean 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0'
DEBUG - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG - Returning cached instance of singleton bean 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0'
DEBUG - Creating implicit proxy for bean 'dataSource' with 0 common interceptors and 2 specific interceptors
DEBUG - Creating CGLIB proxy: target source is SingletonTargetSource for target object [com.sun.proxy.$Proxy134@df1d109a]
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.equals(java.lang.Object)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final int com.sun.proxy.$Proxy134.hashCode()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.lang.String com.sun.proxy.$Proxy134.toString()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.isPreFiltered()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.io.PrintWriter com.sun.proxy.$Proxy134.getLogWriter() throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.isProxyTargetClass()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.isFrozen()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.setLogWriter(java.io.PrintWriter) throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.lang.Object com.sun.proxy.$Proxy134.unwrap(java.lang.Class) throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.removeAdvice(org.aopalliance.aop.Advice)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.removeAdvisor(org.springframework.aop.Advisor)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.setExposeProxy(boolean)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final int com.sun.proxy.$Proxy134.indexOf(org.springframework.aop.Advisor)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.lang.Class com.sun.proxy.$Proxy134.getTargetClass()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final org.springframework.aop.TargetSource com.sun.proxy.$Proxy134.getTargetSource()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final int com.sun.proxy.$Proxy134.getLoginTimeout() throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.addAdvisor(int,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.isExposeProxy()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.addAdvisor(org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.isWrapperFor(java.lang.Class) throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.sql.Connection com.sun.proxy.$Proxy134.getConnection() throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.addAdvice(int,org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.setLoginTimeout(int) throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.lang.Class[] com.sun.proxy.$Proxy134.getProxiedInterfaces()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.removeAdvisor(int) throws org.springframework.aop.framework.AopConfigException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.sql.Connection com.sun.proxy.$Proxy134.getConnection(java.lang.String,java.lang.String) throws java.sql.SQLException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final int com.sun.proxy.$Proxy134.indexOf(org.aopalliance.aop.Advice)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.setPreFiltered(boolean)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.replaceAdvisor(org.springframework.aop.Advisor,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
Unable to proxy method [public final org.springframework.aop.Advisor[] com.sun.proxy.$Proxy134.getAdvisors()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
Unable to proxy method [public final boolean com.sun.proxy.$Proxy134.isInterfaceProxied(java.lang.Class)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.addAdvice(org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.util.logging.Logger com.sun.proxy.$Proxy134.getParentLogger() throws java.sql.SQLFeatureNotSupportedException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final java.lang.String com.sun.proxy.$Proxy134.toProxyConfigString()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
WARN  - Unable to proxy method [public final void com.sun.proxy.$Proxy134.setTargetSource(org.springframework.aop.TargetSource)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
DEBUG - Retrieved dependent beans for bean '(inner bean)#ca01323a': [org.springframework.aop.aspectj.AspectJPointcutAdvisor#0]
Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@184af104: 
defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,
org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,
org.springframework.context.annotation.internalPersistenceAnnotationProcessor,transitionController,dataSource,
sessionFactory,transactionManager,persistenceExceptionTranslationPostProcessor,
org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,
org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor
org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,
pointCut,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor]; 
root of factory hierarchy
Retrieved dependent beans for bean '(inner bean)#c0432d95': [(inner bean)#ca01323a]
 ERROR - Context initialization failed
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [sessionfactory.xml]: Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Post-processing of the FactoryBean's object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy134]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy134
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:336)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1456)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    ... 129 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Post-processing of the FactoryBean's object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy134]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy134
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:167)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1514)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:252)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    ... 139 more
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy134]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy134
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:212)
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:494)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:379)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:339)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:421)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1698)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:164)
    ... 144 more
Caused by: java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy134
    at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
    at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
    at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
    at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
    at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
    at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:57)
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:202)
    ... 151 more

推荐答案

根据 WebSphere 文档,使用 org.springframework.jndi.JndiObjectFactoryBean 的数据源应该定义一个 proxyInterfacejavax.sql.DataSource.

Per WebSphere documentation, data sources using the org.springframework.jndi.JndiObjectFactoryBean should define a proxyInterface of javax.sql.DataSource.

例如:

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/myDS"/>
    <property name="lookupOnStartup" value="false"/>
    <property name="cache" value="true"/>
    <property name="proxyInterface" value="javax.sql.DataSource"/>
</bean>

来源:配置访问到 Spring 应用程序数据源

这篇关于在 WebSphere 服务器上使用 JNDI 的 Spring 自定义数据源连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆