set CLASSPATH=.;d:\jdk1.3.1_02\jre\lib\rt.jar;d:\j2sdkee1.3.1\lib\j2ee.jar; d:\bea\weblogic700\server\lib\weblogic.jar자바파일을 컴파일하기 위해서 J2SE의 rt.jar 파일과 J2EE의 j2ee.jar 파일이 필요하다. 이때 weblogic.jar가 설정되어 있지 않으면 실행시 에러가 발생한다. 왜냐하면 weblogic.jndi.WLInitialContextFactory를 찾을 수 없기 때문이다. CLASSPATH를 설정하고 나면, 이제 프로그램을 위한 모든 준비는 끝난 셈이다.
import javax.jms.Message; import javax.jms.MapMessage; import javax.jms.TopicConnectionFactory; import javax.jms.TopicConnection; import javax.jms.TopicSession; import javax.jms.Topic; import javax.jms.Session; import javax.jms.TopicSubscriber; import javax.jms.JMSException; import javax.naming.InitialContext; import javax.naming.Context; import java.util.Hashtable; public class MyReceiver implements javax.jms.MessageListener { public static void main(String[] args) throws Exception { new MyReceiver("my.jms.TopicFactory", "my.jms.topic"); while(true) { Thread.sleep(10000); } } public MyReceiver(String factoryName, String topicName) throws Exception { InitialContext jndiContext = getInitialContext(); TopicConnectionFactory factory = (TopicConnectionFactory)jndiContext.lookup(factoryName); Topic topic = (Topic) jndiContext.lookup(topicName); TopicConnection connect = factory.createTopicConnection(); TopicSession session = connect.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); TopicSubscriber subscriber = session.createSubscriber(topic); subscriber.setMessageListener(this); connect.start(); } public void onMessage(Message message) { try { MapMessage msg = (MapMessage)message; String text = (String)msg.getObject("name"); System.out.println(text); } catch (JMSException jmsE) { jmsE.printStackTrace(); } } public static InitialContext getInitialContext() throws Exception { Hashtable h = new Hashtable(); h.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); h.put(Context.PROVIDER_URL, "t3://localhost:7001"); return new InitialContext(h); } }이제 Producer를 살펴보자.
import javax.jms.Message; import javax.jms.MapMessage; import javax.jms.TopicConnectionFactory; import javax.jms.TopicConnection; import javax.jms.TopicSession; import javax.jms.Topic; import javax.jms.Session; import javax.jms.TopicPublisher; import javax.jms.JMSException; import javax.naming.InitialContext; import java.util.Hashtable; import javax.naming.Context; public class MySender { public static void main(String[] args) throws Exception { InitialContext jndiContext = getInitialContext(); TopicConnectionFactory factory = (TopicConnectionFactory)jndiContext.lookup("my.jms.TopicFactory"); Topic topic = (Topic) jndiContext.lookup("my.jms.topic"); TopicConnection connect = factory.createTopicConnection(); TopicSession session = connect.createTopicSession(true, 0); TopicPublisher publisher = session.createPublisher(topic); MapMessage msg = session.createMapMessage(); msg.setObject("name", new String("input")); publisher.publish(msg); connect.close(); } public static InitialContext getInitialContext() throws Exception { Hashtable h = new Hashtable(); h.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); h.put(Context.PROVIDER_URL, "t3://localhost:7001"); return new InitialContext(h); } }각 프로그램이 진행되는 순서는 InitialContext → TopicConnectionFactory → TopicConnection → TopicSession → TopicPublisher/Message 또는 TopicSubscriber이고 Topic은 InitialContext으로부터 lookup 메소드를 통하여 얻어온다. 이 때 InitialContext의 경우 얻어오는 코드는 각 제품에 따라 다르다. Consumer의 경우, Message가 받으면 onMessage 메소드가 자동 실행된다. 두 개의 프로그램은 약간 차이가 있지만 필자는 각 소스들이 자바에 대한 기본지식이 있는 개발자들에게 직관적으로 이해될 것이라고 믿는다. 또한 이러한 예제 제공 방식이 적합하다고 생각한다.
import javax.jms.Message; import javax.jms.MapMessage; import javax.ejb.MessageDrivenBean; import javax.jms.MessageListener; import javax.naming.NamingException; import javax.naming.Context; import javax.naming.InitialContext; import javax.ejb.EJBException; import javax.ejb.MessageDrivenContext; public class MyBean implements javax.ejb.MessageDrivenBean, javax.jms.MessageListener { MessageDrivenContext mdContext; Context jndiContext; public void setMessageDrivenContext(MessageDrivenContext mdc) { mdContext = mdc; try { jndiContext = new InitialContext(); } catch(NamingException ne) { throw new EJBException(ne); } } public void onMessage(Message msg) { try { MapMessage recMsg = (MapMessage)msg; String name = (String)recMsg.getObject("name"); } catch(Exception e) { throw new EJBException(e); } } public void ejbCreate() { } public void ejbRemove() { try { jndiContext.close(); mdContext = null; } catch(NamingException ne) { } } }Message-Driven Bean은 javax.ejb.MessageDrivenBean, javax.jms.MessageListener 인터페이스를 구현하여 작성한다. JMS Client에서 본 Consumer 예제와 onMessage 메소드를 제외하고는 다른 모습을 보이는 듯하다. 하지만 이러한 작업들은 모두 EJB 컨테이너에서 담당하고 있는 것이다. 이 Bean을 전개(Deploy)할 때 필요한 정보들, TopicConnectionFactory, Topic 또는 Queue가 모두 등록되어야 한다. 또한 메시지의 동시 처리를 위해서는 SessionPool도 설정해야 한다. Message-Driven Bean은 실제로 호출되어 생성되는 것이 아니기 때문에 ejbCreate 메소드는 사용되지 않는다. 그래서 항상 빈 메소드이다. OnMessage 메소드 안에서 다른 Enterprise Bean들을 호출할 수도 있고, 데이터베이스의 프로시저를 호출할 수도 있다. 또한 새로운 JMS 메세지를 보낼 수도 있다. 이것은 필요에 따라 작성하면 된다.
이전 글 : 웹 로그 통계 내기: AWStats
다음 글 : PyXML 개론
최신 콘텐츠