Problem explained일반적으로 구버젼(5.0.x) MySQ JDBC에서 Column Name Alias를 사용할 경우 아래와 같이 오류가 발생한다.SELECT DISTINCT c.name AS `Client Name`, ...하지만, Alias를 사용하지 않으면 정상작동한다.SELECT DISTINCT c.name, ...The Solution해결책은 JDBC URL을 수정하면 간단히 해결된다.jdbc.url=jdbc:mysql://localhost:3306/miso?useOldAliasMetadataBehavior=true JDBC Manual에 나와 있다. 역시 Manual을 잘 봐야 한다.
Download Link - https://arare.googlecode.com/files/arare.zip 1. Tab기능 개선 - 다중 Tab사용에 따른 다중결과 방식으로 개선 2. Tree기능 개선 - Tree Icon기능 추가 3. Object Find기능 추가 - . 입력 시 하위 Column선택메뉴 활성화 4. Table Information화면 추가 5. Exception dialog개선 6. DB2, MySQL서버 접속 및 사용기능 개선 7. MS-SQL JDBC 드라이버 교체 8. Look and Feel기능 안정화 및 불안정 Lib제거 9. Connection Test기능 추가 10. 기타 안정화 Cross DBMS Query Executer인 Arare가 국제인증(?)을 획득하였습니다. ^^ Arare SQL Executer, one of your products, has been added to Softpedia's The description text was created by our editors, using sources such as text
To assure our visitors that Arare SQL Executer is clean, we have granted it More information about your product's certification and the award is Feel free to link to us using the URLs above. If you choose to link to the
꽤나 오랫동안 끄적거려오던 작업을 baseline을 그으려 한다.일단, 시작은 Oracle작업 시 사용하던 Golden의 기능을 Tibero나 MySql 등의 다양한 DB에서 사용하고자 만들게 되었다. JDBC라는 뛰어난(?) 개념때문에 쉽게 접근가능하리라 생각했으나, 천성이 게을러서 빠른 진도를 못 나갔던 것이 사실이다. 프로젝트는 Google Code에서 진행하고 있었고, 당연히, Member는 혼자이다..ㅋㅋ 100% pure java이며, pure Swing이다. Swing을 다루기 좋은 Netbeans로 작업하였다. 지금까지 작업한 기준으로 Binary와 Source를 Open하고자 한다. 물론, GNU 라이선스를 따름은 당연하다. code사이트는 http://code.google.com/p/arare/ 이다. member로 참여코자 하시는 분 있으시면 신청해 주시길 바란다. 위의 download 링크에서 다운받으신 zip파일을 여시고 첨부된 bat파일을 실행하시면 된다. 많은 사용과 Feedback부탁드린다.
public int[] doSort (int[] aArr) {
int i, j, cipher, num, max; int [][] bucket = new int [10][aArr.length]; int [] count = new int [10]; max = 0; for(i=0;i<aArr.length;i++){ if(max<aArr[i]) max = aArr[i]; } cipher = 1; while(cipher<=max){ for(i=0;i<=9;i++) count[i] = 0; for(i=0;i<aArr.length;i++){ num = (aArr[i]/cipher)%10; bucket[num][count[num]++] = aArr[i]; } num = 0; for(i=0;i<=9;i++){ for(j=0;j<count[i];j++){ aArr[num++] = bucket[i][j]; } } cipher *= 10; } return aArr; } public int[] doSort(int[] aList, int aLow, int aHigh){ int pivot = aList[(lo + hi) / 2]; doSort(aList, aLow, lo - 1);
public int[] doSort(int[] aList){
int h,i,j,k,temp,n = 0; n = aList.length; for(h=n/2;h>0;h=h/2){ for(i=0;i<h;i++){ for(j=i+h;j<n;j=j+h){ temp = aList[j]; for(k=j;k>h-1&&aList[k-h]>temp;k-=h) aList[k] = aList[k-h]; aList[k] = temp; } } } return aList; }
public int[] doSort(int[] aList){
int i, j, temp; for(i=0;i<aList.length-1;i++){ for(j=1;j<aList.length-i;j++){ if(aList[j-1] > aList[j]){ temp = aList[j-1]; aList[j-1] = aList[j]; aList[j] = temp; } } } return aList; }
public int[] doSort(int[] aList){
int k,j,i,temp = 0; for(i=0;i<aList.length-1;i++){ k = i; for(j=i+1;j<aList.length;j++){ if(aList[k]>aList[j]){ k=j; } } temp = aList[i]; aList[i] = aList[k]; aList[k] = temp; } return aList; }
public int[] doSort(int[] aList){
int k,j = 0; for(int i=1;i<aList.length;i++){ k = aList[i]; for(j=i-1;j>=0 && k < aList[j];j--) aList[j+1] = aList[j]; aList[j+1] = k; } return aList; }
회사를 옮기고 맡은 업무가 TA&SA인데...그 중 특히나 J2EE appl에 대한 대처다....
이글 저글 읽다가...발견한 글인데 .... 최고의 글이다.......감동감동감동 !!!!! 여기 오는 독자들은 꼭 읽어보길...권한다...강추한다. http://cafe.naver.com/ArticleRead.nhn?clubid=12263288&menuid=3&boardtype=&page=3&articleid=14 꽤나 오랫동안 연재를 하지 않았기에 혹시나 있지 모를 독자들에게 죄송하단 말을 하고 싶다. ![]() 맞다 간단하다...^^ 이제 코드를 알아보자. 앞서 언급한 바와 같이 Server측과 Applet측은 이미 구현되어 있는 것을 그대로 사용하므로 여기서 새롭게 언급하진 않겠다. 그럼 Ajax관련 코드만 나열하면 아래와 같다. 1. LogTailServlet.java 2. LogViewer.html 아주 간단하다...^^ 또한, 여기서는 기본적인 Web App는 구축되어 있다는 가정과 읽어와야 할 대상이 되는 Log파일이 존재한다는 가정하에 글을 진행하고 있으므로 해당 내용에 대해서 따로 언급하진 않겠다. 그럼 하나씩 알아보자. 먼저 LogTailServlet.java import java.io.*; import javax.servlet.*;
public void doGet(HttpServletRequest request, HttpServletResponse response) public void doPost(HttpServletRequest request, HttpServletResponse response) while((sLine = raFile.readLine()) != null) { private void printOutStatus(String sLine, HttpServletRequest request, HttpServletResponse response) throws Exception { 정말 요즈음 들어 Ajax의 매력에 흠뻑 빠진 느낌이다.
정말 오랜만에 블로그를 다시 시작했다..
아무도 모르는 이 블로그는 내가 누구인지 아무도 모르는 곳이다... 그래서 더 솔직해 질 수 있을지도 모르겠다... 오늘 정말 착한 사람을 다시 만났다 난 그 사람을 슬프게만 했는데....그 사람은 여전히 착했다... 그래서 슬픈걸까? 여전히 같은 모습의 그 사람때문일까? 갑자기 15년전의 내 모습이 떠오는건 왜인지... 마냥 슬퍼진다 그저 아둥바둥대며 살아온 시절은 아니었는지....뒤돌아보게 된다 역시 달라지는 건 없지만....그저 그대로이겠지만...
일반적으로 Windows 에서의 Java Application은 Command Console을 사용하여 구동된다.
이 방식은 아래와 같은 단점을 가지고 있다. 1. 사용자 실수로 인해 Command Console에 Mouse Click이 발생하면 Application이 Hold됨. 2. 사용자가 Logout하면 해당 Application이 종료됨. 3. 특별히 제약이 없는 경우 터미널 서버나 원격 데스크탑 Application을 사용하여 같은 Application을 각 User별로 계속 구동할 수 있음. 이런 단점을 극복하기 위해 Unix에서는 Background Process로 구동시키면 되지만, Windows는 그 태생이 End User를 위한 DeskTop이기에 그 개념이 없다. 그와 유사한 개념이 Windows Service이다. 그러나 애석하게도 현재 JDK는 Windows Service를 사용하는 API를 제공하고 있지는 않다. 그로 인해 Apache나 InstallAnywhere등의 Application 벤더들은 그들만의 방법으로 Service등록을 가능하게 해서 사용하고 있는 실정이다. 지금 제시할 방법은 이러한 Java Application을 Windows Service로 등록하는 간단한 방법이다. 프로젝트에 적용중인 모듈에 적용하기 위해 여러자료를 찾다 발견한 매우 간단한 방법이다. 지금까지 제가 배포한 모듈의 경우 모두 이 방법을 사용해 서비스에 등록했다. 방법은 다음과 같다. JavaService.exe 에 구동 Argument로 설정값을 넘겨주면 서비스 등록이 완료되게 된다. 실제 사용은 아래의 방법을 따른다. 1. JavaService.exe를 구한다. 2. 서비스 등록용 batch파일을 만든다. 아래는 필자가 사용하는 파일의 예이다. C:JavaService -install MyApp %JAVA_HOME%jreinserverjvm.dll -Djava.class.path=.;C:MyAppclasses -start MyApp.StartApp -params INSTALL_DIR=C:MyAppr -out C:MyApplogsstdout.log -err C:MyApplogsstderr.log -auto 3. 서비스 해지용 batch파일을 만든다. 아래는 필자가 사용하는 파일의 예이다. C:JavaService -uninstall MyApp 더 자새한 내용은 http://javaservice.objectweb.org/docs/description.html을 참고하기 바란다.
난 흔히 말하는 SMS 솔루션과 관계된 일을 하고 있다....
솔직히 우리 바닥에서 윈도우는 논외였다. 콘솔만 윈도우면 됬으니까... 크리티컬한 관리대상 장비는 거의 대부분 유닉스나 메인프레임이었기 때문이다 그런데... 아래의 기사는 슬슬 이 시장으로도 M$의 문어발이 접근하고 있다는 생각이 든다.... 솔직히 어찌 될지도 궁금하고 겁나기도 하고 어케 대비해야 할지도 고민이다... 어쨋든..그리 멀지 않은 것만은 사실이다. M$ !! 결국 오는건가? =================================================================================== 윈도우만 편애하던 MS의 CEO 스티브 발머가 마음을 바꾸고, MS가 앞으로 기업들이 보유한 다양한 시스템, 심지어 리눅스가 동작중인 시스템이라도 관리가 용이하도록 지원할 예정이라고 밝혔다. 발머는 지난 20일 그간 MS의 핵심 관리 제품인 오퍼레이션 매니저 소프트웨어에서 비(非) 윈도우 머신에 대한 지원을 강화해달라는 고객들의 요청에 귀를 기울여왔다고 밝혔다. 또한 MS는 올해 말 내놓을 버추얼 서버 제품의 서비스 팩 업데이트에서 리눅스 기반의 버추얼 머신 구동에 대한 지원을 강화할 계획이라고 말했다. 발머가 기조 연설을 하는 동안 레드햇 엔터프라이즈 리눅스가 동작중인 버추얼 서버가 시연됐는데, 연설 도중 발머는 "인정하고 싶지는 않지만 그것이 버추얼 서버 고객들에게 중요한 기능이라는 걸 안다"라고 말했다. 오직 고객을 위해? 현재 버전에서도 리눅스나 다른 운영체제를 구동할 수는 있지만, MS는 고객이 윈도우가 아닌 운영체제를 구동해 곤란을 겪을 때도 지원하겠다는 계획을 세운 것이다. MS는 MS 오퍼레이션 매니저(MOM)로 솔라리스 서버를 제어하는 것을 시연하면서, MOM 콘솔 내에 팝업 형태로 알림 메시지가 나타나는 것을 보여주기 위해 솔라리스가 동작중인 시스템에서 냉각팬을 뽑아버리기도 했다. 발머는 "우리는 썬과 긴밀히 작업해왔다. 알고 있겠지만 전에는 썬과의 긴밀한 협력은 생각할 수도 없었다"라고 말하며, 1년 전 양사가 상호 긴장 완화를 한 이래 두 회사가 함께 작업한 그간의 성과를 기반으로 업데이트를 곧 내놓을 것이라고 덧붙였다. WS-매니지먼트 웹 서비스 표준을 통해 솔라리스 서버 장비를 모니터링하는 데 MOM을 사용한다는 것은, MOM 관리 프로그램이 관리 대상이 윈도우 머신인지 알 필요가 없다는 의미다. MS의 인프라스트럭처 서버 마케팅 부문을 총괄하고 있는 밥 켈리는 반대 상황도 함께 시연하면서 "보는 것처럼 솔라리스가 동일한 프로토콜을 이용해 윈도우 머신을 이렇게 쉽게 관리할 수 있다"라고 말했다. MS의 상호운용성 부족하지 않다 켈리는 “MS의 목표는 윈도우가 수많은 윈도우와 비 윈도우 시스템들을 관리하는 데 가장 비용이 적게 드는 방법을 제공한다는 것을 확실히 보여주는 것”이라고 말했다. 그는 이 관리 소프트웨어가 새로 나온 것이지만 상호 운용성을 이미 제공하고 있다며, 이런 점은 MS가 그 동안 충분히 신뢰를 얻지 못했던 부분이라고 말했다. 켈리는 "우리 제품이 다른 회사 제품과 상호 운용이 되지 않는다는 것을 알고 있다는 것이 정말로 '부끄러운 일'"이라고 말했다. 발머는 20일 연설에서 차세대 데스크톱용 윈도우 제품인 '롱혼'에 대해서도 언급했다. 그는 롱혼이 내년 하반기에 나오면 관리 편의성이 나아지고 운영 비용이 좀더 저렴해질 것이라며, 윈도우 운영체제 최고 책임자인 짐 알친이 지난 주에 언급한 내용을 여러 번 되풀이하며 강조했다. 또한 발머는 롱혼 데스크톱 버전이 출시된 후 약 6개월 뒤에 롱혼 서버가 나올 예정이라며 롱혼 서버 출시 시기에 대해 좀더 자세히 언급했다. 역사적으로 볼 때 서버를 출시하기 전 테스트 기간이 비교적 오래 걸리기 때문에 정확한 스케줄을 맞추는 것을 기대하기는 어려웠다. 켈리는 롱혼의 클라이언트 버전과 서버 버전의 개발 주기를 맞춰가고 있다고 말했다. 이는 서버 출시에 필요한 추가 테스트에 6개월이라는 시간이 필요하다는 것을 의미한다. 그는 "이를 지키기 위해 최선을 다하고 있다"라고 덧붙였다. 발머의 이야기는 MS가 단일화된 시스템 센터 제품을 내놓기로 한 계획을 파기하고, 대신 기존 MOM과 시스템 매니지먼트 서버(SMS) 제품에 대한 업데이트 계획을 세우며 향후 관리 소프트웨어를 어떻게 내놓을지 밝힌 지 하루 만에 나온 것이다.
SUN JAVA STREAMING XML PARSER 소개
현재 dom4j를 사용해서 프로젝트를 수행하고 있다. 성능도 괜찮고 API도 잘 되어 있어서 괜찮다고 생각하고 있었는데 메일로 날아온 SJSXP TechTip을 봤는데 JDBC API를 사용하는 듯한 쉬운 사용법이 일단 맘에 든다. 새로운 프로젝트에 적용해보아야 할듯..... ==================================================================================== XML을 사용하는 대부분의 Java 개발자는 SAX (Simple API for XML) 라이브러리와 DOM(Document Object Model) 라이브러리에 익숙할 것이다. SAX는 이벤트 기반의 API이며, 이는 일반적으로 프로그래머가 파서와 몇 개의 리스너를 등록하고, 특정 XML 문법 생성자(예를 들어 요소나 속성)가 도착되면 리스너 메소드가 호출된다는 의미이다. 그 반대로 DOM은 트리 기반의 아케텍처를 가지며, 전체 문서를 스캔하여 마주치는 각각의 문법 생성자의 오브젝트 트리를 구축한다. 프로그래머는 스캔이 완료된 후 오브젝트 트리에 접근하여 수정할 수 있다 이 두 방법 모두 각각의 결점을 가지고 있다: 리스너를 이용하는 이벤트 기반의 API는 일반적으로 다루기 힘들다. 리스너들이 파서에 의해 조종되기 때문이다. 트리 기반의 API는 스캔되는 문서의 양에 비해 과도한 양의 메모리를 소모할 수 있다. 이제 Java 개발자들이 XML 을 스캔하는데 이용할 수 있는 세 번째 API가 등장하였다. StAX (Streaming API for XML parse)가 그것이다. SJSXP란? SJSXP(Sun Java Streaming XML Parser)는 StAX를 빠른 속도로 구현한다. 썬마이크로시스템즈와 협력하고 있는 BEA Systems, XML-guru James Clark, Stefan Haustein, Aleksandr Slominski (XmlPull 개발자들), 그리고 JCP의 다른 멤버들은 JSR 173를 구현하는 것으로써 StAX를 개발하였다. StAX은 공유 인터페이스들에 기반하는, 파서(parser) 독립적인 Java API이다. SJSXP는 Java Web Services Developer Pack v1.5에 포함되어있다. SJSXP에 대해 처음으로 알아차릴만한 것은 이것이 스트림 API에 기반한다는 것이다. 즉, 개발자가 어느 한 노드에 접근하기 위해 전체 문서를 읽을 필요가 없다. 또한, 파서를 시작하여 파서가 데이터를 이벤트 리스너 메소드에 "push"하도록 허용하는 법칙을 따르지 않는다. 대신에 SJSXP는 "pull" 메소드를 구현하며, 이 메소드는 정렬 포인터를 문서에서 현재 스캔되고 있는 지점에 유지한다. 이는 종종 커서(cursor)라고 불린다. 사용자는 단순히 커서가 현재 가리키고 있는 노드에 대한 파서를 요청하면 된다. XML 문서 파싱에 SJSXP 이용하기 SJSXP를 이용하여 XML 문서를 읽는 것은 아주 쉽다. 대부분의 작업은 javax.xml.stream.XMLStreamReader 인터페이스를 구현하는 오브젝트를 통해 이뤄진다. 이 인터페이스는 XML 문서의 첫 부분에서 마지막까지 이동되는 커서를 나타낸다. 몇 가지 명심해야할 것이 있다. 커서는 항상 하나의 아이템(시작 태그 요소, 진행 명령, DTD 선언 등)만을 가리켜야 한다. 또한 커서는 항상 앞으로 움직여야 하며 (뒤로 움직일 수 없다), 다음에 무엇이 나타나는지 미리 보기를 실행할 수 없다. 다음의 코드 발췌에서 파일로부터 XML을 읽는 XMLStreamReader를 얻을 수 있다. URL url = Class.forName("MyClassName").getResource( "sample.xml"); InputStream in = url.openStream(); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader parser = factory.createXMLStreamReader(in); 그 후 다음 코드를 이용하여 XML 파일을 반복할 수 있다. while(parser.hasNext()) { eventType = parser.next(); switch (eventType) { case START_ELEMENT: // Do something break; case END_ELEMENT: // Do something break; // And so on ... } } XMLStreamReader의 hasNext() 메소드는 XML 파일에서 또다른 유효한 아이템이 있는지 확인한다. 만약 있다면, 커서가 다음 아이템으로 넘어가게하기 위해 next() 메소드를 사용할 수 있다. next() 메소드는 만나게되는 문법상 생성자(아이템)의 타입을 가리키는 인티거 코드를 리턴한다. XMLInputStreamReader에는 몇 개의 get 메소드가 있어서 커서가 가리키는 XML 아이템의 내용을 얻는 데 사용할 수 있다. 첫번째 메소드는 getEventType()이다: public int getEventType() 메소드는 커서가 있는 곳에서 파서가 찾은 아이템의 타입을 식별하는 integer 코드를 리턴한다. next() 메소드에 의해 리턴되는 것과 같은 코드이다. 아이템은 XMLInputStream 상수 중 하나에 의해 식별된다. XMLStreamConstants.START_DOCUMENT XMLStreamConstants.END_DOCUMENT XMLStreamConstants.START_ELEMENT XMLStreamConstants.END_ELEMENT XMLStreamConstants.ATTRIBUTE XMLStreamConstants.CHARACTERS XMLStreamConstants.CDATA XMLStreamConstants.SPACE XMLStreamConstants.COMMENT XMLStreamConstants.DTD XMLStreamConstants.START_ENTITY XMLStreamConstants.END_ENTITY XMLStreamConstants.ENTITY_DECLARATION XMLStreamConstants.ENTITY_REFERENCE XMLStreamConstants.NAMESPACE XMLStreamConstants.NOTATION_DECLARATION XMLStreamConstants.PROCESSING_INSTRUCTION 만약 아이템에 이름이 있는 경우, getName()과 getLocalName() 메소드를 사용하여 이름을 얻을 수 있다. 후자는 어떤 다른 정보(예; 확인된 네임스페이스가 없는 요소의 이름) 없이 이름 자체를 산출한다. public Qname getName() public String getLocalName() 만약 당신이 현재 아이템의 네임스페이스를 식별하고 싶다면 getNamespaceURI() 메소드를 사용 할 수 있다. public String getNamespaceURI() 만약 DTD 선언 내의 텍스트나 요소 안의 텍스트 등과 같은 동반되는 텍스트가 있을 때에는 다음 메소드들을 사용하여 얻을 수 있다.(후자는 요소를 위해 단독으로 사용 될 수 있다) public String getText() public String getElementText() 만약 요소가 그것과 관계 되는 속성을 가진다면 getAttributeCount() 메소드를 사용하여 현재 요소가 가진 속성들의 갯수를 얻을 수 있다. 그 후 getAttributeName() 와 getAttributeValue() 메소드를 사용하여 각각의 정보를 검색 할 수 있다. public int getAttributeCount() public Qname getAttributeName(int index) public String getAttributeValue(int index) 만약 속성의 로컬 이름과 요소의 네임스페이스 URI를 안다면, 또한 다음의 메소드를 이용하여 속성값을 얻을 수 있다. public String getAttributeValue( String elementNamespaceURI, String localAttributeName) 추측했겠지만, 모든 접근자 메소드가 특정 상태에 적용가능한 것이 아니다. 예를 들어, 현재 DTD를 프로세싱 중이라면 getElementText()을 호출할 수 없다. 만약 이를 호출한다면, 파서가 충돌하는 이벤트 타입을 식별했다는 XMLStreamException을 얻게 되거나 메소드가 스스로 널(null) 값을 리턴하게 될 것이다. XMLInputFactory 클래스의 setProperty() 메소드를 사용하여 몇 가지 파서 속성을 시작할 수 있다. 예를 들어, 다음은 파서와 마주치는 엔티티 레퍼런스는 교체될 것이라고 지정한다. factory.setProperty( XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.TRUE); 파서가 외부 엔티티를 지원하는 것을 막기 위해 다음과 같이 설정한다. factory.setProperty( XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); 파서가 네임스페이스를 알아차리게하기 위해 다음과 같이 설정한다. factory.setProperty( XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE); SJSXP의 현재 버전에서는 다음의 명령은 허용되지만 파서는 확인되지 않는다는 것을 유의하기 바란다. factory.setProperty(XMLInputFactory.IS_VALIDATING, Boolean.TRUE); 만약 이 XMLInputFactory 특성들 중 어느 하나라도 가능하게 된다면 setXMLReporter() 메소드를 사용하여 파서가 만나게되는 오류를 제어할 수 있다. 파서가 만나는 오류의 타입을 가장 빨리 정확하게 결정할 수 있는 방법은 setXMLReporter() 메소드와 상호 작용하는 익명의 이너 클래스를 사용하는 것이다. 이는 다음과 같다. factory.setXMLReporter(new XMLReporter() { public void report(String message, String errorType, Object relatedInformation, Location location) { System.err.println("Error in " + location.getLocationURI()); System.err.println("at line " + location.getLineNumber() + ", column " + location.getColumnNumber()); System.err.println(message); } }); XML 문서 작성에 SJSXP 사용하기 XML 결과를 작성하는 것은 SJSXP를 이용하면 쉽다. 이 경우, XMLStreamReader 인터페이스 대신에 XMLStreamWriter 인터페이스를 사용할 수 있다. XMLStreamWriter 인터페이스는 작성하는 요소, 속성, 코멘트, 텍스트를 비롯해 XML 문서의 모든 부분을 작성하기 위한 직접적인 메소드를 제공한다. 다음의 예제에서는 어떻게 이 인터페이스를 얻어서 XML 문서를 작성하는데 사용하는지 보여준다. XMLOutputFactory xof = XMLOutputFactory.newInstance(); XMLStreamWriter xtw = xof.createXMLStreamWriter(new FileWriter("myFile")); xtw.writeComment( "all elements here are in the HTML namespace"); xtw.writeStartDocument("utf-8","1.0"); xtw.setPrefix("html", "http://www.w3.org/TR/REC-html40"); xtw.writeStartElement( "http://www.w3.org/TR/REC-html40","html"); xtw.writeNamespace( "html", "http://www.w3.org/TR/REC-html40"); xtw.writeStartElement( "http://www.w3.org/TR/REC-html40","head"); xtw.writeStartElement( "http://www.w3.org/TR/REC-html40","title"); xtw.writeCharacters("Java Information"); xtw.writeEndElement(); xtw.writeEndElement(); xtw.writeStartElement( "http://www.w3.org/TR/REC-html40","body"); xtw.writeStartElement("http://www.w3.org/TR/REC-html40","p"); xtw.writeCharacters("Java homepage is "); xtw.writeStartElement("http://www.w3.org/TR/REC-html40","a"); xtw.writeAttribute("href","http://java.sun.com"); xtw.writeCharacters("here"); xtw.writeEndElement(); xtw.writeEndElement(); xtw.writeEndElement(); xtw.writeEndElement(); xtw.writeEndDocument(); xtw.flush(); xtw.close(); 각 요소를 작성하는 것이 끝나면 사용자는 라이터(writer)를 날려보내고 닫아야한다. 이전의 코드는 다음의 XML로 결과가 나타난다.(여기서는 쉽게 읽을 수 있게 라인 별로 나타내었다.) <!--all elements here are explicitly in the HTML namespace--> <?xml version="1.0" encoding="utf-8"?> <html:html xmlns:html="http://www.w3.org/TR/REC-html40"> <html:head> <html:title>Java Information</html:title> </html:head> <html:body> <html:p> Java information is <html:a href="http://frob.com">here</html:a> </html:p> </html:body> </html:html> XML 문서 필터링 만약 각각의 아이템 타입을 스캔하고 싶지 않다면 들어오는 XML 문서에 대한 필터를 생성할 수 있다. 이를 위해서는 javax.xml.stream.StreamFilter 인터페이스를 구현하는 클래스를 생성한다. 이 인터페이스는 단지 accept() 메소드만으로 구성된다. 이 메소드는 XMLStreamReader 오브젝트를 허용하고 원시 Boolean을 리턴한다. StreamFilter의 일반적인 구현은 다음과 같다. public class MyStreamFilter implements StreamFilter { public boolean accept(XMLStreamReader reader) { if(!reader.isStartElement() && !reader.isEndElement()) return false; else return true; } } 그 다음으로 XMLInputFactory의 createFilteredReader() 메소드를 호출하여 필터링된 리더(reader)를 생성하고 이를 원래 XML 스트림 리더와 StreamFilter 구현에 모두 전달한다. 다음과 같다. factory.createFilteredReader( factory.createXMLStreamReader(in), new MyStreamFilter()); SJSXP의 더 자세한 정보는 Sun Java Streaming XML Parser release notes를 참고하기 바란다. Sun Java Streaming XML Parser 예제 코드 구동하기 이번 테크팁에 대한 샘플 아카이브(ttfeb2005sjsxp.jar)를 다운로드한다. Java Web Services Developer Pack Downloads page에서 Java WSDP 1.5를 다운로드, 설치한다. 예제 압축파일을 다운로드 받은 디렉토리를 변경하고, 다음과 같이 샘플 아카이브에 대한 JAR 파일의 압축을 푼다. jar xvf ttfeb2005sjsxp.jar 사용자의 classpath가 ttfeb2005sjsxp.jar와 jsr173_api.jar를 포함하도록 설정한다. 이들은 Java WSDP 1.5 installation의 sjsxp/lib 디렉토리에 위치하고 있다. SJSXPInput를 컴파일하고 구동한다. 다음의 각각의 XML 아이템과 유사한 엔트리가 나타날 것이다. Event Type (Code=11): DTD Without a Name With Text: ----------------------------- SJSXPOutput를 컴파일하고 구동한다. 결과는 XMLOutputFile라는 이름의 파일에 보내지며, 위의 결과 예제에 보여지는 요소들을 포함할 것이다. 1.Resin Install Command Line Argument 2.resin.conf(1) 3.resin.conf(2) 4.Resin Install on UNIX 5.How to Start with Appache 6.How to Start with IIS 7.Resin3.0 변경사항
Resin 역시 Java Application 이기 때문에 “Write Once, Run Everywhere” 를 추구한다. 그러므로 Unix에서 구동하기 위해 특별히 make해야 한다거나 소스를 수정해야 하는 것은 필요치 않다. 즉, JDK만 설치되어 있다면 동일하다는 뜻이다. 아래 문서의 내용은 Linux와 Mac OS-X도 함께 포함된다. 다만, Daemon이기 때문에 기본적으로 Background로 구동되어야 하고 그 구동방법이 Windows의 그것과는 다르기에 필요한 몇 가지 설정이 있을 뿐이다. Unix에 Install하기 위해 고려할 사항은 아래와 같다.
1. Resin 사용자 계정 생성 2. JDK1.4이상 설치여부 3. Perl 5.6 이상 설치 여부(for $RESIN_HOME/bin/httpd.sh) 4. rc.d 등록여부
이 이외에 resin.conf설정이나 web-app 의 deploy방법, command-line argument사용법 등은 windows의 그것과 동일하며 이미 앞선 글에서 설명되었으므로 생략하도록 하겠다.
1. Resin 사용자 계정 생성 A. Install Guide에 의하면 Resin을 구동하기 위한 특별한 계정은 따로 존재하지 않는다.(꼭, Root 이어야 할 필요는 없다. 오히려 보안정책상 일반 User를 추천한다.) B. 필요하다면 JAVA_HOME 과 RESIN_HOME을 설정한다.(구성되어 있지 않다면 설정하는 것이 좋다.)
2. JDK1.4이상 설치여부 A. Caucho에서는 JDK1.4이상을 권고하고 있으며 version확인법은 아래와 같다. # java –version java version "1.4.2_06" Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_06-b03) Java HotSpot(TM) Server VM (build 1.4.2_06-b03, mixed mode) B. 주의할 것은 JRE만 설치되어서는 안되고 JDK가 설치되어야 한다는 것이다. 위의 내용은 JRE만 Check 할 수 있을 뿐이다. # javac Usage: javac where possible options include: -g Generate all debugging info -g:none Generate no debugging info -g:{lines,vars,source} Generate only some debugging info -nowarn Generate no warnings -verbose Output messages about what the compiler is doing -deprecation Output source locations where deprecated APIs are used -classpath -sourcepath -bootclasspath -extdirs -d -encoding -source -target -help Print a synopsis of standard options C. 위와 같이 JDK 설치도 확인되어야 한다. D. 각 OS별로 JDK설치 방법은 다르므로 관련 OS의 Tech note를 참조하기 바라며 이 글에서는 언급하지 않겟다.
3. Perl 5.6이상 설치여부 A. Unix에서 resin을 구동하는 방법은 $RESIN_HOME/bin/httpd.sh를 사용하는 것이다. B. Httpd.sh의 내용은 주석부분을 제거하면 아래와 같다. #! /bin/sh # # Extra arguments to Java. If you're passing arguments to the JVM, you'll # need to use -Jxxx. For example, args="-J-ms48m". You can modify # the pid file with args="-pid server-a.pid" # args= # class to start class=com.caucho.server.http.HttpServer # name of the server name=httpd # location of perl executable perl=perl # trace script and simlinks to find thw wrapper script=`/bin/ls -l $0 | awk '{ print $NF; }'` while test -h "$script" do script=`/bin/ls -l $script | awk '{ print $NF; }'` done bin=`dirname $script` exec $perl $bin/wrapper.pl -chdir -name "$name" -class "$class" $args $* 결과적으로 보면 httpd.sh가 있는 디렉토리를 구해서 perl을 사용해서 wrapper.pl이라는 파일을 구동시키고 있음을 알 수 있다. 위의 파일에 포함된 실행옵션들은 글 말미에 별도 설명하고 여기선 생략한다. 자세히 해석하길 원한다면 Unix shell script에 관한 자세한 자료를 참조하길 바란다. C. 위에서 언급한 wrapper.pl의 내용은 아래와 같다. i. Wrapper.pl은 약 800여 line의 perl파일이다. 해당 파일의 내용을 하나씩 해석하는 것은 Perl script 사용법을 언급하며 설명하는 것이고 이 글의 범위를 벗어나게 되므로 지양한다. ii. 다만, 관련 파일의 내용에 대해 나열하고 주의사항을 언급한다. iii. Wrapper.pl의 내용은 아래와 같다. 1. Resin의 start, stop, restart 2. JAVA_HOME설정 3. RESIN_HOME설정 4. configuration file의 변경 5. CLASSPATH설정 6. native thread로 강제 구동 7. green thread로 강제 구동 8. jit 컴파일러 사용여부 9. stdout log file의 변경 10. stderr log file의 변경 11. pid file 설정 12. 자동 restart 여부 iv. Wrapper.pl관련 오류 및 조치사항 1. 먼저 wrapper.pl구동을 위한 Perl은 Version 5.6이상을 권고하고 있으며 확인방법은 아래와 같다. # perl -v This is perl, v5.6.1 built for sun4-solaris-64int (with 48 registered patches, see perl -V for more detail) Copyright 1987-2001, Larry Wall 2. 아래의 내용은 perl이 설치되어 있지 않거나 perl 버전이 낮은 경우 발생한다. # ./httpd.sh start usage: dirname [ path ] Can't open perl script "/wrapper.pl": No such file or directory 3. 아래의 내용의 원인도 역시 perl이 설치되지 않았거나 version이 맞지 않아서 발생하며 참고로 위의 내용은 HP-UX11에서 발생한 내용이다. # ./httpd.sh syntax error in file ./wrapper.pl at line 9, next 2 tokens "use File" syntax error in file ./wrapper.pl at line 72, next 2 tokens "my(" syntax error in file ./wrapper.pl at line 73, next 2 tokens "fileparse(" syntax error in file ./wrapper.pl at line 517, next 2 tokens "0 and" syntax error in file ./wrapper.pl at line 527, next token "}" syntax error in file ./wrapper.pl at line 634, next 2 tokens "setpgrp;" syntax error in file ./wrapper.pl at line 706, next 2 tokens "my $file " syntax error in file ./wrapper.pl at line 715, next 2 tokens "$dir or" syntax error in file ./wrapper.pl at line 717, next 2 tokens "$pwd or" syntax error in file ./wrapper.pl at line 724, next 2 tokens "$dir or" ./wrapper.pl has too many errors. 4. 아래의 내용은 resin이 사용하는 pid파일을 write하지 못할 때 발생하는 내용이다. 해결방법은 해당 디렉토리와 파일의 권한을 확인하고 재설정하도록 한다. # ./httpd.sh start Can't locate Socket.pm in @INC at /resin-2.1.4/bin/wrapper.pl line 10. BEGIN failed--compilation aborted at /resin-2.1.4/bin/wrapper.pl line 10.
4. rc.d등록여부 A. rc.d관련 설정은 해당 시스템 관리자의 role이므로 기본적으로는 권한이 있는 관리자에게 설정해달라고 하는 것이 옳다. B. Caucho의 권고사항은 아래와 같다. httpd.sh를 resin/bin에 resin-a.sh로 이름을 바꾸고 권한을 할당하여 복사한다. resin-a.sh에 JAVA_HOME, RESIN_HOME, PATH, "-pid" 를 설정한다. "resin-a.sh start" 와 "resin-a.sh stop”을 root 계정으로 test한다. 아래와 같이 수행한다. "ln -s /usr/local/resin/bin/resin-a.sh /etc/rc.d/rc3.d/S86resin-a" "ln -s /usr/local/resin/bin/resin-a.sh /etc/rc.d/rc5.d/S86resin-a" "ln -s /usr/local/resin/bin/resin-a.sh /etc/rc.d/rc2.d/K14resin-a"sr/local/resin/bin/resin-a.sh /etc/rc.d/rc3.d/S86resin-a" "ln -s /usr/local/resin/bin/resin-a.sh /etc/rc.d/rc5.d/S86resin-a" "ln -s /usr/local/resin/bin/resin-a.sh /etc/rc.d/rc2.d/K14resin-a"
이글루는 표가 지원안된다...
간신히 미리보기에서 제대로 보이게 만들었더만 정작 올리니까 깨진다. 결국 사내 intranet에 올린 걸 그림으로 떠서 붙이기로 했다...쩝
ITSMF korea에서 하는 첫 포럼 기념의 행사였던 ITIL Foundation교육을 받았다.
2일간 교육과 마지막날 인증시험이 있었고 꽤나 힘들게 공부했다. 내용은 쉬웠지만 너무 짧은 기간이 문제였다. 떨어질까 겁났는데 합겼했다....^^ 4일 과정이라면 무난할 듯 하다. 올해 목표가 PMP, CISSP, ITIL Foundation이었는데 일단 하나는 이룬셈이다. 이제 PMP를 향해 달려가야겠다....이건 좀 더 공부해야겠지?...^^
이번 내용은 지난주에 언급한 바와 같이 다중 서비스 구축 방법에 대해서 알아보겠다.
1. 다중서비스 구축방법 이 문제는 resin이 standalone으로 구동된다는 전제하에 해당되는 것이다. 만약 Apache나 IIS에 plugin으로 구동시키고 있다면 두 개의Instance를 띄운다는 것은 Apache와 IIS의 설정과 관련된 일이므로 이 문서의 범위 밖의 일이므로 언급하지 않겠다. 두 개 이상의 instance를 사용하는 방법 현재 resin은 기본적으로 단일 Java 프로세스로 구동되며 내부적으로 Client의 요청마다 Thread를 생성하여 구동하는 기본적인 WebServer구조를 유지하고 있다. 즉, 이 말은 두 개의 instance를 띄운다는 것은 (Oracle에서의 Instance개념과 달리) 두 개의 Java Process를 각각 구동시킨다는 의미가 된다. 그러므로 두 개의 프로세스를 구동시키기 위해서는 Unix나 Windows 모두 권한이 있는 계정으로 접속한 후 command를 통해 여러개의process를 띄우면 되겠으나 두가지 고려할 사항이 있다. 1. port 설정 만약, 같은 port로 두 개를 띄우고 각각 자동적으로 서비스 되길 바란다면 그것은 두 개의 서비스가 아니라 하나의 서비스에 load balancing을 위한 설정을 하겠다는 뜻이다. 그러므로 두 개의 instance를 띄운다는 것은 각각 port가 다르게 설정되어야 함을 의미한다. port가 다르다는 것은 두 개의 resin.conf 파일이 각각 다르다는 것을 의미한다. 즉, $RESIN_HOME/bin/httpd -install -conf $파일명을 사용하여 각각 다른 conf파일을 지정해야 할 것이다. 2. Windows Service명 중복 Unix의 경우 어차피 Daemon Process로 구동되도록 명령을 수행할때, 같은 process명이라도 pid가 다르므로 상관없이 둘 다 daemon 으로 구동되겠지만 Windows의 경우 Background process로 구동하기 위해 service로 구동할 때는 service명이 같으면 안된다는 문제가 있다. 이 문제는 서비스 명을 다르게 주어서 등록하는 방법을 사용해 해결하면 된다. 즉, $RESIN_HOME/bin/httpd -install-as $서비스명을 사용하여 구동하여 중복된 이름을 방지할 수 있다. 이상의 두가지 문제는 이미 올렸던 글 1.Resin Install Command Line Argument을 참조하면 알 수 있다. 다중 web-app 와 가상호스트 지난 글에도 언급했지만 resin.conf의 구조는 아래와 같다. <caucho.com> <http-server> <host id='gryffindor.caucho.com' app-dir='gryffindor'> <web-app id='/'> <servlet-mapping .../> ... </web-app> <web-app id='/test' app-dir='/usr/local/test'> ... </web-app> </host> <host id='slytherin.caucho.com' app-dir='slytherin'> ... </host> ... </http-server> </caucho.com> 이 구조를 잘 살펴보면 하나의 http-server에 두개 이상의 host가 존재하며 하나의 host에 두개 이상의 web-app가 존재함을 알 수 있다. 즉, 아래의 그림으로 설명할 수 있다. 위의 그림을 보면 의문점이 생길 것이다. 맨 아래쪽의 접근 방식을 보면 하나의 web-app를 사용할 때도 위와 같이 디렉토리명을 사용해서 접근이 가능한데 무엇이 다른가 하는 것이다. 다른점은 다른 app로 작동하느냐 이다. 즉, 하나의 web-app를 사용할 때는 아무리 디렉토리별로 다르게 접근한다고 해도 모두 같은 session을 공유하고 같은 WEB-INF의 class를 사용하도록 되어 있다. 하지만, 위와 같은 경우는 각기 다른 session을 가지며, 또한 WEB-INF 역시 각기 달리 갖는다. 완전히 독립적인 app로 인식한다는 것이다. 게다가 web.xml을 사용할 경우도 역시 각기 다른 web.xml을 사용해야 함은 물론이다. 그렇다면 가상호스트는 무엇인가? 위의 그림에서 하나의 서버에 두 개의 host가 존재한다 각각은 고유의 도메인을 가지고 있지만 같은 host의 같은 ip를 사용한다. 즉, 글자 그대로 가상의 호스트처럼 동작한다는 의미이다. 일단 사용자의 hosts파일은 아래와 같다고 가정한다. /etc/hosts 127.0.0.1 localhost 127.0.0.1 www.sms.co.kr 127.0.0.1 www.maxigent.co.kr 사용자는 www.maxigent.co.kr로 접속을 시도한다. 그러면 먼저 사용자의 hosts파일을 검색해서 해당 도메인에 대한 정보에 해당하는 ip로 접속을 시도한다. 만약 해당정보가 없다면 해당 user의 시스템에 설정된 DNS서버에 quering을 하게 될 것이다. 이 부분에 대한 자세한 정보를 원한다면 internetworking의 구조에 대해 참조하기 바란다. resin은 해당 request가 들어오면 자신의 conf파일을 검색해서 host id와 mapping을 시도한다. 그 결과 해당하는 host id가 존재하면 그부분의 web-app를 반환하게 된다. 결론적으로 기본적인 virtual hosting을 위한 resin.conf는 아래와 같다 <http-server> ... <host id='sms.sds.co.kr'> <app-dir>/home/www/sms/docs</app-dir> ... </host> <host id='maxigent.sds.co.kr'> <app-dir>/home/www/maxigent/docs</app-dir> ... </host> 이 이외에 Virtual Host with Apache or IIS, JVM per Virtual Host, IP-Based Virtual Hosting등의 좀더 깊이있는 주제는 http://www.caucho.com/resin-2.1/ref/virtual-host.xtp 을 살펴보기 바란다. 각 방법별 적용 위에서 두 개 이상의 web-app를 구동하는 방법을 알아봤다. 대부분의 site에서는 위와 같은 방법을 사용하여 운영할 이유는 특별히 없을 것이다. 그러나, 개발중인 경우나 test나 BMT등의 daemo용으로 구축을 요할 때 위의 방법중 하나를 사용하는 것은 필요하다. 위의 방법중 첫 번째 resin을 두 개 이상 구동하는 것을 추천한다. 물리적인 장비의 성능 및 용량이 충분하다면 이 방법을 사용하여 운영중이거나 혹은 다른 개발중인 app에 영향없이 다른 app를 구동할 수 있기때문이다. 물론, virtual host나 web-app를 두 개 이상을 두는 것도 생각해 볼 수 있는 방법이긴 하나 일단 web-app를 두 방법 모두 해당 resin instance의 성능을 나눠 사용하는 것이므로 먼저 운영중인 app에 영향이 생기는 것은 부정할 수 없다. 또한, web-app를 나눠 사용하는 경우 doc-root가 같기 때문에 개발자의 실수로 인한 다른 app의 문제 발생 소지를 가지고 있다. virtual host의 경우 일단 DNS를 설정해야 한다는 문제가 있고, 그렇지 않을 경우 ip-based로 설정해야 하는데 이것 또한 장비의 NIC가 두 개 이상이어야 한다는 제한이 생기게 된다. 즉, 두 개 이상의 서비스가 필요하다면 장비의 성능이 제공하는 범위에서 각기 다른 process로 구동하라는 것이 결론이다. 장비의 성능이 문제가 된다면 -Xms, -Xmx -Xss등의 메모리 관련 command line argument와 <thread-max>, <thread-keepalive>, <request-timeout>, <accept-buffer-size>, <thread-min> 등의 값을 조절하면 될 것이다.
|
카테고리
이전블로그
이글루링크
최근 등록된 덧글
잘봤읍니다
by wsa at 04/25 덕분히 시원하게 해결되.. by 호호호 at 08/24 최소30%의 여유공간은 .. by 달터 at 03/23 혼자 하는 Project라 이.. by 제이 at 12/04 혹시 url 허용 길이를 설.. by 조승모 at 07/31 퍼갑니다~~ by hsu at 11/02 여러 자료를 보며 공부.. by ^_^ at 01/05 모사이트 를 들어가서 그.. by dfdssds at 12/19 감사합니다 퍼갈께요 by ㄳ at 06/19 좋은 글 잘 보았습니다. .. by Oops at 12/14 메모장
ITIL Foundation PMP CISSP CISA 기술사 최근 등록된 트랙백
cheap ray ban sung..
by breaking up with a bo.. moncler online alış.. by it blocks your pores.. reduce weight fruta p.. by bee pollen suppleme.. reduce weight fruta p.. by bee pollen weight los.. b pollen weight loss by botanical slimming re.. botanical slimming sof.. by paiyouguo Do they ro.. slim forte double power by botanical slimming sof.. bee pollen weight loss by reduce weight fruta p.. fruta planta pills by reduce weight fruta p.. Miaozi Slimming Caps.. by botanical slimming y.. 이글루 파인더
라이프로그
|