Site Search :
Standard Enterprise XML Methodology Pattern Setting Tunning Other
Article Contributors
GuestBook
Javapattern Maven
XSourceGen Dev
JetSpeed Test
JLook Image
jLook Family Site


WebLogic WLSPool Size변경 application
 
웹로직 8.1의 경우 config xml파일의 수정이 불가능하기 때문에 해당 jar파일의 설정값중 ejb pooling size를 변경할 수 있는 utility클래스를 소개하도록 한다. ( 2003/12/10 ) 105
Written by specular - 전홍성,최지웅
1 of 1
 

여러분들 날씨가 많이 추워졌죠? 날씨가 추워서인지 계속 잠만오고..아무래도 제가 겨울잠을 준비하는
것 같습니다. 스키장도 좀 다니고 해야 하는데 주말에 원 시간이 있어야 돌아다니든지 하죠.. ^^
애인이 없어서 그런지 옆구리도 허전하고 그렇다고 시간이 나는것도 아니고 말이죠..
이번 아티클소스는 쫀님이 작성을 하셨고 글은 제가 쓰고 있습니다.. 요즘 많이 할일이 없으신가 봅니다.
다시 엄청난 공부로 내공을 키우시는걸 보면 말이죠.^^

딴소리지만 아래쪽에 있는 jNetServer를 소스오픈시 분석하여 응용하게 되면 여러분들도 아주 간단한 
EJB Container정도는 뚝딱 만드시지 않을까 생각합니다. 아닌가요? ㅎㅎ

자. 아티클 들어갑니다.

▶ 작성동기

어느날 쫀이 열심히 프로젝트를 하여 오픈 2달전에 이미 모든 요구사항을 구현한 후 테스트중이었습니다.
그런데 하루는 계속 ejb가 작동에러를 발생을 시키더라 이겁니다. 
EAI프로젝트에서 BEA WLI를 이용하여 work flow를 작성하고 해당 업무를 자동으로 EJB로 바꿔주는데
문제는 WLI에서 EJB에 대한 pooling size가 아주 적은 수로 설정이 되어지더란 것인데 만약에
해당 애플리케이션을 바꾸려면 ear or jar압축을 푼후 META정보를 수정을 하고 다시 압축한 후 
deploy를 해야 한다는 것이었는데 EJB가 많아지면 많이질수록 하게 되는 노가다는 이루 말할수
없겠지요.

▶ 생각꺼리

자~ 실제 해결방법을 보여주기 전에 제가 항상 여러분들에게 질문을 하죠? 어떻게 하면 위의 문제점을
처리할 수 있을 것인지 말이죠..
남의 것을 덥석덥석 받아먹을 때는 이미 지나야 하지 않나요? 여기의 아티클들을 보시고 한다면
최소한 그정도의 예의(?)는 갖추셔야 하지 않을까요? 
스스로 문제를 찾아 해결하려는 노력~ copy-paste에 의존하지 않는 방법을 터득해야죠. 발전해야하니까요.

생각하셨나요? 흠~ 이를 어떻게 한다? jar파일의 내용을 처리해야 하는데.. 그리고 xml을 처리해야 하겠는데?
문제는 ejb-jar, weblogic-ejb-jar.xml의 구문조차도 모른다면 이 글을 읽는 것을 포기해야 할지도 몰라요.ㅡ.ㅡ
자바의 맛이 프로그램을 Visual한 MS계열의 툴이 아닌 text로 만들어냈다는것이었는데 요즘 각종 IDE들이 
그러한 것(애플리케이션 코딩)들을 클릭클릭으로 해주니 이제 뭐 비슷하게 되긴 했습니다.
지금 플젝을 하고 있는데 한 개발자가 기존에 했던 프로젝트의 코딩패턴을 제가 보기위해서 EJB코드를
열어 하나만 실행해보라고 했는데 WSAD를 실행시키더란 말이죠..
이거 원~ 쩝... ^^ 툴도 좋지만 기본적인 것들을 먼저 본후에 하면 더 좋겠죠?

▶ 구현방법

이제 구현에 들어갑니다. 
우선 우리가 deploy를 시켰던 파일은 jar나 ear의 형태를 취하게 될것이구요. 

1. 우선 해당 압축파일을 찾는다
2. 압축된 파일중 ejb에 관련된 META-INF의 정보를 찾아 해당 xml파일을 파싱하도록 한다.
3. 파싱된 문서의 pool size를 입력받은 내용으로 치환한 후 다시 저장한다.
4. 다시 해당 파일을 압축한다.

위의 정도로 구현을 하면 되겠네요.
기본적인 standard API의 사용은 필수이겠구요.

JDK1.3 이하의 버젼을 쓰시는 분들은 XML파싱에 관련된 클래스를 다운받아 클래스 패스에 추가하신 후 
컴파일 및 실행하셔야 합니다.


▶ 구현체



package jlook.weblogic.util;

import java.io.*;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;

import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.xml.sax.helpers.*;

/**
 *	특정 디렉토리 밑의 모든 EJB jar 파일을 검색하여 jar 파일 내 
 *	WebLogic Deployment Descriptor[weblogic-ejb-jar.xml] 파일을 DOM으로 로딩하여 
 *	initial-beans-in-free-pool, max-beans-in-free-pool의 size를 command line으로
 *	입력한 값으로 변경저장하는 Application이다.
* usage : java WLSPoolModifier <target-directory> <min-size> <max-size>
* * @since 1.0 * @author Jeon HongSeong(hsjeon70@dreamwiz.com) */ public class WLSPoolModifier implements Runnable { /** Target Directory */ private static String PATH; /** inital size */ private static int minSize; /** maximum size */ private static int maxSize; /** WebLogic Deployment Descriptor file 경로 */ private static final String DD_ENTRY = "META-INF/weblogic-ejb-jar.xml"; /** root tag name */ private static final String WEBLOGIC_ENTERPRISE_BEAN = "weblogic-enterprise-bean"; /** stateless session descriptor tag name */ private static final String STATELESS_SESSION_DESCRIPTOR = "stateless-session-descriptor"; /** pool tag name */ private static final String POOL = "pool"; /** maximum size tag name */ private static final String MAX_BEANS_IN_FREE_POOL = "max-beans-in-free-pool"; /** initial size tag name */ private static final String INITIAL_BEANS_IN_FREE_POOL = "initial-beans-in-free-pool"; /** current time mill */ private static long systime = System.currentTimeMillis(); /** DOCTYPE의 SYSTEM ID */ private static String SYSTEM_ID; /** DOCTYPE의 PUBLIC ID */ private static String PUBLIC_ID; /** weblogic.doctype file loading 여부 */ private static boolean load = false; /** * static initializer
* weblogic.doctype file을 classpath에서 찾아 로딩한다. */ static { try { ClassLoader loader = WLSPoolModifier.class.getClassLoader(); InputStream in = loader.getResourceAsStream("weblogic.doctype"); if(in!=null) { Properties p = new Properties(); p.load(in); p.list(System.out); SYSTEM_ID=p.getProperty("systemId"); PUBLIC_ID=p.getProperty("publicId"); load = true; } } catch(Exception e) { e.printStackTrace(); } } /** * application main method
* command line 인수를 validate하고, thread를 start한다.
* * @param args path, min-size, max-size */ public static void main(String args[]) throws Exception { if(args.length!=3) { System.out.println("java WLSPoolModifier <path> <min-size> <max-size>"); return; } PATH = args[0]; try { minSize = Integer.parseInt(args[1]); } catch(Exception e) { minSize = 20; } try { maxSize = Integer.parseInt(args[2]); } catch(Exception e) { maxSize = 20; } System.out.println("@ target directory>> "+PATH); System.out.println("@ new minimum size>> "+minSize); System.out.println("@ new maximum size>> "+maxSize); Thread t = new Thread(new WLSPoolModifier()); t.start(); } /** * Target directory내 jar파일을 검색하기 위해 searchJarFile() method을 호출한다.
* */ public void run() { File dir = new File(PATH); if(!dir.exists()) { System.out.println("The path does not exists. - "+PATH); return; } try { searchJarFile(dir); } catch(Exception e) { e.printStackTrace(); } } /** * dir 내 모든 jar 파일을 찾아 jar 파일에 대해 findEntry() 메서드를 실행하고, * weblogic-jar-ejb.xml 파일이 존재할 경우 convert(), makeJar() 메서드를 실행한다. * */ private void searchJarFile(File dir) throws Exception { File[] lists = dir.listFiles(); for(int i=0;i> "+lists[i]); Document root = findEntry(lists[i]); if(root!=null) { byte[] dd = convert(root); makeJar(lists[i], dd); } } } } } /** * 파라미터의 Document object를 XSLT를 이용해 byte[] 로 convert한다. * * @param root weblogic-jar-ejb.xml에 대한 Document object * @return Document에 대한 byte[] */ private byte[] convert(Document root) { try { TransformerFactory factory = TransformerFactory.newInstance(); Transformer tf = factory.newTransformer(); DocumentType doctype = root.getDoctype(); String publicId=null; String systemId=null; if(doctype != null) { publicId = doctype.getPublicId(); systemId = doctype.getSystemId(); } else { if(load) { systemId = SYSTEM_ID; publicId = PUBLIC_ID; } else { systemId = "http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd"; publicId = "-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN"; } } System.out.println("\t- publicId>> "+publicId); System.out.println("\t- systemId>> "+systemId); tf.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, systemId); tf.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, publicId); DOMSource source = new DOMSource(root); ByteArrayOutputStream bos = new ByteArrayOutputStream(); StreamResult result = new StreamResult(bos); tf.transform(source,result); return bos.toByteArray(); } catch(Exception e) { e.printStackTrace(); return null; } } /** * 해당 jar 파일에 weblogic deployment descriptor를 치환하는 메서드
* orginal jar 파일은 backup을 남긴다.[~.jar.org]
* * @param oldJar ejb jar file * @param dd weblogic-ejb-jar.xml에 대한 byte array */ private void makeJar(File oldJar, byte[] dd) throws Exception { JarFile jarFile = null; File newJar = new File(oldJar.getParentFile(), "_"+oldJar.getName()); FileOutputStream fo = null; JarOutputStream jos = null; System.out.println("\t- make the "+newJar); try { jarFile = new JarFile(oldJar); fo = new FileOutputStream(newJar); jos = new JarOutputStream(fo); Enumeration en = jarFile.entries(); while(en.hasMoreElements()) { JarEntry entry = (JarEntry)en.nextElement(); InputStream in = jarFile.getInputStream(entry); byte[] buff = readData((int)entry.getSize(), in); in.close(); JarEntry newEntry = new JarEntry(entry.getName()); entry.setMethod(entry.DEFLATED); entry.setSize(buff.length); entry.setTime(systime); CRC32 crc322 = new CRC32(); if(entry.getName().equals(DD_ENTRY)) { crc322.update(dd); } else { crc322.update(buff); } entry.setCrc(crc322.getValue()); jos.putNextEntry(newEntry); if(entry.getName().equals(DD_ENTRY)) { jos.write(dd,0,dd.length); } else { jos.write(buff,0,buff.length); } jos.flush(); jos.closeEntry(); } } catch(Exception e) { e.printStackTrace(); throw e; } finally { try { if(jos!=null) jos.finish(); } catch(Exception e) {} try { if(jos!=null) jos.close(); } catch(Exception e) {} try { if(fo!=null) fo.close(); } catch(Exception e) {} try { if(jarFile!=null) jarFile.close(); } catch(Exception e) {} } if(jos!=null) { System.out.println("\t- rename the "+newJar+" to "+oldJar); File backup = new File(oldJar.getParentFile(), oldJar.getName()+".org"); if(!backup.exists()) { boolean result = oldJar.renameTo(backup); if(!result) { System.out.println("cannot rename to "+backup); } } else { if(!oldJar.delete()) System.out.println("cannot delete "+oldJar); } if(!newJar.renameTo(oldJar)) System.out.println("cannot rename to "+oldJar); } } /** * ejb jar 파일에서 weblogic deployment descriptor를 찾아 DOM Document object로 * 반환하는 메서드
* * @param file ejb jar file * @return weblogic-ejb-jar.xml에 대한 Document object */ private Document findEntry(File file) { JarFile jarFile = null; try { jarFile = new JarFile(file); Enumeration en = jarFile.entries(); while(en.hasMoreElements()) { JarEntry entry = (JarEntry)en.nextElement(); if(entry.getName().equals(DD_ENTRY)) { System.out.println("\t- find the entry - "+entry.getName()); InputStream in = jarFile.getInputStream(entry); Document root = loadDocument(in); in.close(); return root; } } } catch(Exception e) { System.out.println(">> "+e.toString()); e.printStackTrace(); } finally { try { if(jarFile!=null) jarFile.close(); } catch(Exception e) {} } return null; } /** * parameter의 InputStream으로 부터 들어오는 xml data를 DOM Document object를 생성한다.
* * @param in weblogic-ejb-jar.xml에 해당하는 stream * @return weblogic-ejb-jar.xml에 대한 DOM Document object */ private Document loadDocument(InputStream in) throws Exception { System.out.println("\t- load the Document "); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setErrorHandler(new DefaultHandler()); Document doc = builder.parse(in); doc.normalize(); Element root = doc.getDocumentElement(); Node node1 = findNode(root, WEBLOGIC_ENTERPRISE_BEAN); if(node1 == null) { System.out.println("cannot find the node. - "+WEBLOGIC_ENTERPRISE_BEAN); node1 = doc.createElement(WEBLOGIC_ENTERPRISE_BEAN); root.appendChild(node1); } Node node2 = findNode(node1, STATELESS_SESSION_DESCRIPTOR); if(node2 == null) { System.out.println("cannot find the node. - "+STATELESS_SESSION_DESCRIPTOR); node2 = doc.createElement(STATELESS_SESSION_DESCRIPTOR); node1.appendChild(node2); } Node node3 = findNode(node2, POOL); if(node3 == null) { System.out.println("cannot find the node. - "+POOL); node3 = doc.createElement(POOL); node2.appendChild(node3); } Node node4 = findNode(node3, MAX_BEANS_IN_FREE_POOL); if(node4 == null) { System.out.println("cannot find the node. - "+MAX_BEANS_IN_FREE_POOL); node4 = doc.createElement(MAX_BEANS_IN_FREE_POOL); Text txt = doc.createTextNode(""); node4.appendChild(txt); node3.appendChild(node4); } Node node5 = findNode(node3, INITIAL_BEANS_IN_FREE_POOL); if(node5 == null) { System.out.println("cannot find the node. - "+INITIAL_BEANS_IN_FREE_POOL); node5 = doc.createElement(INITIAL_BEANS_IN_FREE_POOL); Text txt = doc.createTextNode(""); node5.appendChild(txt); node3.appendChild(node5); } setNodeValue(node5, minSize); setNodeValue(node4, maxSize); System.out.println("\t- change min and max size ["+minSize+", "+maxSize+"]"); return doc; } /** * node에 대한 child tag를 찾아 반환하는 메서드
* * @param node 검색 기준 node * @param childNodeName 검색할 child node name * @return child node */ private Node findNode(Node node, String childNodeName) { NodeList lst = node.getChildNodes(); for(int i=0;i * * @param node Node * @param value 변환할 값 */ private void setNodeValue(Node node, int value) { NodeList lst = node.getChildNodes(); Node tmp=null; for(int i=0;i> "+tmp.getNodeValue()); tmp.setNodeValue(value+""); } } /** * InputStream으로 부터 해당 size 만큼의 byte를 읽어 반환하는 메서드
* * @param size 읽을 데이터 size * @param in InputStream * @return 읽은 결과 byte array data */ private byte[] readData(int size, InputStream in) { byte[] buff = new byte[size]; try { int totalSize=0; do { int len = in.read(buff,totalSize,size-totalSize); if(len==-1) { break; } totalSize+=len; } while(totalSize<size); return buff; } catch(Exception e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); } } }
위의 파일내용에 대한 제약사항을 알려드립니다. OS : Platform independent App Server : WebLogic 6.1 or later JDK : Sun JDK1.4 or Other 간단하게 아티클을 작성했습니다. XML에 관련해서나 압축엔트리에 관련해서 사용된 코드도 유심히 살펴보시는 것이 좋을 것 같습니다.
 
1
References
 
Copyright ⓒ 2003 www.javapattern.info & www.jlook.com, an jLOOK co.,LTD