I am trying to combining a TransactionAwareContextSourceProxy with a PoolingContextSource. My tests work fine when using only a TransactionAwareContextSourceProxy or a PoolingContextSource. However, when combining the two, I get the following exception:
14:38:21.961| WARN DirContext 'javax.naming.ldap.InitialLdapContext@3a47c130' failed validation with an exception.[DefaultDirContextValidator.validateDirContext(176)]
javax.naming.OperationNotSupportedException: [LDAP: error code 53 - Unwilling To Perform]; remaining name ''
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3114)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2987)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2794)
at com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1826)
at com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1749)
at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirContext.java:368)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:338)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:321)
at javax.naming.directory.InitialDirContext.search(InitialDirContext.java:248)
at org.springframework.ldap.pool.validation.DefaultDirContextValidator.validateDirContext(DefaultDirContextValidator.java:165)
at org.springframework.ldap.pool.factory.DirContextPoolableObjectFactory.validateObject(DirContextPoolableObjectFactory.java:169)
at org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:837)
at org.springframework.ldap.pool.factory.PoolingContextSource.getContext(PoolingContextSource.java:422)
at org.springframework.ldap.pool.factory.PoolingContextSource.getReadWriteContext(PoolingContextSource.java:408)
and
org.springframework.transaction.CannotCreateTransactionException: Could not create DirContext instance for transaction; nested exception is org.springframework.dao.DataAccessResourceFailureException: Failed to borrow DirContext from pool.; nested exception is java.util.NoSuchElementException: Could not create a validated object
at org.springframework.transaction.compensating.support.AbstractCompensatingTransactionManagerDelegate.doBegin(AbstractCompensatingTransactionManagerDelegate.java:91)
at org.springframework.ldap.transaction.compensating.manager.ContextSourceAndHibernateTransactionManager.doBegin(ContextSourceAndHibernateTransactionManager.java:80)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.startTransaction(TransactionalTestExecutionListener.java:507)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.startNewTransaction(TransactionalTestExecutionListener.java:269)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:162)
at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:374)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
at org.springframework.test.context.ju开发者_如何学运维nit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.dao.DataAccessResourceFailureException: Failed to borrow DirContext from pool.; nested exception is java.util.NoSuchElementException: Could not create a validated object
at org.springframework.ldap.pool.factory.PoolingContextSource.getContext(PoolingContextSource.java:425)
at org.springframework.ldap.pool.factory.PoolingContextSource.getReadWriteContext(PoolingContextSource.java:408)
at org.springframework.ldap.transaction.compensating.manager.ContextSourceTransactionManagerDelegate.getNewHolder(ContextSourceTransactionManagerDelegate.java:86)
at org.springframework.transaction.compensating.support.AbstractCompensatingTransactionManagerDelegate.doBegin(AbstractCompensatingTransactionManagerDelegate.java:84)
... 26 more
Caused by: java.util.NoSuchElementException: Could not create a validated object
at org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:840)
at org.springframework.ldap.pool.factory.PoolingContextSource.getContext(PoolingContextSource.java:422)
... 29 more
This is my Spring configuration:
<bean id="contextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="${ldap.url}" />
<property name="base" value="${ldap.base.main}" />
<property name="userDn" value="${ldap.userDn}" />
<property name="password" value="${ldap.password}" />
<!-- Do not use standard pooling, but pooling support from Spring. -->
<property name="pooled" value="false" />
</bean>
<bean id="transactionAwareContextSource" class="org.springframework.ldap.transaction.compensating.manager.TransactionAwareContextSourceProxy">
<constructor-arg ref="poolingContextSource" />
</bean>
<bean id="poolingContextSource" class="org.springframework.ldap.pool.factory.PoolingContextSource">
<property name="contextSource" ref="contextSourceTarget" />
<property name="dirContextValidator" ref="dirContextValidator" />
<property name="testOnBorrow" value="${ldap.pooling.testOnBorrow}" />
<property name="testWhileIdle" value="${ldap.pooling.testWhileIdle}" />
<property name="maxActive" value="${ldap.pooling.maxActive}" />
<property name="maxTotal" value="${ldap.pooling.maxTotal}" />
<property name="maxIdle" value="${ldap.pooling.maxIdle}" />
<property name="minIdle" value="${ldap.pooling.minIdle}" />
<property name="maxWait" value="${ldap.pooling.maxWaiting}" />
</bean>
<bean id="dirContextValidator" class="org.springframework.ldap.pool.validation.DefaultDirContextValidator">
<property name="base" value="${ldap.validationBase.main}" />
</bean>
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<constructor-arg ref="transactionAwareContextSource" />
</bean>
<bean id="transactionManager"
class="org.springframework.ldap.transaction.compensating.manager.ContextSourceAndHibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<property name="contextSource" ref="transactionAwareContextSource" />
</bean>
Has anybody gotten this to work successfully?
If not, do I really need ldap pooling or are ldap connections should cheap that it is not really important?
This works with Spring LDAP 1.3.1 with the following configuration:
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<property name="contextSource" ref="contextSource"/>
</bean>
<bean id="contextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="${ldap.url}"/>
<property name="userDn" value="${ldap.userDn}"/>
<property name="password" value="${ldap.password}"/>
<property name="pooled" value="false"/>
</bean>
<bean id="pooledContextSource" class="org.springframework.ldap.pool.factory.PoolingContextSource">
<property name="contextSource" ref="contextSourceTarget"/>
<property name="dirContextValidator" ref="dirContextValidator"/>
<property name="testOnBorrow" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="minIdle" value="${ldap.minIdle}"/>
<property name="maxIdle" value="${ldap.maxIdle}"/>
<property name="maxActive" value="${ldap.maxActive}"/>
<property name="maxTotal" value="${ldap.maxTotal}"/>
<property name="maxWait" value="${ldap.maxWait}"/>
</bean>
<bean id="dirContextValidator"
class="org.springframework.ldap.pool.validation.DefaultDirContextValidator"/>
<bean id="contextSource"
class="org.springframework.ldap.transaction.compensating.manager.TransactionAwareContextSourceProxy">
<constructor-arg ref="pooledContextSource"/>
</bean>
精彩评论