2011-11-30 2 views
2

현재 기존 웹 응용 프로그램을위한 새로운 모듈을 개발하려고합니다. LDAP 기능을 추가하려고하고 SimpleNamingContextBuilder가 LdapTemplate과 함께 작동하지 않는 컨텍스트를 등록 할 때 LDAP 컨텍스트를 초기화하는 데 문제가 있습니다.Spring의 SimpleNamingContextBuilder 및 LDAP

우리는 스프링 applicationContext.xml에 몇 가지 JNDI 조회가 있으므로 테스트 케이스를 실행하기 전에 테스트 케이스 생성자에서 SimpleNamingContextBuilder을 사용하여 모의 JNDI 리소스를 만들어야한다. 우리의 봄 application-context-test.xml에서

SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder(); 
builder.bind("someJNDIname",someObject); //e.g. for some datasource 
builder.activate(); 

우리는 다음 ldapConfiguration 한 다음 SimpleNamingContextBuilder으로

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:application-context-test.xml"}) 
public class TestClass { 
    public TestClass(){ 
     .. //init the SimpleNamingContextBuilder 
    } 

    @Autowired 
    private LdapTemplate template; 

    @Test 
    public void someTestcase(){ 
     ldapTemplate.search("", "(objectclass=user)" ,new LdapUserMapper()); 
    } 
} 

이미 다음 내가 할 간단한 InitialContext를 등록한다 : 우리는 함께 테스트 케이스를

<bean id="ldapContextSource" class="org.springframework.ldap.core.support.LdapContextSource"> 
    <property name="url" value="ldap://ourserver:389" /> 
    <property name="base" value="CN=Groups,CN=ourcompany,DC=com" /> 
    <property name="userDn" value="CN=binduser" /> 
    <property name="password" value="password" /> 
</bean> 

<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate"> 
    <constructor-arg ref="ldapContextSource" /> 
</bean> 

을 실행 오류 :

org.springframework.ldap.NotContextException: DirContext object is required.; nested exception is javax.naming.NotContextException: DirContext object is required. 
    at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:198) 
    at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:319) 
    at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:259) 
    at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:571) 
    at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:556) 
    at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:411) 
    at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:431) 
    at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:451) 
    at com.somecompany.TestClass.someTestcase(TestClass.java:30) 
     [...] 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 
Caused by: javax.naming.NotContextException: DirContext object is required. 
    at javax.naming.directory.InitialDirContext.castToDirContext(InitialDirContext.java:106) 
    at javax.naming.directory.InitialDirContext.getURLOrDefaultInitDirCtx(InitialDirContext.java:112) 
    at javax.naming.directory.InitialDirContext.search(InitialDirContext.java:245) 
    at org.springframework.ldap.core.LdapTemplate$4.executeSearch(LdapTemplate.java:253) 
    at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:293) 
    ... 35 more 

이 오류는 LDAP에 DirContext이 필요하다고 알려줍니다. 어떻게 SimpleNamingContextBuilder를 생성하고 그러한 DirContext을 사용할 수 있습니까?

SimpleNamingContextBuilder를 등록하지 않으면 LDAPTemplate을 만들면 작동합니다. 그러나 응용 프로그램의 다른 부분에서 JNDI 조회가 필요한 다른 문제가 발생할 것입니다.

답변

3

SimpleNamingContextBuilder를 가져 와서 DirContext의 인스턴스를 만들지 못했지만 사용자 지정 DirContextBuilder를 사용하여이 제한을 극복 할 수있었습니다.

조롱 된 SimpleNamingContext는 주로 바인딩 된 객체를 제공합니다.

InitialContext.doLookup(String name) 

방법 - 이러한 것들이 작동하고 예를 들어. LDAP DirContext 인스턴스는 "활성화 된"컨텍스트에 대한 검사를 생략하기 때문에 activate()를 적용하기 위해 코드를 부트 스트랩하므로 아무런 문제가 발생하지 않습니다. 적어도 주어진 JNDI + LDAP 테스트 사례에는 해당되지 않습니다. 이 검사를 누락

코드는 "java.naming.factory.initial을"환경 키를 찾습니다과 환경이 비어있는 경우가 조롱받을 (이 InitialContext.doLookup (문자열 이름)의 경우입니다) 바인드 된 객체를 가진 SimpleNamingContext. 당신이 LdapTemplate를 사용하는 경우

환경 비어와 키 "java.naming.factory.initial을"로 설정되어 "com.sun.jndi.ldap.LdapCtxFactory"나에 있습니다 비슷한 일이 아니다 최소의 (아마) DirContext.

이 경우 createInitialContextFactory 호출에서 작업중인 DirContext 인스턴스가 반환되고 LdapTemplate 조회가 성공적으로 수행됩니다.

그러니 그냥 클래스 DirContextBuilder 생성 - 같은 - SimpleNamingContextBuilder의 코드를 가지고 :

public class DirContextBuilder implements InitialContextFactoryBuilder { 

... 

public InitialContextFactory createInitialContextFactory(Hashtable<?,?> environment) { 
    if (environment != null) { 
... 
} 

이 활성화 에 대한 검사 == null이을 생략하고 당신이 당신의 바운드 JNDI 객체를 테스트하고있는 준비를 LdapTemplate 작업.

+0

이렇게하면 혼합 문제가 해결되지 않습니다. 동일한 컨텍스트에서 데이터베이스에 대한 JNDI 데이터 소스를 초기화하려고합니다. –

+0

같은 문맥에서 양쪽 모두를 필요로하는 경우는, 커스텀의 DirContextBuilder에서도 가능합니다. DirContext의 독자적인 구현을 작성하거나, 예를 들어, 다음과 같이 사용합니다. JBoss one (org.jnp.interfaces.NamingContextFactory). –

+0

두 문맥이 같은 문맥에서 필요합니다.이 작업을 정확하게 수행하는 방법을 보여줄 수 있습니까? 정말 고맙겠 어! 감사합니다. –

1

나는 똑같은 문제에 직면했다. 그러나 아래 트릭을 통해이를 극복하십시오.

@BeforeClass 
public static void setUp(){ 
    OracleDataSource ods = null; 
    try { 
     ods= new OracleDataSource(); 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    } 
    ods.setURL("jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=....; 
    ods.setUser(..); 
    ods.setPassword(..);   

    SimpleNamingContextBuilder builder = null; 
    try { 
     builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder(); 
     builder.bind("some/name", ods); 
    } catch (NamingException e) { 
     e.printStackTrace(); 
    } 
} 

@Before 
public void beforeTest(){ 
     SimpleNamingContextBuilder.getCurrentContextBuilder().deactivate(); 
} 

@Test 
public void yourTest(){ 
    ..... 
} 

이렇게하면 일부/name으로 데이터베이스를 바인드하고 ldap에 올바르게 연결할 수 있습니다.

+0

'@ContextConfiguration'이 jdbc 데이터 소스에 jndi를 요구하는 스프링 컨텍스트를 구성하기 전에'@ BeforeClass'를 사용하여 jndi를 등록합니다. 그러나 그것을 작동시키기 위해서는'builder.activate()'를 추가해야합니다. 이 트릭을 주셔서 감사합니다 +1':)' – albciff