'JNDI'에 해당되는 글 1건

  1. 2008/11/04 JNDI DataSource Loading for TDD
Tomcat 등의 Servlet Container를 사용하여, 웹애플리케이션을 개발할 때, DataSource를 Servlet Container의 Context 에 JNDI Resource로 bind 하여 사용하는 경우가 많다.

test case를 실행하기 위해 JNDI remote provider 를 제공하는 application server (glassfish, jboss 등)를 사용할 수도 있으나, 이러한 것은 test의 원자성을 저해하기 때문에 test 환경 자체에서 JNDI resource를 생성할 수 있는 방법을 생각해 보았다.

Sun에서 제공하는 File System Service Provider를 이용하는 것이다. 사용법은 매우 간단하다. 단순히 naming context의 initail context factory 를 com.sun.jndi.fscontext.RefFSContextFactory 로 지정하기만 하면 된다.

다음은 간단히 만들어 본 class 이다. 이 class는 context xml 파일을 읽어서 JNDI resource를 loading해 주는 역할을 한다. test를 수행하기 전에 JNDILoader.init()을 실행 해주면 다른 작업 없이 test case를 실행시킬 수 있을 것이다.

package com.fguy.test;

import java.io.File;
import java.io.IOException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class JNDILoader {
	private static final Logger LOG = Logger.getLogger(JNDILoader.class);

	private static final boolean initialized = false;
	private static final String CONTEXT_XML = "WebContent/META-INF/context.xml";

	private JNDILoader() {

	}

	public static final void init() throws ParserConfigurationException,
			SAXException, IOException, DOMException, NamingException {

		if (!initialized) {
			Context context = getNamingContext();

			List resourceNames = new ArrayList();
			Map> references = new HashMap>();

			NodeList contextResourceNodeList = getContextResourceNodeList();
			for (int i = 0; i < contextResourceNodeList.getLength(); i++) {
				Node item = contextResourceNodeList.item(i);
				// print comment;
				if (LOG.isDebugEnabled()
						&& item.getNodeType() == Node.COMMENT_NODE
						&& item != null) {
					LOG.debug(item.getNodeValue());
				}

				// register to JNDI
				if ("resource".equalsIgnoreCase(item.getNodeName())
						&& "javax.sql.DataSource".equals(item.getAttributes()
								.getNamedItem("type").getNodeValue())) {
					NamedNodeMap attributes = item.getAttributes();
					String name = attributes.getNamedItem("name")
							.getNodeValue();
					Map reference = references.get(name);

					if (reference == null) {
						reference = new HashMap();
					}

					for (int j = 0; j < attributes.getLength(); j++) {
						String n = attributes.item(j).getNodeName();
						String v = attributes.item(j).getNodeValue();
						if (!"name".equals(n)) {
							reference.put(n, v);
						}
						LOG.debug(attributes.item(j));
					}

					resourceNames.add(name);
					references.put(name, reference);
				}

				if ("resourceparams".equalsIgnoreCase(item.getNodeName())) {
					NodeList parameters = item.getChildNodes();
					String name = item.getAttributes().getNamedItem("name")
							.getNodeValue();
					Map reference = references.get(name);

					if (reference == null) {
						reference = new HashMap();
					}

					for (int j = 0; j < parameters.getLength(); j++) {
						Node paramItem = parameters.item(j);
						if ("parameter".equalsIgnoreCase(paramItem
								.getNodeName())) {
							NodeList children = paramItem.getChildNodes();
							String n = null;
							String v = null;
							for (int k = 0; k < children.getLength(); k++) {
								Node child = children.item(k);
								if ("name"
										.equalsIgnoreCase(child.getNodeName())) {
									n = child.getNodeValue();
								} else if ("value".equalsIgnoreCase(child
										.getNodeName())) {
									v = child.getNodeValue();
								}
								LOG.debug(child);
							}
							reference.put(n, v);
						}
					}
					references.put(name, reference);
				}
			}
			for (String name : resourceNames) {
				Reference reference = new Reference("javax.sql.DataSource",
						"org.apache.commons.dbcp.BasicDataSourceFactory", null);
				Map referenceMap = references.get(name);

				for (String key : referenceMap.keySet()) {
					reference
							.add(new StringRefAddr(key, referenceMap.get(key)));
				}

				context.rebind("java:comp/env/".concat(name), reference);
			}
		}
	}

	private static final NodeList getContextResourceNodeList()
			throws ParserConfigurationException, SAXException, IOException {
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
				.newInstance();
		DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
		Document doc = docBuilder.parse(new File(CONTEXT_XML));
		return doc.getFirstChild().getChildNodes();
	}

	private static final Context getNamingContext() throws NamingException {
		System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
				"com.sun.jndi.fscontext.RefFSContextFactory");
		System.setProperty(Context.PROVIDER_URL, "file:///tmp");

		return new InitialContext();
	}
}

댓글을 달아 주세요