Spring自定义DataSource与WebSphere服务器上的JNDI连接

时间:2016-05-25 19:11:29

标签: java spring hibernate websphere aop

我有与发布中指定的相同要求将用户ID作为客户端标识符传递以用于审核目的。 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

中提到的方法相同。

以下是我所拥有的一段代码:

@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 ,如下所示。

<aop:aspectj-autoproxy />

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

我正在 websphere服务器中部署我的网络服务。一切正常如果我使用 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中检索它。

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

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

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

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)    
之前有人跟着这个方法。如果某人可以提供有关如何进一步解决此错误的说明,将会很有帮助。 是否有任何其他推荐的方法来遵循这种方法。提前谢谢!

UPDATE ::

我尝试过使用ProxyInterface类型,如下面的答案所示。我能够解决空指针异常,但我收到了cglib代理错误。

    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

1 个答案:

答案 0 :(得分:1)

根据WebSphere文档,使用org.springframework.jndi.JndiObjectFactoryBean的数据源应定义proxyInterface 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>

来源:Configuring access to a Spring application data source