<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="http://benelog.egloos.com/style/style_rss.xsl" type="text/xsl" media="screen"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
	<title>개발을 통한 자기수양 - benelog</title>
	<link>http://benelog.egloos.com</link>
	<description>세상에 대한 진심어린 기대 </description>
	<language>ko</language>
	<pubDate>Thu, 19 Jun 2008 11:08:36 GMT</pubDate>
	<generator>Egloos</generator>
	<image>
		<title>개발을 통한 자기수양 - benelog</title>
		<url>http://md.egloos.com/img/samplelogo.gif</url>
		<link>http://benelog.egloos.com</link>
		<width>80</width>
		<height>80</height>
		<description>세상에 대한 진심어린 기대 </description>
	</image>
  	<item>
		<title><![CDATA[ 코드 검색 사이트 ]]> </title>
		<link>http://benelog.egloos.com/1941048</link>
		<guid>http://benelog.egloos.com/1941048</guid>
		<description>
			<![CDATA[ 
  <p><a href="http://www.google.com/codesearch" title="http://www.google.com/codesearch" class="external">http://www.google.com/codesearch</a></p><p><a href="http://www.krugle.com/" title="http://www.krugle.com/" class="external">http://www.krugle.com/</a></p><p><a href="http://koders.com/" title="http://koders.com/" class="external">http://koders.com/</a></p><p><a href="http://codase.com/" title="http://codase.com/" class="external">http://codase.com/</a></p><p><a href="http://programmingishard.com/" title="http://programmingishard.com/" class="external">http://programmingishard.com/</a></p><p><a href="http://labs.oreilly.com/code/" title="http://labs.oreilly.com/code/" class="external">http://labs.oreilly.com/code/</a></p><p><a href="http://www.digibarn.com/collections/posters/tongues/tongues.jpg">http://www.digibarn.com/collections/posters/tongues/tongues.jpg</a></p><p><a href="http://www.apifinder.com/">http://www.apifinder.com/</a></p>			 ]]> 
		</description>
		<category>기술 자료</category>
		<pubDate>Thu, 19 Jun 2008 11:08:36 GMT</pubDate>
		<dc:creator>정상혁</dc:creator>
	</item>
	<item>
		<title><![CDATA[ Spring 3.0에 대한 소식 ]]> </title>
		<link>http://benelog.egloos.com/1937831</link>
		<guid>http://benelog.egloos.com/1937831</guid>
		<description>
			<![CDATA[ 
  <ul><li><a class="external" title="http://www.springify.com/archives/15" href="http://www.springify.com/archives/15"><span style="COLOR: #810081">Live from SpringOne 2008: Collected bits about Spring 3.0</span></a></li></ul><p>&nbsp;벌써 3.0에 대한 이야기가 나오고 있습니다.</p><p>&nbsp;잘 하면 2008년 4분기 정도에&nbsp;GA(General Availability) release(일반사용 가능 버전)가 나온다고 하는군요. Spring Core 모듈이 Java 5에 대해 본격적으로 의존하고&nbsp;이제 더 이상&nbsp;&nbsp;Java 1.4에서는 돌아갈 수 없다고 합니다.</p><p>&nbsp; 이미 어느 정도 윤곽이 잡혀있듯이,&nbsp; Spring MVC에서 REST에 대한 full scale 지원이 포함된다는군요. 그리고&nbsp;&nbsp;Spring batch에서 지원되었던&nbsp;repeat, retry, resume의 개념들과 &nbsp;Spring WS의 <a class="external" title="http://static.springframework.org/spring-ws/site/reference/html/oxm.html" href="http://static.springframework.org/spring-ws/site/reference/html/oxm.html"><span style="COLOR: #810081">Spring OXM</span></a> 등이 보다 상위 모듈에서 포함되어서 제공될지도 모르겠습니다.&nbsp;또, Junit 3.8 기반의 통합테스트 클래스들은 deprecated로 표시될 것 같습니다. (아마도 <a class="external" title="AbstractSingleSpringContextTests" href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/test/AbstractSingleSpringContextTests.html"><span style="COLOR: #800080">AbstractSingleSpringContextTests</span></a>같은 클래스들을 이야기하는 것이겠죠?)</p>			 ]]> 
		</description>
		<category>개발 이야기</category>
		<pubDate>Tue, 17 Jun 2008 08:58:00 GMT</pubDate>
		<dc:creator>정상혁</dc:creator>
	</item>
	<item>
		<title><![CDATA[ Q33N의 비밀 - 뉴욕의 프로그래머 중 ]]> </title>
		<link>http://benelog.egloos.com/1936267</link>
		<guid>http://benelog.egloos.com/1936267</guid>
		<description>
			<![CDATA[ 
  <p>이전에 다른 게시판에 썼던 글인데, 오랜만에&nbsp;이 내용이 생각나서 여기에도 올려봅니다.<br />
</p><hr><p>&nbsp;존경하는 임백준님의 책 '<a class="external" title="뉴욕의 프로그래머" href="http://blog.hanb.co.kr/11">뉴욕의 프로그래머</a>'에 있는 내용입니다.<br />
</p><p><br />
</p><blockquote><p>노트패드로 할 수 있는 일이 생각보다 많다는 사실을 알고들 있는지?</p><p>어느 날 신나게 구라를 풀던 콜린이 말했다.</p><p>쌍 둥이 빌딩이 무너졌을 때 건물을 들이받은 비행기의 번호가 Q33N이었다는 것을 기억하는 사람은 없겠지만, 아무튼 그렇거든. 노트패드를 열고 Q33N을 입력해봐. 그리고 폰트 크기는 72로 최대한 키우고. 그 다음 글자체를 Wingdings로 선택하라고. 화면에 뭐가 나타나는지 보라고.</p><p style="text-align: right;">&nbsp;&nbsp;story 3. "무정부주의자 콜린" 중에서</p></blockquote><p><br />
</p><p><br />
</p><p>전 책에서 이 부분을 읽자 마자 따라서 해봤고, 화면에 나온 결과를 보고 정말 신기하다고 느꼈죠. windows개발자가 몰래 911를 추도하기 위해서 넣은 것일 거라고&nbsp;생각했었습니다.&nbsp;나아가서 집에 있는 윈도우 2000이 깔린 컴퓨터에서도 되는 걸 보고 MS가 911이후에 2000버전의 노트패드에도 패치를 한건지, 아니면 개발자 중에 놀라운 예언가가 있었던것일까 하는 상상도 했었습니다.<br />
</p><p><br />
</p><p>&nbsp;그.러.나.</p><p>&nbsp;혹시나 해서 찾아봤더니, 실제의 비행기 번호는 그와 전혀 다른 번호였고, 위의 이야기는 정말로 '구라'였습니다. 원래 폰트가 그렇게 생겨먹은 겁니다.</p><p><a href="http://www.hoax-slayer.com/wingdings-911.html"></a>&nbsp;</p><p>&nbsp;다음&nbsp;링크의 아래쯤에 가면 'Q33NY'라는 문자열로 그런 소문이 도는데&nbsp;사실이 아니라고 밝히고 있습니다.</p><p><a href="http://www.hoax-slayer.com/wingdings-911.html"><span style="color: rgb(128, 0, 128);">http://www.hoax-slayer.com/wingdings-911.html</span></a></p><br />
<p>&nbsp;네이버의 지식인에서도 비슷한 질문들이 오갔고, 여기서보니 호기심 천국에도 옛날에 나왔다고 하는군요.</p><p><a href="http://kin.naver.com/detail/detail.php?d1id=1&amp;dir_id=106&amp;eid=mEFZPG/iLDaISzjuCO7V4mXyyWV1VCWm&amp;qb=cTMzbnk=">http://kin.naver.com/detail/detail.php?d1id=1&amp;dir_id=106&amp;eid=mEFZPG/iLDaISzjuCO7V4mXyyWV1VCWm&amp;qb=cTMzbnk=</a><br />
</p><br />
<p>원래 저는&nbsp;의심이 많은 편인데, 이번에는 완전 속을 뻔 했습니다 ^^; 아마 임백준님도 사실이 아니라는 것을&nbsp;아시면서도 재미로 책에 넣으신거겠죠? ^^</p>			 ]]> 
		</description>
		<category>개발 이야기</category>
		<pubDate>Mon, 16 Jun 2008 08:39:29 GMT</pubDate>
		<dc:creator>정상혁</dc:creator>
	</item>
	<item>
		<title><![CDATA[ Spring batch와 Spring integration의 만남 ]]> </title>
		<link>http://benelog.egloos.com/1935914</link>
		<guid>http://benelog.egloos.com/1935914</guid>
		<description>
			<![CDATA[ 
  <p>&nbsp; Spring portfolio의 일부 중 최근에 관심을 제가&nbsp;관심을 가지고 있는&nbsp;&nbsp;Spring batch와 Spring integration을&nbsp;연결한 프로토타입 코드들이 나왔습니다.</p><p>&nbsp; Spring batch form에 최근에 올라온 글입니다.&nbsp;</p><ul><li><a class="external" title="http://forum.springframework.org/showthread.php?t=55863" href="http://forum.springframework.org/showthread.php?t=55863">Spring Integration Prototype</a></li></ul><p>&nbsp; 그리고&nbsp;&nbsp;6월 18일에 이 것을 주제로 한 온라인 세미나 같은것이 있나 보네요. </p><ul><li><a class="external" title="http://www.springframework.org/node/687" href="http://www.springframework.org/node/687">Webinar: Enterprise Integration with Spring Batch</a></li></ul><p>&nbsp; 이 코드들은 Java 5를 사용하기 때문에 Spring batch 1.1 정식 배포판에는 들어가지 않을거라고 합니다. Spring batch 프로젝트에서는 2.0전까지 Java5 으로 가지는 않을거라고 하네요.</p><p>&nbsp; <a class="external" title="http://zepag.blogspot.com/2008/06/springone08-spring-batch.html" href="http://zepag.blogspot.com/2008/06/springone08-spring-batch.html">SpringOne 08의 Spring batch 주제의 발표</a>에서도 관련 내용이 들어갈 것 같네요. Spring batch와 Spring integration의 convergence가 있는 것으로 보인다는 언급이 있습니다.</p><p><a href="http://www.egloos.com/egloo/insert.php?eid=d0032573"></a></p><p>&nbsp;Spring batch와&nbsp;Spring WS, Spring Integration은 얽히고 섥힌 관계라고 보입니다. Spring integration의 Web Service Adapters에서 Spring Web Service를 사용하고 있고, Spring batch에서도 XML파일 처리에 Spring WS의 일부인 <u><a class="external" title="http://static.springframework.org/spring-ws/site/reference/html/oxm.html" href="http://static.springframework.org/spring-ws/site/reference/html/oxm.html"><span style="COLOR: #810081">Spring OXM</span></a></u>를 통한 위임처리를 할 수 있습니다. 그리고 위와 같이 Spring integration는 Spring batch도 연결시켰군요.</p><p>&nbsp; Spring batch의 Job은 Spring Application Flatform을&nbsp;통해서 OSGi 번들로도&nbsp; 실행가능하게 되었습니다.</p><ul><li>&nbsp;&nbsp;<a class="external" title="http://blog.springsource.com/main/2008/05/30/running-a-spring-batch-job-in-the-springsource-aplication-platform/" href="http://blog.springsource.com/main/2008/05/30/running-a-spring-batch-job-in-the-springsource-aplication-platform/">Running a Spring Batch Job in The SpringSource Application Platform</a></li></ul><p>&nbsp; 향후 버전에서는 더욱 더 배치에 특화된 기능들이 추가될 것이라고 하네요.</p><p>&nbsp;&nbsp;Spring batch + Spring Integration + Spring WS + Spring Application Flatform.. 그 미래가 어떻게 될지 정말 기대가 됩니다. </p><p>&nbsp; 가끔 google이 하는 짓들을 보면 그런 생각이 들었는데,&nbsp; 스프링도 이러다보면 세계정복을 하는게 아닐지 모르겠습니다.;</p>			 ]]> 
		</description>
		<category>개발 이야기</category>
		<pubDate>Mon, 16 Jun 2008 03:05:36 GMT</pubDate>
		<dc:creator>정상혁</dc:creator>
	</item>
	<item>
		<title><![CDATA[ Effective Java 2nd Edition ]]> </title>
		<link>http://benelog.egloos.com/1912122</link>
		<guid>http://benelog.egloos.com/1912122</guid>
		<description>
			<![CDATA[ 
  <p>&nbsp;&nbsp; Amazon에서 예약주문 단계에서 판매상태로 바뀌었습니다.<br><a href="http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1212115691&amp;sr=8-1"><span style="COLOR: #810081">http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1212115691&amp;sr=8-1</span></a></p><p>&nbsp;</p><p>&nbsp; 회사에서 Yes24에서 책을 주문할 수 있는 쿠폰을 주기 때문에 저는 공짜로 보기 위해서 거기서 주문할 수 있을 때까지 기다리고 있는 중입니다.<br><br>&nbsp; Joshua Bloch과의 인터뷰를 보니 역시 Generics등 Java5 이후의 주제들에 대해서 내용이 보강되었다고 하네요. 정확히는 21개의 항목과 83페이지가 늘어났다고 합니다. 기대가 되는군요.<br><br><a class="external" title="http://www.infoq.com/articles/bloch-effective-java-2e" href="http://www.infoq.com/articles/bloch-effective-java-2e"><span style="COLOR: #810081">Book Excerpt and Interview: Effective Java, Second Edition</span></a><br><br>더불어 121페이지의 예제코드의 실수도 언급되어 있길래 옮겨봅니다.</p><p>&nbsp;</p><p>지금 인쇄판에 들어간 코드</p><blockquote><p>static Object reduce(List list, Function f, Object initVal) {<br>&nbsp;&nbsp;&nbsp; Object[] snapshot = list.toArray(); // Locks list internally<br>&nbsp;&nbsp;&nbsp; Object result = initVal;<br>&nbsp;&nbsp;&nbsp; for (Object o : list)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = f.apply(result, o);<br>&nbsp;&nbsp;&nbsp; return result;<br>}</p></blockquote><p>&nbsp;</p><p>수정된 내용</p><blockquote><p>static Object reduce(List list, Function f, Object initVal) {<br>&nbsp;&nbsp;&nbsp; Object[] snapshot = list.toArray(); // Locks list internally<br>&nbsp;&nbsp;&nbsp; Object result = initVal;<br>&nbsp;&nbsp;&nbsp; for (Object o : snapshot)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = f.apply(result, o);<br>&nbsp;&nbsp;&nbsp; return result;<br>}</p></blockquote><p>&nbsp;</p><p>&nbsp; Joshua Bloch의&nbsp;말에 따르면&nbsp;다음에 찍는 인쇄판에서는 수정을 하겠지만 현재 시중에 나가는 판에는 이 오류가 포함이 되어 있다고 합니다.</p><p>&nbsp;</p><p>&nbsp; 이 책의 초판에 대해서 저도 워낙 많이 추천과 인용을 하고 다녀서 저를 아시는 분들은 이 책 이야기가&nbsp;&nbsp;이제 지겹다고도 느끼실지도 모릅니다. 그래도 또 한번&nbsp;해보겠습니다.</p><p>&nbsp;Java 개발자는 크게 두 종류로 나눌 수 있습니다. Effective Java의 내용을 아는 사람과 모르는 사람. 이 책을 읽지 않은 개발자가 Java의 API 설계에 참여했던 Joshua Bloch만큼 Java에 대해서 알거나 그만큼 천재가 아닌 경우를 빼고는 이 책을 읽은 개발자보다 좋은 Java 코드를 짜기는 힘들다고 생각합니다. 이 책을 읽지 않고도&nbsp;자기가 짠 Java 코드를 공개한 적이 있는 사람이라면 읽고 나서는 당장 그 코드를 수정하고 싶어질 것입니다. 이 책을 읽지 않고도&nbsp; '나는 괜찮은 Java개발자야' 라고 생각한다면 그것이 자만이나 착각일 가능성이 더 높습니다.</p><p>&nbsp;&nbsp;2001년도에 초판이 나온 이후로 &nbsp;Java 개발자의 필독서라고도 불려지고 있지만, 여기저기서 만나는 코드를 보면 아직도 이 책을 안 읽은 사람이 많은 것을 알 수 있습니다. 회사 전체에서 쓰는 프레임웍들에 들어간 코드에도 이 책에서 나오는 지침에 어긋나서 잠재적인 문제점을 가지고 있는 경우를 몇 번이나 봤습니다.</p><p>&nbsp; Ruby를 배우는&nbsp;것도 좋고, 디자인 패턴이나 프레임웍을 공부하는 것도 좋습니다. 아니면 Java Language Spec를 바닥부터&nbsp;공부하는 것도 중요할 수 있습니다. 하지만 그 이전에,&nbsp;Java를 쓰는 프로젝트에 있는 사람이라면 이 책을 읽는 것이 우선일 것입니다. 리팩토링을 배우는 것도 그 대상언어가 Java라면 마틴파울러의 책보다 이 책이 더 중요하다고 생각합니다. 마틴파울러의 리팩토링은 고민을 하고 프로그래밍을 하는 개발자라면 그 책을 읽지 않아도&nbsp; 이미 실천하고 있는 기법들이 많을 것입니다. 그러나 Effective Java의 교훈들은 책을 안 본 사람이 스스로 깨닳기에 힘든 내용도 많습니다.</p><p>&nbsp; 사실 저도 최근에 책을 다시보니 처음 볼 때&nbsp;깨닳지 못했던 것도 많이 배우고 있습니다. 그래서 저도 Effective Java의 교훈을 다 익히고 잘 활용하고 있는 사람이라고 말할 수는 없습니다. </p><p>&nbsp; 그래도 이 책 덕분에 저는 많은 것을 얻었습니다.&nbsp; 이 책에서 배운 것을 바탕으로&nbsp;쓴 글&nbsp;덕분에 많은 분들을 알게 되기도 했으니까요.&nbsp; 널리 알려서 좋은 정보가 있으면 가끔이라도 정리해서 여기저기 올리는 일도 이 책을 읽고난 후부터 하게 되었던 것 같습니다.</p><p>&nbsp;</p><p>&nbsp;</p>			 ]]> 
		</description>
		<category>개발 이야기</category>
		<pubDate>Fri, 30 May 2008 06:57:49 GMT</pubDate>
		<dc:creator>정상혁</dc:creator>
	</item>
	<item>
		<title><![CDATA[ Java에서 Checked Exception은 언제 써야 하는가? ]]> </title>
		<link>http://benelog.egloos.com/1901121</link>
		<guid>http://benelog.egloos.com/1901121</guid>
		<description>
			<![CDATA[ 
  <p>&nbsp;&nbsp;Java 의 Exception 처리는 C++에서 도입되었지만 checked exception은 Java만의 독특한 특징입니다. 아시다시비, 컴파일러가 exception을 꼭 처리해라고 강요하는 것이죠. &nbsp;이것은&nbsp; java 이후에 설계된 언어인 C#이나 루비에도 채택되지 않았습니다. 즉 Java 이외의 다른 언어들의 Exception 처리 방식은 Java의 unchecked exception과 동일한 방식입니다.</p><p>&nbsp; Java의 초기에 checked Exception의 사용을 권장하던 것에 대해서 지금은&nbsp;많은 반론이 제기되고 있습니다. 극단적으로 Java언어의 Checked Exception 도입 자체가 실패라고 주장하는 사람도 많습니다. Thinking in Java의 저자인 Bruce Eckel도 그 중 한 사람입니다. &nbsp;Spring framework의 아버지 Rod Johnson도 Checked Exception이 쓰여야 할 때도 있지만&nbsp;그 것이 과도하게 선호되어 온 것은 지적하고 있습니다.</p><p>&nbsp; 어쨓든 Exception 부분은 Java로 API 설계와 코딩를 할 때 가장 어려운 부분이라고 느껴집니다. Java 아키텍트와 개발팀의 실력을 측정하는 좋은 방법은 그들이 만든 Exception 처리 코드를 보라는 말까지 있으니까요.</p><p>&nbsp;</p><h4>&nbsp;Exception 처리&nbsp;방식 참고자료</h4><p><a class="external" title="Exception Handling" href="http://lastmind.net/blog/2007/11/exception-handling.html"></a></p><ul><li><p><span style="FONT-FAMILY: 굴림"><a class="external" title="Effective Java" href="http://www.yes24.com/Goods/FTGoodsView.aspx?goodsNo=363730&amp;CategoryNumber=001001003016003014">Effective Java</a></span>&nbsp; 중&nbsp;Chapter 8 (Item 39~47)</p><ul><li><a class="wiki" title="Effective Java ch8" href="http://benelog.springnote.com/pages/1213602">8장 예외처리</a> 페이지에 정리해 놓았습니다.</li></ul></li></ul><p>&nbsp;</p><ul><li><p><span style="FONT-FAMILY: 굴림"><a class="external" title="Expert One-on-One J2EE Design and Development" href="http://www.amazon.ca/Expert-One-One-Design-Development/dp/customer-reviews/0764543857">Expert One-on-One J2EE Design and Development</a>&nbsp;중 Chapter 4 Design Techniques and Coding Standards for J2EE Projects, Exception Handling 부분</span></p><ul><li>alternative return value가 있는 경우에는 Checked exception</li><li>data connection 생성 실패와 같이 뭔가 크게 잘못 되고 있어서 호출한 쪽에서 아무도 이를 처리할 수 없을 때는 Runtime exception.</li><li>소수의 호출자만이 Exception을 받아서 처리해야 할 때도 Runtime exception.</li><li>불명확하면 Runtime exception.</li><li><a class="external" title="http://blog.naver.com/haruma95/80050223953" href="http://blog.naver.com/haruma95/80050223953"><span style="COLOR: #810081">checked Exception과 Runtime exception</span></a>&nbsp;페이지에서 일부 내용이 번역되어 있습니다.</li><li><a class="external" title="http://www.yes24.com/Goods/FTGoodsView.aspx?goodsNo=1943792&amp;CategoryNumber=001001003016003012" href="http://www.yes24.com/Goods/FTGoodsView.aspx?goodsNo=1943792&amp;CategoryNumber=001001003016003012">Spring 프레임웍크 워크북</a>&nbsp;(박재성 저) 88쪽에도&nbsp;인용되어 있는 원칙입니다.</li></ul></li></ul><p>&nbsp;</p><ul><li><p>Barry Ruzek의&nbsp; <a href="http://dev2dev.bea.com/pub/a/2006/11/effective-exceptions.html"><span style="COLOR: #5a5194">EFFECTIVE JAVA EXCEPTIONS</span></a></p><ul><li>Fault Handling(Unplanned condition)에는 RuntimeException, Contingency(Expected condition, alternative method result)에는 return type, exception, error code 등의 전략을 사용</li><li>Fault를 한곳에서 잡아서 처리하는 Fault barrier pattern 사용 권장. Struts라면 org.apache.struts.action.ExceptionHandler, SpringMVC라면 SimpleMappingExceptionResolver</li><li>AOP 적용이 도움이 될 수도 있음.</li><li>황상철님의 블로그 <a class="external" title="http://moai.tistory.com/322" href="http://moai.tistory.com/322">Effective Java Exceptions 발표자료</a>&nbsp;페이지에서&nbsp;이 내용이 요약된 pdf 파일을 받을 수 있습니다.&nbsp;(<a class="external" title="http://moai.tistory.com/attachment/dk180000000000.pdf" href="http://moai.tistory.com/attachment/dk180000000000.pdf"><span style="COLOR: #0000ff">effective java exceptions.pdf</span></a>&nbsp;)</li></ul></li></ul><p>&nbsp;</p><ul><li><p>Jim Cushing&nbsp;&nbsp;<a class="external" title="http://today.java.net/pub/a/today/2003/12/04/exceptions.html" href="http://today.java.net/pub/a/today/2003/12/04/exceptions.html"><span style="COLOR: #810081">Three Rules for Effective Exception Handling</span></a></p><ul><li>&nbsp;Be specific, Throw Early, Catch Late의 3가지 원칙을 제시하고 있습니다.</li></ul></li></ul><p>&nbsp;</p><ul><li><p><a class="external" title="http://www.manageability.org/blog/stuff/exceptional-exception-handling-techniques/view" href="http://www.manageability.org/blog/stuff/exceptional-exception-handling-techniques/view">13 Exceptional Exception Handling Techniques</a></p><ul><li>Checked Exception을 RuntimeException으로 감싸기, throws 절에 RuntimeException이라도 선언해주기 등의 기법을 추천하고 있습니다.</li></ul></li></ul><p>&nbsp;</p><ul><li><p>Gunjan Doshi의&nbsp;<a class="external" title="http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html" href="http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html"><span style="COLOR: #810081">Best Practices for Exception Handling</span></a></p><ul><li>Client code가 할 일이 있을 때는 checked,&nbsp;없을 때는 unchecked.&nbsp;progamming error에는&nbsp;unchecked exception.</li><li>적절한&nbsp;캡슐화. 비지니스 layer에서&nbsp;SqlException을 던지지 말것.</li></ul></li></ul><p>&nbsp;</p><ul><li><p>Rob Walling의 Exception Handling에 관한 글&nbsp;<a class="external" title="http://www.softwarebyrob.com/2007/08/27/two-fundamental-no-frills-square-one-rules-exception-handling/" href="http://www.softwarebyrob.com/2007/08/27/two-fundamental-no-frills-square-one-rules-exception-handling/"><span style="COLOR: #0000ff">The Two Fundamental, No Frills, Square One Rules of Exception Handling</span></a></p><ol><li>에러메시지에 도움이 되는 정보를 더할 수 없다면, Exception을 잡지마라, 2. Exception을 잡았으면 기록하라." 두가지 원칙을 말하고제시하고 있습니다.</li></ol></li></ul><p>&nbsp;</p><ul><li><p>Alan Griffiths의 <a class="external" title="http://www.octopull.demon.co.uk/java/ExceptionalJava.html" href="http://www.octopull.demon.co.uk/java/ExceptionalJava.html"><span style="COLOR: #0066cc">Exceptional Java</span></a></p><ul><li>이 주제에 대해 비교적 초기에 나온 글로써,&nbsp;다른 글에도 많이 인용되고&nbsp;있습니다.</li><li>Exception 처리에 대한 전통적인 원칙이 캡슐화 저해, 정보손실,&nbsp;정보 과적의 문제를 일으킨다고 이야기합니다.</li><li>public&nbsp;메소드에서&nbsp;던지는 Exception은 해당 패키지에 소속된 클래스일것,&nbsp;다른 패키지에서는 이를 부를 때를 Exception을 전파시키지 말고&nbsp;그 패키지의&nbsp;Exception으로 감쌀 것을 추천하고 있습니다.</li></ul></li></ul><p>&nbsp;</p><ul><li><p><a class="external" title="http://www.onjava.com/pub/a/onjava/2006/01/11/exception-handling-framework-for-j2ee.html?page=1" href="http://www.onjava.com/pub/a/onjava/2006/01/11/exception-handling-framework-for-j2ee.html?page=1"><span style="COLOR: #810081">An Exception Handling Framework for J2EE Applications</span></a></p><ul><li>&nbsp;J2EE application에서의 Exception처리 전략에 대해서 설명하고 있습니다.</li></ul></li></ul><p>&nbsp;</p><h4>Checked Exception에 대한 부정적 견해를 정리한 글</h4><ul><li><p>Brian Goetz의 글: <a class="external" title="http://www.ibm.com/developerworks/java/library/j-jtp05254.html" href="http://www.ibm.com/developerworks/java/library/j-jtp05254.html">Java theory and practice: The exceptions debate</a></p><ul><li><p>Bruce Eckel, Rod Johnson, Joshua Bloch등의 주장을 정리해 놓은 글입니다. Checked Exception이 상세한 구현을 부적절하게 노출함,불안정한 메소드 시그너처,읽기힘든 코드,Exception 삼키기,너무 많은 Exception wrapping의 문제점 있는 것을 나열하고 있습니다. unchecked exception은 Documentation이 더욱 중요하다고 강조하고 있습니다.</p></li></ul></li></ul><p>&nbsp;</p><ul><li><p>Rod Waldhoff의 글 : <a class="external" title="http://radio.weblogs.com/0122027/stories/2003/04/01/JavasCheckedExceptionsWereAMistake.html" href="http://radio.weblogs.com/0122027/stories/2003/04/01/JavasCheckedExceptionsWereAMistake.html">Java's checked exceptions were a mistake</a></p><ul><li>Java의 Exception Handling은 실패한 실험이라고 주장하는 내용입니다. Checked Exception방식은 일부 low level에서만 의미가 있다고 말합니다.</li></ul></li></ul><p>&nbsp;</p><ul><li><p>Bruce Eckel의 견해(Thinking in Java의 저자): <a class="external" title="http://www.mindview.net/Etc/Discussions/CheckedExceptions" href="http://www.mindview.net/Etc/Discussions/CheckedExceptions">Does Java need Checked Exceptions?</a></p><ul><li>Error report 방식을 통일했다는 점에서는 의미가 있지만, 오히려 개발자들이 Exception을 그냥 삼키는 코드를 많이 짜게 하는 결과가 생겼다고 지적합니다.</li></ul></li></ul><p>&nbsp;</p><ul><li><p>Bill Venners(C#의 아키텍트)와 Bruce Eckel의 인터뷰 : <a class="external" title="http://www.artima.com/intv/handcuffs.html" href="http://www.artima.com/intv/handcuffs.html">The Trouble with Checked Exceptions</a></p><ul><li>versioning, scalability의 문제 때문에 C#에 &nbsp;Checked Exception이 도입되지 않았다고 밝히고 있습니다.</li></ul></li></ul><h4><u><span style="COLOR: #568942"><a class="external" title="http://www.theserverside.com/news/thread.tss?thread_id=19192" href="http://www.theserverside.com/news/thread.tss?thread_id=19192"></a></span></u><a class="external" title="http://blog.naver.com/haruma95/80050223953" href="http://blog.naver.com/haruma95/80050223953"><span style="COLOR: #810081"><br></span></a>Checked Exception에 대한 논의가 진행된 페이지</h4><ul><li><a class="external" title="http://www.c2.com/cgi/wiki?JavaExceptionsAreParticularlyEvil" href="http://www.c2.com/cgi/wiki?JavaExceptionsAreParticularlyEvil">Java Exceptions Are Particularly Evil</a></li><li><a class="external" title="http://www.c2.com/cgi/wiki?CheckedExceptionsAreOfDubiousValue" href="http://www.c2.com/cgi/wiki?CheckedExceptionsAreOfDubiousValue">Checked Exceptions Are Of Dubious Value</a></li><li><u><span style="COLOR: #568942"><a class="external" title="http://www.theserverside.com/news/thread.tss?thread_id=19192" href="http://www.theserverside.com/news/thread.tss?thread_id=19192"></a></span></u><a class="external" title="http://www.c2.com/cgi/wiki?ExceptionTunneling" href="http://www.c2.com/cgi/wiki?ExceptionTunneling">Exception Tunneling</a></li><li><u><span style="COLOR: #568942"><a class="external" title="http://www.theserverside.com/news/thread.tss?thread_id=19192" href="http://www.theserverside.com/news/thread.tss?thread_id=19192">Opinion: The Eternal Debate on Checked Exceptions</a></span></u>&nbsp;: theserverside에서 벌어진 논쟁</li></ul><p>&nbsp;</p><h4>이클립스 Exception처리 코드 템플릿 관련 자료</h4><ul><li><a class="external" title="Exception Handling" href="http://lastmind.net/blog/2007/11/exception-handling.html">Exception Handling</a></li><li><a class="external" title="http://whiteship.tistory.com/1612" href="http://whiteship.tistory.com/1612">이클립스의 기본 try-catch 탬플릿 비추</a></li></ul>			 ]]> 
		</description>
		<category>기술 자료</category>
		<pubDate>Thu, 22 May 2008 22:58:13 GMT</pubDate>
		<dc:creator>정상혁</dc:creator>
	</item>
	<item>
		<title><![CDATA[ JDBC에서 Connection, Statement,ResultSet의 close ]]> </title>
		<link>http://benelog.egloos.com/1898928</link>
		<guid>http://benelog.egloos.com/1898928</guid>
		<description>
			<![CDATA[ 
  <p>이미&nbsp;많이 알려진 내용이지만, 아직도&nbsp;문제를 많이 일으키는 주제입니다. 그래서 보다&nbsp;이 주제를 검색엔진에서 쉽게&nbsp;찾을 수 있었으면 하는 마음에서 이 글을 정리해봤습니다.</p><p>&nbsp;</p><blockquote><p>&nbsp; Connection conn = null;<br>&nbsp; PreparedStatement pstmt = null;<br>&nbsp; ResultSet rs = null; // &lt;---- !!!<br>&nbsp; try{<br>&nbsp;&nbsp;&nbsp;&nbsp; conn = ...&lt;getConnection()&gt;...;<br>&nbsp;&nbsp;&nbsp;&nbsp; pstmt = conn.prepareStatement("select .....");<br>&nbsp;&nbsp;&nbsp;&nbsp; rs = pstmt.executeQuery(); // &lt;----- !!!<br>&nbsp;&nbsp;&nbsp;&nbsp; while(rs.next()){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......<br>&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp; }&nbsp; catch(Exception e){<br>&nbsp;&nbsp;&nbsp;&nbsp; ....<br>&nbsp; }&nbsp; finally {<br>&nbsp;&nbsp;&nbsp;&nbsp; if ( rs != null ) try{rs.close();}catch(Exception e){}&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; if ( pstmt != null ) try{pstmt.close();}catch(Exception e){}<br>&nbsp;&nbsp;&nbsp;&nbsp; if ( conn != null ) try{conn.close();}catch(Exception e){}</p><p>&nbsp;}</p></blockquote><p>&nbsp;</p><p>&nbsp; 이것이 JDBC API 사용시에 권장되는 코딩방식입니다. 코드는 참조자료에 있는 이원영님의 글에서 인용했습니다.</p><p>&nbsp;JDBC 스펙을 찾아보면 Statement가 닫힐 때 ResultSet은 닫히고, Connection이 닫히면 Statement도 닫힌다고 되어 있습니다. 하지만 Staement close 시에 Exception이 발생한다면 이것이 따로 Exception을 catch되지 않고서는 뒤에 Connection을 닫는&nbsp;코드가 실행되지 않습니다. 그리고 Connection pool에서 얻어온 Connection객체는 connection.close()로 처리하는 것이 pool로의 반환을 의미하는 것이지 실제로 connetion을 close하는 것이 아니기 때문에 Statement까지 닫아준다고 장담할 수 없습니다. ResultSet의 경우도 WAS에도 제공하는 Statement cache 기능 때문에 명시적으로 close해주는 것이 확실한 자원해제를 보장할 수 있습니다.</p><p>&nbsp;&nbsp;DBMS에서 "maximum open cursor exceed !" 나 "Limit on number of statements exceeded " 에러를 내고 있다면 위와 같이 코딩했는지 한번 확인해보시기 바랍니다.</p><p>&nbsp; 각 벤더별 드라이버의 구현이나 WAS의 Connection Pool의 구현등에 따라서 저 정도까지 안 해도 문제가 안 생길 수도&nbsp;있습니다. 그리고 독립적으로 돌아가는 배치프로그램이나 커넥션풀을 쓰지 않는 경우에는 보다 덜 엄격해도 될 때도 있습니다.&nbsp; 그래도 어떠한 경우에도 안심하고 있을만한 코드는 위와 같은 구조입니다.</p><p>&nbsp; javaservice.net에서 이원영님이 처음에 이 문제에 대한 글을 쓰신것이 2000년 9월입니다. 그래서&nbsp; 많은 분들이 알고 계시지만 그래도 정말 반복적으로 만나게 되는 문제입니다.&nbsp; 저의 경험이 편향된지도 모르겠지만, 지금까지 제가 만났던 JDBC AP를 그대로 쓰는 개발팀은 세 팀이였었는데, 모두 이렇게 코딩하지 않을 경우 문제가 생길 가능성이 있다는 것을 모르고 있었습니다. 결국 그 중 한 팀은 시스템 전체를 몇 일동안 매시간마다 재부팅시키게 만들게 했었습니다.</p><p>&nbsp; 미국의 모 대형항공사의 예약시스템을 3시간동안 멈춘 코드도&nbsp;위와 같은 방식을 따르지 않았었습니다.&nbsp;finally절이 다음과 같았다고 합니다.</p><blockquote><p>}finally{</p><p style="MARGIN-LEFT: 2em">if (stmt!=null) stmt.close();</p><p style="MARGIN-LEFT: 2em">if (conn!=null) conn.close();</p><p>}</p></blockquote><p>&nbsp;그 예약 시스템은 이중화된 DB로 구성되어 있었고, 그 DB들은 가상IP주소로 어플리케이션과 연결되어 있었습니다.&nbsp; 정기 점검을 위해 DB중 하나를 수동&nbsp; fail-over 시키는 순간 내려간 DB의 JDBC연결에서 나온 statement객체의 close문장은 Exception을 일으켰습니다. 이 문장은&nbsp;별도로&nbsp;catch 되지 않았기 때문에 그 다음의 conn.close()는 실행되지 않았습니다. 결국 이 때문에 반환되지 않은 Connection 자원들로 인해 리소스 풀은 곧 바닥이 났습니다. 그 후에 새로 Connection을 얻고자 하는 다른 프로그램들은 블록되어서 전체 시스템을 멈추었습니다.</p><p>&nbsp;아마도 JDBC API를&nbsp;쓰는 곳에는 언제나 생길 수 있는 문제일 것입니다. 좋은 API는 문서를 안 보고 자연스럽게 써도 사용하기 쉽고 문제를 안 일으키는 것일텐데, JDBC는 제대로 사용하기가 오히려 더 어려운 API입니다. 위의 항공사 사건 같이 전 세계에서 JDBC로 인해 야기된&nbsp;장애,생산성 저하를 다 따져본다면, 가히 이 API가 인류에게 끼친 해악이 엄청나다는 생각까지도 듭니다. &nbsp;요즘은 Framework 기반 개발로 JDBC를 직접 안 쓰는 것이 이런 점에서는 다행입니다.</p><p>&nbsp;</p><p>&nbsp; JDBC API에서 대표적으로 지적받는 문제점은 Checked Exception을 남발했다는 것입니다. catch 절에서 아무 것도 하지 않는 것은 바람직하지 않은 코딩이지만&nbsp;JDBC API에서는 정말 할 것이 없습니다. 그래서 이런 문제점을 알고서 그 후에&nbsp;나온&nbsp;JDBC를 활용한 API들,&nbsp;Spring의 <a class="external" title="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/jdbc/core/JdbcTemplate.html" href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/jdbc/core/JdbcTemplate.html">JdbcTemplet</a>, <span style="FONT-FAMILY: 굴림"><a class="external" title="http://www.hibernate.org/" href="http://www.hibernate.org/">Hibernate</a>의 &nbsp;<a class="external" title="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Query.html" href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Query.html">Query</a> 인터페이스,&nbsp; <a class="external" title="http://en.wikipedia.org/wiki/Java_Persistence_API" href="http://en.wikipedia.org/wiki/Java_Persistence_API">JPA</a></span><span style="FONT-FAMILY: 굴림">의&nbsp;<a class="external" title="http://java.sun.com/javaee/5/docs/api/javax/persistence/Query.html" href="http://java.sun.com/javaee/5/docs/api/javax/persistence/Query.html">Query</a>&nbsp;인터페이스, <a class="external" title="http://java.sun.com/jdo/" href="http://java.sun.com/jdo/">JDO</a>의 <a class="external" title="http://db.apache.org/jdo/api21/apidocs/javax/jdo/Query.html" href="http://db.apache.org/jdo/api21/apidocs/javax/jdo/Query.html">Query</a>&nbsp;인터페이스에서는</span> Checked Exception인 SqlException을 볼 수 없게 설계되어 있습니다.</p><p>&nbsp; 그리고 JDBC에서는&nbsp;접속에러, 쿼리에러, 제약조건 에러 등 다양한 원인으로 생기는 Exception을 SqlException 1개로 다 때우는 문제도 있습니다. Spring에서는 이것을 더 섬세하게 구분한 &nbsp;Exception들을 정의를 하고 있습니다. <a class="external" title="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/dao/DataAccessException.html" href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/dao/DataAccessException.html">DataAccessException</a>의 하위 클래스를 보면&nbsp;&nbsp;<a class="external" title="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/dao/CleanupFailureDataAccessException.html" href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/dao/CleanupFailureDataAccessException.html">CleanupFailureDataAccessException</a>, <a class="external" title="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/dao/DataIntegrityViolationException.html" href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/dao/DataIntegrityViolationException.html">DataIntegrityViolationException</a>, <a class="external" title="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/dao/DataRetrievalFailureException.html" href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/dao/DataRetrievalFailureException.html">DataRetrievalFailureException</a>&nbsp;등이 보입니다.</p><p>&nbsp;</p><p>&nbsp; <a class="external" title="http://benelog.egloos.com/1901121" href="http://benelog.egloos.com/1901121">Java의 Checked Exception 처리 문제에 관한 글</a>은 따로 정리했습니다.</p><p>&nbsp;</p><h4>미국 항공사 장애 사건 관련 참고자료</h4><p><a class="external" title="http://www.yes24.com/Goods/FTGoodsView.aspx?goodsNo=2753365&amp;CategoryNumber=001001003016002003" href="http://www.yes24.com/Goods/FTGoodsView.aspx?goodsNo=2753365&amp;CategoryNumber=001001003016002003">Release It 릴리스 잇 : 성공적인 출시를 위한 소프트웨어 설계와 배치</a> &nbsp;(마이클 나이가드 저/신승환,정태중 역, 위키북스)</p><p style="MARGIN-LEFT: 2em">2장 사례연구 : 항공사를 정지시킨 예외(Exception) 사건</p><p>&nbsp;</p><h4>JDBC 관련 참고자료</h4><p>&nbsp;Javaservice.net에 이원영님이 올린 글</p><ul><li><a class="external" title="http://www.javaservice.net/~java/bbs/read.cgi?m=devtip&amp;b=servlet&amp;c=r_p&amp;n=968185187&amp;k=JDBC&amp;d=tb" href="http://www.javaservice.net/~java/bbs/read.cgi?m=devtip&amp;b=servlet&amp;c=r_p&amp;n=968185187&amp;k=JDBC&amp;d=tb">서블렛 + JDBC 연동시 코딩 고려사항 -제1탄-</a></li><li><p><a class="external" title="http://www.javaservice.net/~java/bbs/read.cgi?m=devtip&amp;b=servlet&amp;c=r_p&amp;n=968522077" href="http://www.javaservice.net/~java/bbs/read.cgi?m=devtip&amp;b=servlet&amp;c=r_p&amp;n=968522077">서블렛 + JDBC 연동시 코딩 고려사항 -제2탄-</a></p><p>&nbsp;</p></li></ul><p>같은 내용으로 zdnet에 올라온 글</p><ul><li><a class="external" title="http://www03.zdnet.co.kr/news/enterprise/0,39031021,10048177,00.htm" href="http://www03.zdnet.co.kr/news/enterprise/0,39031021,10048177,00.htm">서블렛 + JDBC 연동시 코딩 고려사항 4</a></li><li><a class="external" title="http://www03.zdnet.co.kr/news/enterprise/0,39031021,10048192,00.htm" href="http://www03.zdnet.co.kr/news/enterprise/0,39031021,10048192,00.htm">서블렛 + JDBC 연동시 코딩 고려사항 5</a></li><li><a class="external" title="http://www.zdnet.co.kr/builder/dev/java/0,39031622,10048223,00.htm" href="http://www.zdnet.co.kr/builder/dev/java/0,39031622,10048223,00.htm">서블렛 + JDBC 연동시 코딩 고려사항 6</a></li></ul>			 ]]> 
		</description>
		<category>기술 자료</category>
		<pubDate>Wed, 21 May 2008 11:38:35 GMT</pubDate>
		<dc:creator>정상혁</dc:creator>
	</item>
	<item>
		<title><![CDATA[ Digester를 이용한 Naver Open API Java Client 모듈 ]]> </title>
		<link>http://benelog.egloos.com/1891482</link>
		<guid>http://benelog.egloos.com/1891482</guid>
		<description>
			<![CDATA[ 
  <p>&nbsp;</p><p>네이버&nbsp;Open API Cafe에서 검색 API의 Java Client 모듈을 보게 되었습니다.</p><p><a class="external" title="http://cafe.naver.com/ArticleRead.nhn?clubid=11906219&amp;amp;amp;page=1&amp;amp;amp;menuid=3&amp;amp;amp;boardtype=L&amp;amp;amp;articleid=1372" href="http://cafe.naver.com/ArticleRead.nhn?clubid=11906219&amp;amp;amp;page=1&amp;amp;amp;menuid=3&amp;amp;amp;boardtype=L&amp;amp;amp;articleid=1372">http://cafe.naver.com/ArticleRead.nhn?clubid=11906219&amp;amp;amp;page=1&amp;amp;amp;menuid=3&amp;amp;amp;boardtype=L&amp;amp;amp;articleid=1372</a></p><p><a href="http://insford.tistory.com/116">http://insford.tistory.com/116</a></p><p>위의&nbsp;모듈을 참고해서&nbsp;같은 역할을 하는 모듈을&nbsp;다르게 구현해봤습니다.</p><p>&nbsp;</p><p>특징은 아래와 같습니다.</p><ul><li>&nbsp;RSS를 파싱하는 부분을&nbsp;XML parsing API로 널리 알려진 Digester(<a href="http://commons.apache.org/digester/">http://commons.apache.org/digester/</a>)를 사용했습니다. Digester의 예제 코드로 제공되는 RSS파싱모듈을 그대로 써서 짧은 코드로 파싱이 가능했습니다. 사용한 모듈의 API문서는 다음의 링크에서 볼 수 있습니다.</li></ul><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (<a class="external" title="http://commons.apache.org/digester/commons-digester-1.5/docs/api/org/apache/commons/digester/rss/RSSDigester.html" href="http://commons.apache.org/digester/commons-digester-1.5/docs/api/org/apache/commons/digester/rss/RSSDigester.html">RSSDigester</a>&nbsp;, <a class="external" title="http://commons.apache.org/digester/commons-digester-1.5/docs/api/org/apache/commons/digester/rss/Channel.html" href="http://commons.apache.org/digester/commons-digester-1.5/docs/api/org/apache/commons/digester/rss/Channel.html">Channel</a>&nbsp;, <a class="external" title="http://commons.apache.org/digester/commons-digester-1.5/docs/api/org/apache/commons/digester/rss/Item.html" href="http://commons.apache.org/digester/commons-digester-1.5/docs/api/org/apache/commons/digester/rss/Item.html">Item</a>)</p><ul><li>요청 파라미터를 담는 클래스를 따로 뺐습니다.&nbsp;&nbsp;(RequestParameter.java) 이중 Target 값은 (blog, news 등 검색할 컨텐츠 유형을 선택하는 파라미터입니다.) enum으로 해서 정해진 값이 아닐 경우 compile이 안 되게 했습니다.</li><li><p>open&nbsp;API&nbsp;key값은 필수값이므로 OpenApiClient클래스의 생성자의 파라미터로 받았습니다.&nbsp;대신&nbsp;키 값이 없이 이 객체가 생성될 수 없도록 default 생성자는 private으로 돌려놨습니다.</p></li></ul><p>&nbsp;</p><p>첨부한 파일은 이클립스에서 Dynamic Web&nbsp;Project로 생성한 폴더를 압축한 것입니다.&nbsp;테스트 실행 서버는 Tomcat 5.5를 사용했습니다. Eclipse WTP가 설치되어&nbsp;있는 환경이면 실행이 가능합니다. 그리고 enum을 썼기에 Java5이상이어야&nbsp;합니다.</p><p>&nbsp;</p><p>Open API에 대한 자세한 사용법은&nbsp;<a href="http://openapi.naver.com/index.nhn">http://openapi.naver.com/index.nhn</a>&nbsp;를 참조하시면 됩니다.</p><p>&nbsp;</p><h4>소스코드</h4><p>전체&nbsp;소스와 라이브러리 다운받기 : <a class="attachment" title="openApiTest.zip" href="http://benelog.springnote.com/pages/1188470/attachments/517706"><span style="COLOR: #0000ff">openApiTest.zip</span></a>&nbsp;</p><p>&nbsp;</p><blockquote><p>package openapiclient;</p><p>import java.io.InputStream;<br>import java.io.UnsupportedEncodingException;<br>import java.net.MalformedURLException;<br>import java.net.URL;<br>import java.net.URLEncoder;</p><p>import org.apache.commons.digester.rss.Channel;<br>import org.apache.commons.digester.rss.RSSDigester;</p><p>public class NaverSearchClient {<br>&nbsp;<br>&nbsp;private static final String OPEN_API_URL = "<a href="http://openapi.naver.com/search">http://openapi.naver.com/search</a>";<br>&nbsp;private String key;<br>&nbsp;<br>&nbsp;@SuppressWarnings("unused")<br>&nbsp;private NaverSearchClient(){};<br>&nbsp;<br>&nbsp;public NaverSearchClient(String key){<br>&nbsp;&nbsp;this.key = key;<br>&nbsp;}<br>&nbsp;public Channel search(RequestParameter param) throws Exception{<br>&nbsp;&nbsp;RSSDigester digester = new RSSDigester();<br>&nbsp;&nbsp;URL requestUrl = getRequestUrl(param);<br>&nbsp;&nbsp;InputStream is = requestUrl.openConnection().getInputStream();<br>&nbsp;&nbsp;return (Channel) digester.parse(is);<br>&nbsp;}</p><p>&nbsp;private URL getRequestUrl(RequestParameter param)&nbsp;throws UnsupportedEncodingException, MalformedURLException {<br>&nbsp;&nbsp;StringBuffer serverUrl = new StringBuffer(OPEN_API_URL);<br>&nbsp;&nbsp;serverUrl.append("?target=" + param.getTarget());<br>&nbsp;&nbsp;serverUrl.append("&amp;key=" + key);<br>&nbsp;&nbsp;serverUrl.append("&amp;start=" + param.getStart());<br>&nbsp;&nbsp;serverUrl.append("&amp;display=" + param.getDisplay());<br>&nbsp;&nbsp;serverUrl.append("&amp;query=" + URLEncoder.encode(param.getQuery(), "UTF-8"));<br>&nbsp;&nbsp;if(param.getSort()!=null) serverUrl.append("&amp;sort=" + param.getSort());<br>&nbsp;&nbsp;return new URL(serverUrl.toString());<br>&nbsp;}<br>}</p></blockquote><p>&nbsp;</p><p>&nbsp;</p><blockquote><p>&nbsp;package openapiclient;</p><p>public class RequestParameter {<br>&nbsp;<br>&nbsp;public enum Category{<br>&nbsp;&nbsp;KIN,BLOG,CAFE,DOC,WEBKR,BOOK, SHOP, ENCYC,<br>&nbsp;&nbsp;KRDIC, JPDIC, ENDIC, NEWS, LOCAL, VIDEO,IMAGE;&nbsp;&nbsp;<br>&nbsp;&nbsp;public String toString(){<br>&nbsp;&nbsp;&nbsp;return super.toString().toLowerCase();<br>&nbsp;&nbsp;}<br>&nbsp;}</p><p>&nbsp;private Category target;<br>&nbsp;private String sort;<br>&nbsp;private int start;<br>&nbsp;private int display;<br>&nbsp;private String query;</p><p>&nbsp;// getter and setters 생략<br>&nbsp;}</p></blockquote><p>&nbsp;</p><h4>JSP에서 사용한 예제</h4><p>JSTL을 함께 사용해서 찍어본 예제입니다. <a href="http://openapi.naver.com/index.nhn">http://openapi.naver.com/index.nhn</a> 에 가셔서 API key를 발급 받으시고 소스 중간에 밑줄로 표시된 부분에 그 값을 넣으시고 돌려주시면 됩니다.</p><blockquote><p>&lt;%@ page language="java" contentType="text/html; charset=EUC-KR"&nbsp;&nbsp; pageEncoding="EUC-KR"%&gt;<br>&lt;%@ taglib prefix="c" uri="<a href="http://java.sun.com/jsp/jstl/core">http://java.sun.com/jsp/jstl/core</a>" %&gt;<br>&lt;%@ page import="openapiclient.RequestParameter" %&gt;<br>&lt;%@ page import="openapiclient.NaverSearchClient" %&gt;<br>&lt;%@ page import="org.apache.commons.digester.rss.Channel" %&gt;<br>&lt;%<br>&nbsp;<strong><u>String KEY = "????"; // Open API key값을 넣으세요</u></strong><br>&nbsp;NaverSearchClient client = new NaverSearchClient(KEY);<br>&nbsp;RequestParameter param = new RequestParameter();<br>&nbsp;param.setDisplay(10);<br>&nbsp;param.setStart(1);<br>&nbsp;param.setQuery("미역국");<br>&nbsp;param.setTarget(RequestParameter.Category.NEWS);<br>&nbsp;Channel result = client.search(param);<br>&nbsp;result.render(System.out); // 콘솔에 받아온 내용을 확인삼아 찍어봄<br>&nbsp;request.setAttribute("result", result);<br>%&gt;<br>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<a href="http://www.w3.org/TR/html4/loose.dtd">http://www.w3.org/TR/html4/loose.dtd</a>"&gt;<br>&lt;html&gt;<br>&lt;head&gt;<br>&lt;meta http-equiv="Content-Type" content="text/html; charset=EUC-KR"&gt;<br>&lt;title&gt;Naver Open API를 이용한 검색&lt;/title&gt;<br>&lt;/head&gt;<br>&lt;body&gt;<br>&lt;c:forEach var='item' items='${result.items}'&gt;<br>&nbsp; &lt;p&gt;<br>&nbsp; &lt;a href="${item.link}"&gt; ${item.title} &lt;/a&gt; &lt;br/&gt;<br>&nbsp; ${item.description}<br>&nbsp; &lt;/p&gt;<br>&lt;/c:forEach&gt;<br>&lt;/body&gt;<br>&lt;/html&gt;</p></blockquote><p>&nbsp;</p><h4>실행결과화면</h4><p>&nbsp; <img class="attachment" title="openApiClient.JPG" alt="openApiClient.JPG" src="http://benelog.springnote.com/pages/1188470/attachments/517718"> <span class="xquared_marker" id="xquared_marker_0"></span></p>			 ]]> 
		</description>
		<category>코드,그냥 재미로</category>
		<pubDate>Fri, 16 May 2008 08:22:09 GMT</pubDate>
		<dc:creator>정상혁</dc:creator>
	</item>
	<item>
		<title><![CDATA[ batch job에서의 바람직한 트랜잭션 처리 방식 ]]> </title>
		<link>http://benelog.egloos.com/1889589</link>
		<guid>http://benelog.egloos.com/1889589</guid>
		<description>
			<![CDATA[ 
  <p>&nbsp;일반적인 온라인 어플리케이션에서는 사용자가 보내는 event 한번에 하나의 트랜잭션을 묶어서 처리합니다. 하지만 배치처리에서는 하나의 처리가 하나의 트랜잭션으로 관리되는 것은 때로는 문제가 될 수 있습니다.</p><p>&nbsp;몇 만 건 이상의 행과 같이 대용량 데이터를 다루는 경우에는 roll back segment 같은 공간의 부족현상이 생길 수도 있습니다. 그리고 상대적으로 긴 처리 시간동안 DB에 lock을 걸리게 해서 전체 시스템에 병목을 만들 수도 있습니다. 사용자가 많은 웹어플리케이션이 동시에 접근하는 DB에서 배치처리를 돌릴 때는 이를 더 염두에 두어야 할 것입니다.</p><p>&nbsp; 또, 데이터가 건마다 독립성을 가지고 있는 경우라면 한 두건의 처리실패 때문에 앞에 성공한 건들도 다 Roll back이 되어버린다면 더 많은 건의 데이터가 의도하지 않은 상태로 오래 유지될 수 있습니다. 배치처리의 에러가 발생 즉시 해결되지 않을 수도 있기 때문에 때문에 업무 규칙상으로 가능한 경우라면 부분적으로 성공한 건이라도 DB에 반영되는 것이 좋을 것입니다. 그렇지 않을 경우에 재시도시에 다시&nbsp;모든 데이터를 처리해야 하니 그 처리시간이 더 길어지는 단점도 있습니다.</p><p>&nbsp; 그렇다고 해서 데이터 매 건마다 따로 트랜잭션 처리를 하는 것도 성능상 좋지 못합니다. 트랜잭션을 시작하고 끝낼 때 드는 비용도 감안해야 되기 때문입니다.</p><p>&nbsp; 따라서 일정한 행 단위를 묶어서 처리를 하는 것이 배치처리에서는 더 바람직한 방식이라고 할 수 있습니다.</p><p>&nbsp; WebSphere XD Compute Grid에서는 check-point algorithm을 time-based와 record-based 두 가지 방식으로 제공해서 이런 문제에 대한 해결책을 제시하고 있습니다.<br>&nbsp; Spring batch에서는 ItemOrientedStep 클래스에서 commitInterval이라는 속성으로 주기적인 commit방식을 지원합니다. 데이터 특성이나 업무규칙에 따라서 적절한 값을 트랜잭션 단위로 묶이는 건수를 설정으로 지정할 수 있는 것입니다.</p><p>&nbsp;</p><h5>참고자료 1</h5><p><a class="external" title="http://www.devx.com/Java/Article/20791/1763/page/1" href="http://www.devx.com/Java/Article/20791/1763/page/1">High-volume Transaction Processing in J2EE</a>&nbsp;:</p><p>세번째 페이지의 Job Partitioning and Chunking 단락에서 아래와 같이 설명하고 있습니다.</p><p>&nbsp;</p><blockquote><p>Running your job as one long-lived transaction isn't a good idea. Long-lived transactions are more fragile than short-lived transactions. They are more susceptible to errors and DBMS locking problems because the locks are held longer. Smaller chunks are more reliable and less likely to exceed your connection and session timeouts.</p></blockquote><p>&nbsp;</p><h5>참고자료2</h5><p><a class="external" title="http://www.speakeasy.org/~jwilton/oracle/dedicated-rbs.html" href="http://www.speakeasy.org/~jwilton/oracle/dedicated-rbs.html">Misconception: Big batch jobs should use a ‘dedicated’ rollback segment</a>&nbsp;:</p><p>Oracle의 경우를 설명한 글입니다. DBA들이 보통 긴 transaction을 유지하는 batch job에 전용 role back segment를 할당하는데 실제로는 이것이 별도움이 못 된다고 말합니다. 결국 다른 session들이 사용할 수 있는 roll back segment를 사용하는 것은 똑같기 때문에 ORA-01555 에러를 유발할 수 있다고 합니다.&nbsp;결국 보다 작은 transaction 단위를 가지고 가는 것이 근본적인 해결책입니다.</p><p>&nbsp; 그리고 실패시&nbsp;재시도를 위해서 지난&nbsp;번 처리한 영역까지 표시하거나 앞에 성공한 건들을 다 지워줘야 하는 경우 때문에&nbsp;&nbsp;큰 transaction을 가지고 가는 문제가 .생기는데, 재시도를 위한 기능을 트랜잭션에서 제공받기 전에 응용프로그램에서 적절한 로직으로 처리하는 것이 필요하다고 나와 있습니다.</p><p>&nbsp;</p><blockquote><p>The problem that needs to be addressed in cases such as these is the design of the batch processes that require such a huge transaction.<span style="mso-spacerun: yes">&nbsp;</span> Transactions in Oracle should normally be kept fairly short.<span style="mso-spacerun: yes">&nbsp;</span> While it is undesirable to commit for every row processed (which will cause excessive redolog buffer flushing and high waits on “<span style="FONT-FAMILY: Courier">log file sync</span>”), it makes sense to have batch processes commit for every few hundred rows processed.</p></blockquote><p>......</p><blockquote><p>Often the greatest barrier to changing batch jobs to commit continuously is failure tolerance.<span style="mso-spacerun: yes">&nbsp;</span> If a batch job that commits continuously fails part way through, then there must be a way to restart that batch job where it left off, or clean up from the first attempt so that the job can be started over.<span style="mso-spacerun: yes">&nbsp;</span> Whereas before this restart capability was provided by rolling back the large transaction, the proposed rollback-friendly model requires that the appropriate application logic be built into the batch processing software.</p></blockquote><p>......</p><blockquote><p>If you allow your semi-frequently committing batch jobs to randomly select rollback segments like all the rest of the transactions in your system, you will be less likely to overwrite recently committed changes, since the burden of the batch transactions is spread around, rather than concentrated in a single rollback segment</p></blockquote><p>&nbsp;</p><h5>참고자료3</h5><p>&nbsp;<a class="external" title="http://www.ibm.com/developerworks/websphere/library/techarticles/0606_antani/0606_antani.html" href="http://www.ibm.com/developerworks/websphere/library/techarticles/0606_antani/0606_antani.html">Solving Business Problems with WebSphere Extended Deployment</a>&nbsp;:</p><p>&nbsp;WebSphere XD에서 제공하고 있는 check-point algorithm에 대한 설명을 볼 수 있습니다.</p><p>&nbsp;</p><h5>참고자료4</h5><p><a class="external" title="http://static.springframework.org/spring-batch/spring-batch-docs/reference/html/execution.html#d0e3602" href="http://static.springframework.org/spring-batch/spring-batch-docs/reference/html/execution.html#d0e3602">Spring batch documentation - 4.4.1.2. Configuring a CommitInterval</a>&nbsp;:</p><p>Spring batch에서 주기적인 commit을 설정하는 방법입니다.</p>			 ]]> 
		</description>
		<category>기술 자료</category>
		<pubDate>Thu, 15 May 2008 01:52:17 GMT</pubDate>
		<dc:creator>정상혁</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 매쉬업(Mashup) 도구들 ]]> </title>
		<link>http://benelog.egloos.com/1857319</link>
		<guid>http://benelog.egloos.com/1857319</guid>
		<description>
			<![CDATA[ 
  <h4>Yahoo Pipe</h4><ul><li><a href="http://pipes.yahoo.com/pipes/">http://pipes.yahoo.com/pipes/</a></li><li>설명 : <a title="http://en.wikipedia.org/wiki/Yahoo_Pipes" class="external" href="http://en.wikipedia.org/wiki/Yahoo_Pipes">http://en.wikipedia.org/wiki/Yahoo_Pipes</a> , <a href="http://radar.oreilly.com/archives/2007/02/pipes-and-filters-for-the-inte.html" title="http://radar.oreilly.com/archives/2007/02/pipes-and-filters-for-the-inte.html" class="external">Pipes and Filters for the Internet</a><br />
</li><li><p>예제<br />
</p><ul><li><a href="http://pipes.yahoo.com/pipes/pipe.info?_id=vvW1cD212xGMiR9aqu5lkA" title="http://pipes.yahoo.com/pipes/pipe.info?_id=vvW1cD212xGMiR9aqu5lkA" class="external">&nbsp;New York Times thru Flickr</a><br />
</li></ul></li><li><p>사용법<br />
</p><ul><li><a href="http://usefulvideo.blogspot.com/2007/02/yahoo-pipes-tutorials.html" title="http://usefulvideo.blogspot.com/2007/02/yahoo-pipes-tutorials.html" class="external">Yahoo! Pipes tutorials</a> <a href="http://www.jumpcut.com/fullscreen?id=C086AA92568811DCAB02000423CF381C&amp;amp;amp;type=movie" title="http://www.jumpcut.com/fullscreen?id=C086AA92568811DCAB02000423CF381C&amp;amp;amp;type=movie" class="external">How to Translate a Feed Using Pipes</a><br />
</li><li><a href="http://www.jumpcut.com/fullscreen?id=594F555C568011DC9D24000423CEF5B0&amp;amp;amp;type=movie" title="http://www.jumpcut.com/fullscreen?id=594F555C568011DC9D24000423CEF5B0&amp;amp;amp;type=movie" class="external">Learn How to Build a Pipe in Just a Few Minutes</a><br />
</li><li><a href="http://alexeysmirnov.name/blog/?page_id=198" title="http://alexeysmirnov.name/blog/?page_id=198" class="external">Alexey's Yahoo Pipes tutorial</a><br />
</li></ul></li></ul><h4>MS Popfly<br />
</h4><ul><li><a href="http://www.popfly.com/">http://www.popfly.com/</a>&nbsp;<br />
</li><li>설명 : <a href="http://en.wikipedia.org/wiki/Popfly">http://en.wikipedia.org/wiki/Popfly</a><br />
</li><li>Silverlight 기술에 기반<br />
</li><li>시연동영상 : <a href="http://www.youtube.com/watch?v=hkTdJAYb--M" class="external" title="http://www.youtube.com/watch?v=hkTdJAYb--M">Three Minut Mashup - Microsoft Popfly</a><br />
</li></ul><p><br />
</p><h4>IBM lotus mashup<br />
</h4><ul><li><a href="http://www.ibm.com/lotus/mashups">http://www.ibm.com/lotus/mashups</a>&nbsp;<br />
</li><li>2008년 중반에 공개 예정<br />
</li></ul><p><font style="" color="#810081"><br />
</font></p><h4>Google Mashup Editor<br />
</h4><ul><li><a href="http://www.googlemashups.com/">http://www.googlemashups.com/</a><br />
</li><li>설명 : <a href="http://en.wikipedia.org/wiki/Google_Mashup_Editor"><font style="" color="#810081">http://en.wikipedia.org/wiki/Google_Mashup_Editor</font></a><br />
</li></ul><p><br />
</p><h4>Intel Mash maker</h4><ul><li><a href="http://mashmaker.intel.com/web/">http://mashmaker.intel.com/web/</a><br />
</li><li>웹브라우저에 확장된 기능을 제공하는 형식<br />
</li><li>시연동영상 : <a href="http://blip.tv/file/get/Intel_SW-IntelMashMakerOverviewVideo814.wmv">http://blip.tv/file/get/Intel_SW-IntelMashMakerOverviewVideo814.wmv</a><br />
</li></ul><p><br />
</p><h4>관련링크</h4><p><a href="http://uzys.tistory.com/97" title="http://uzys.tistory.com/97" class="external"><font style="" color="#810081">mashup 도구</font></a></p><p><font style="" color="#810081"><br />
</font></p><p><br />
</p>			 ]]> 
		</description>
		<category>기술 자료</category>
		<pubDate>Wed, 23 Apr 2008 08:52:33 GMT</pubDate>
		<dc:creator>정상혁</dc:creator>
	</item>
</channel>
</rss>
