JNDI initializing for local file system
JNDI는 Java Naming and Directory Interface 랜다. LDAP을 통해서 객체에 접근하는데 주로 쓰이는 것 같은데… 뭐.. 정확히 어디에 많이 활용되는 나도 잘 모르겠다.
단순히 Hibernate tool로 generate된 dao(Data Access Object) 코드에서 JNDI가 사용되기 때문에 generate된 코드를 수정없이 쓰려면 JNDI 환경을 먼저 설정해 주어야 했다.
JNDI 기본 패키지는 JDK 1.2부터 기본으로 포함되었다. 문제는 context 라이브러리다. 자신이 사용하고자 하는 Directory에 따라 라이브러리를 classpath에 넣어주어야 한다. 라이브러리는 다음 링크에서 다운 받을 수 있다.
http://java.sun.com/products/jndi/downloads/index.html
현재는 1.2.1의 경우 license agreement를 하고 들어가면 여러가지 Directory Service Provider에 해당하는 라이브러리가 나열된다. 이중에서 local file system을 JNDI를 통해 접근하려면 File System Service Provider를 지원하는 fscontext*.jar 가 있어야 한다.
라이브러리를 다운받고 classpath에 넣은 후에는 jndi.properties 파일을 작성해준다. jndi.properties 파일의 위치는 classpath 가장 상위 디렉토리 밑에 위치해야 한다. 예를 들어 classpath가 C:\classpath\ 라면 C:\classpath\jndi.properties 파일이 있어야 한다. (classpath가 여러개고 복수개의 jndi.properties 파일이 있다면…? 어떻게 되는지 나도 모르겠다. 그냥 여기에서 그렇게 하라고 나와 있으니깐.. -_-)
jndi.properties에는 다음과 같이 설정한다.
# context factory class java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory # class 가 들어있는 디렉토리 java.naming.provider.url=file:///C:/workspace/project/bin # 요건 뭔지 모르겠네.. com.sun.jndi.ldap.netscape.schemaBugs=true
그리고 Java 코드에서 다음과 같이 초기화와 동시에 인스턴스를 저장한다.
InitialContext ctx = new InitialContext();
try{
Object fac = ctx.lookup("SessionFactory");
if(fac == null){
ctx.rebind("SessionFactory", sessionFactory);
}
}catch(NamingException ne){
ctx.bind("SessionFactory", sessionFactory);
}
dao = new DailySearchByTypeHome();
rebind를 하는 이유는 잘은 모르겠지만 아마도 local file system이 서버가 아니기 때문에 process가 종료되면 저장된 인스턴스가 없어지기 때문에 JNDI에 SessionFactory란 이름이 존재하여도 인스턴스가 없어서 null로 반환되기 때문이다. 그래서 인스턴스를 다시 재등록하는 것이다.
저장된 인스턴스는 다음과 같이 꺼내쓸 수 있다.
try {
return (SessionFactory) new InitialContext().lookup("SessionFactory");
}
catch (Exception e) {
log.error("Could not locate SessionFactory in JNDI", e);
throw new IllegalStateException("Could not locate SessionFactory in JNDI");
}


