<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-29738970</id><updated>2012-02-16T21:10:01.778+09:00</updated><category term='번역'/><category term='얘기꺼리'/><category term='P. Note for EJB'/><category term='P. Note for PHP'/><category term='P. Note for DBMS'/><category term='Announce'/><category term='좋은 책 이야기'/><category term='P. Note for Win32'/><category term='Project::My Room'/><category term='P. Note for Servers'/><category term='iPhone and iPod'/><category term='머리속 그림들'/><category term='Project::SecretMessanger'/><title type='text'>은은한 자스민 벡터 - 블로그를 이전합니다. http://defree.co.kr/blog 로 오세요!</title><subtitle type='html'>(The jasmine Vector of distant peals)</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default?start-index=101&amp;max-results=100'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>111</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-29738970.post-7428656882510326883</id><published>2009-01-14T14:36:00.001+09:00</published><updated>2009-01-14T23:59:58.422+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='번역'/><title type='text'>Project Darkstar server tutorial 번역</title><content type='html'>&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;font id="zcz_" size="6"&gt; Project Darkstar Server Application Tutorial&lt;/font&gt;&lt;br id="fsoq"&gt;&lt;br id="hixs"&gt;&lt;font id="ljcq" size="4"&gt;목차&lt;/font&gt;&lt;br id="mxc8"&gt;&lt;br id="s2:2"&gt;(Java bindings for OpenGL : https://jogl.dev.java.net/)&lt;br id="y4tz"&gt;&lt;ul id="r9y."&gt;&lt;li id="gazw"&gt;소개 (Introduction)&lt;br id="yl_p"&gt;&lt;/li&gt;&lt;li id="bg3r"&gt;Project Darksart Server Application 코딩하기 (Coding Project Darkstar Server Applications)&lt;/li&gt;&lt;ul id="eesm"&gt;&lt;li id="urzc"&gt;목표와 철학 (Goals and Philosophy)&lt;/li&gt;&lt;li id="bin8"&gt;실행하기 (Approach to Execution)&lt;/li&gt;&lt;ul id="r:vr"&gt;&lt;li id="dy69"&gt;작업과 관리 (Tasks and Managers)&lt;/li&gt;&lt;li id="y.50"&gt;작업 순번 (Task Ordering)&lt;/li&gt;&lt;li id="ojke"&gt;작업 실행시간 (Task Lifetime)&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;ul id="babw"&gt;&lt;li id="ye7l"&gt;Managed Object와 Managed Reference (Managed Objects and Managed References)&lt;/li&gt;&lt;ul id="f-i."&gt;&lt;li id="m_yf"&gt;Managed Reference를 통하여 Managed Object 접근하기 (Accessing Managed Objects through Managed References)&lt;/li&gt;&lt;li id="m87v"&gt;나만의 Managed Object 디자인하기 (Designing Your Managed Objects)&lt;/li&gt;&lt;li id="y4ye"&gt;The Player Managed Object (The Player Managed Object)&lt;/li&gt;&lt;li id="cbqk"&gt;The AppListener (The AppListener)&lt;/li&gt;&lt;/ul&gt;&lt;li id="z2ok"&gt;서버 API 클래스 위치하기 (Locating the Server API Classes)&lt;/li&gt;&lt;li id="zv5x"&gt;System Classes and Interfaces (System Classes and Interfaces)&lt;/li&gt;&lt;li id="v-:b"&gt;Task Manager Classes and Interfaces (Task Manager Classes and Interfaces)&lt;/li&gt;&lt;li id="g_.y"&gt;Data Manager Classes and Interfaces (Data Manager Classes and Interfaces)&lt;br id="nakm"&gt;&lt;/li&gt;&lt;li id="rqwc"&gt;Channel Manager Classes and Interfaces (Channel Manager Classes and Interfaces)&lt;/li&gt;&lt;/ul&gt;&lt;li id="fe8t"&gt;Lesson One: Hello World!&lt;/li&gt;&lt;ul id="gqg2"&gt;&lt;li id="szcu"&gt;HelloWorld 코딩하기 (Coding HelloWorld)&lt;/li&gt;&lt;ul id="j2mw"&gt;&lt;li id="ezrg"&gt;HelloWorld&lt;/li&gt;&lt;/ul&gt;&lt;li id="tpi1"&gt;HelloWorld 실행하기 (Running HelloWorld)&lt;/li&gt;&lt;ul id="q1wv"&gt;&lt;li id="ehb0"&gt;HelloWorld 실행하기 (Running HelloWorld)&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;li id="m_nh"&gt;Lesson Two: Hello Logger!&lt;/li&gt;&lt;ul id="mtto"&gt;&lt;li id="vs3f"&gt;HelloLogger 코딩하기 (Coding HelloLogger)&lt;/li&gt;&lt;ul id="nr24"&gt;&lt;li id="ktd_"&gt;HelloLogger&lt;/li&gt;&lt;/ul&gt;&lt;li id="iaen"&gt;The Logging Properties File&lt;/li&gt;&lt;/ul&gt;&lt;li id="h6n0"&gt;Lesson 3: Tasks, Managers, and Hello Timer&lt;/li&gt;&lt;ul id="izm6"&gt;&lt;li id="lf:y"&gt;Tasks (Tasks)&lt;/li&gt;&lt;li id="kg87"&gt;Managers (Managers)&lt;/li&gt;&lt;li id="e45r"&gt;HelloTimer 코딩하기 (Coding HelloTimer)&lt;/li&gt;&lt;ul id="zttj"&gt;&lt;li id="xic0"&gt;HelloTimer&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;li id="r-jc"&gt;Lesson 4: Hello Persistence!&lt;/li&gt;&lt;ul id="bzy7"&gt;&lt;li id="rf5m"&gt;HelloPersistence 코딩하기 (Coding HelloPersistence)&lt;/li&gt;&lt;ul id="hm93"&gt;&lt;li id="i478"&gt;HelloPersistence&lt;/li&gt;&lt;/ul&gt;&lt;li id="k7ey"&gt;HelloPersistence2 코딩하기 (Coding HelloPersistence2)&lt;/li&gt;&lt;ul id="uhfv"&gt;&lt;li id="n7ld"&gt;HelloPersistence2&lt;/li&gt;&lt;/ul&gt;&lt;ul id="tyvo"&gt;&lt;li id="n5ut"&gt;TrivalTimedTask&lt;br id="nods"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;ul id="zf7r"&gt;&lt;ul id="cgxs"&gt;&lt;li id="t482"&gt;HelloPersistence3 코딩하기 (Coding HelloPersistence3)&lt;br id="bwra"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id="l2-y"&gt;&lt;ul id="b5ef"&gt;&lt;li id="w9h6"&gt;HelloPersistence3 26&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;li id="umvc"&gt;Lesson 5: Hello User!&lt;br id="zc5j"&gt;&lt;/li&gt;&lt;ul id="a8qp"&gt;&lt;li id="tlrk"&gt;사용자가 로그인할 때 일어나는 일 (Knowing When a User Logs In)&lt;br id="f.ve"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id="o:2o"&gt;&lt;ul id="w0sy"&gt;&lt;li id="isvo"&gt;HelloUser&lt;br id="gtc7"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;ul id="hv4c"&gt;&lt;li id="tzg-"&gt;직접 통신 (Direct Communication)&lt;br id="jk9d"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id="w51l"&gt;&lt;ul id="niw-"&gt;&lt;li id="dglf"&gt;HelloUser2&lt;br id="s1_t"&gt;&lt;/li&gt;&lt;li id="rjh7"&gt;HelloUserSessionListener&lt;br id="ijy1"&gt;&lt;/li&gt;&lt;li id="dn33"&gt;HelloEchoSessionListener&lt;br id="yf1l"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li id="q9yi"&gt;예제 실행하기 (Running the Examples)&lt;br id="n167"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li id="rhao"&gt;Lesson 6: Hello Channels!&lt;br id="l-t0"&gt;&lt;/li&gt;&lt;ul id="cvwb"&gt;&lt;li id="q6l:"&gt;HelloChannels 코딩하기 (Coding HelloChannels)&lt;br id="rezz"&gt;&lt;/li&gt;&lt;ul id="ouiu"&gt;&lt;li id="a6lj"&gt;HelloChannels&lt;br id="hdrj"&gt;&lt;/li&gt;&lt;li id="rp2e"&gt;HelloChannelsSessionListener&lt;br id="c5hd"&gt;&lt;/li&gt;&lt;li id="hg-x"&gt;HelloChannelsChannelListener&lt;br id="xgtg"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li id="f6lr"&gt;HelloChannels 실행하기 (Running HelloChannels)&lt;br id="b.yc"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li id="iv5v"&gt;결론 (Conclusion)&lt;br id="d3ec"&gt;&lt;/li&gt;&lt;ul id="j4-6"&gt;&lt;li id="huqh"&gt;Best Practices&lt;br id="wxo5"&gt;&lt;/li&gt;&lt;li id="asbf"&gt;튜토리얼에 없는 내용 (Things Not Covered in This Tutorial)&lt;br id="d.ny"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li id="r-38"&gt;Appendix A: SwordWorld Example Code&lt;br id="p101"&gt;&lt;/li&gt;&lt;ul id="ehxp"&gt;&lt;li id="aova"&gt;Sword World&lt;br id="oovu"&gt;&lt;/li&gt;&lt;li id="y9wu"&gt;SwordWorldObject&lt;br id="idwo"&gt;&lt;/li&gt;&lt;li id="he0e"&gt;SwordWorldRoom&lt;br id="u-qt"&gt;&lt;/li&gt;&lt;li id="c5jw"&gt;SwordWorldPlayer&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br id="z7li"&gt;&lt;br id="dd2:"&gt;&lt;font id="qijt" size="5"&gt;소개 (Introduction)&lt;/font&gt;&lt;br id="xrh5"&gt;&lt;div id="yn1p" style="margin-left: 40px;"&gt;Project Darkstar Server(PDS)의 튜토리얼로의 여행을 환영합니다. 이 문서는 PDS상의 게입서버를 만들기 위하여 필요한 모든 것을 알려주기 위해 작성되었습니다. 우리는(역자주:아마 PDS를 진행하는 개발자들이겠죠?) 이러한 프로그램을 PDS 어플리케이션이라고 부르고, 여러분은 이 용어를 이 튜토리얼과 다른 PDS 문서들에서 보게 될 것입니다. 이 튜토리얼은 PDS 어플리케이션을 어떻게 만들 수 있는지에 대한 개략으로 시작해서 한 단계씩 간단한 어플리케이션을 개발하여보겠습니다.&lt;br id="v7su"&gt;&lt;/div&gt;&lt;div id="eoda" style="margin-left: 40px;"&gt;Welcome to the Project Darkstar Server (PDS) application tutorial. This document is designed to teach you everything you need to know to start writing game servers that run on top of the Project Darkstar Server. We call such programs PDS applications, and you will see that term used in this and other PDS documents. This tutorial begins with an overview of how to code a PDS application, then steps through the development of a very simple application.&lt;br id="hhaz"&gt;&lt;/div&gt;&lt;br id="y:-b"&gt;&lt;br id="h9:7"&gt;&lt;font id="tm43" size="5"&gt;PDS 어플리케이션 코딩하기 (Coding Project Darkstar Server Applications)&lt;/font&gt;&lt;br id="r4y1"&gt;&lt;div id="j1.2" style="margin-left: 40px;"&gt;이 챕터는 PDS 환경에서 어덯게 게임 서버 어플리케이션을 코딩하는지에 대한 기초 컨셉을 알려줍니다. 해당 컨셉들을 이해한다는 것은 규모가 크고 신뢰성이 있으며 오류에 강하고 견고한 네트웍 게임을 만드는 첫번째 단계입니다.&lt;br id="povp"&gt;&lt;/div&gt;&lt;div id="a2di" style="margin-left: 40px;"&gt;This chapter presents the fundamental concepts of how to code game server applications in the Project Darkstar Server (PDS) environment. Understanding these concepts is the first step on the path to building massively scalable, reliable, fault-tolerant, and persistent network games.&lt;br id="q5u3"&gt;&lt;/div&gt;&lt;br id="p9_y"&gt;&lt;br id="fjkq"&gt;&lt;div id="ka5w" style="margin-left: 40px;"&gt;&lt;font id="zsr6" size="4"&gt;목표와 철학 (Goals and Philosophy)&lt;br id="c6uf"&gt;&lt;/font&gt;PDS 코딩 모델을 이해하기 위해 PDS 시스템의 설계 목표를 이해하는 것이 좋습니다. 기본적인 목표는 다음과 같습니다.&lt;br id="iskt"&gt;In order to understand the Project Darkstar Server (PDS) coding model, it is useful to understand the system's goals. The fundamental goals are as follows:&lt;br id="gp8k"&gt;&lt;ul id="ydaf"&gt;&lt;li id="j5d:"&gt;신뢰성이 있으며 견고하고 대규모에 적용가능하며 오류에 강한 게임 개발자에게 투명한 서버측 코딩을 할 수 있어야 한다.&lt;/li&gt;&lt;li id="usg1"&gt;개발자에게 단일 스레드 이벤트 기반 프로그래밍 모델을 제공하여야 한다. 개발자의 다른 이벤트등에 대한 오류가 전파되지 않도록 하여야 한다.&lt;br id="iw8e"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id="n:km"&gt;&lt;li id="gcwt"&gt;Make server-side game code reliable, scalable, persistent, and fault-tolerant in a manner that is transparent to the game developer.&lt;/li&gt;&lt;li id="dtpc"&gt;Present a simple single-threaded event-driven programming model to the developer. The developer should never have his or her code fail due to interactions between code handling different events. Applications coded to run in the PDS environment are called PDS applications.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;br id="i-ek"&gt;&lt;br id="whqc"&gt;&lt;div id="n3pt" style="margin-left: 40px;"&gt;&lt;font id="d:b1" size="4"&gt;실행 접근성 (Approach to Execution)&lt;/font&gt;&lt;br id="viia"&gt;&lt;br id="x1pw"&gt;&lt;b id="mu4u"&gt;태스크와 매니저 (Tasks and Managers)&lt;/b&gt;&lt;br id="fkd5"&gt;PDS 어플리케이션 프로그래머 측면에서 보면 PDS 어플리케이션은 확실히 단일 스레드와 이벤트 기반 모델로 실행됩니다. 어떤 데이터가 수정되거나 하는 하나의 이벤트를 다루는 코더에 의해서 이벤트 핸들링 코딩됩니다. 그러므로 실행이란 결과에 대한 증명과 데드락에 대한 증명으로 생각 될 수 있습니다. 사실, 동기화가 전혀 필요 없는 대부분의 상태라는 조건하에 Managed Object에서 synchronized 키워드를 시도하는 것은 해결하기 어려운 버그를 초래할 수 있습니다.&lt;br id="b_pm"&gt;실제로 이 시스템(PDS)는 각각의 이벤트를 처리하기 위해 상당수의 스레드를 사용합니다. 이 스레드들을 컨트롤 하는 것을 태스크(tasks)라고 합니다. PDS는 각각의 무슨 태스크가 억세스하는 데이터들을 추적합니다. 충돌을 피하기 위하여, 이전에 생성된 태스크가 제대로 종료되도록 최근 생성된 태스크는 중지되며 스케쥴링됩니다.&lt;br id="x3fp"&gt;태스크는 PDS 매니저(PDS Manager)에 의해 생성됩니다. PDS 환경 안팍으로 PDS 어플리케이션은 메니저를 사용하여 효과적인 액션을 취할 수 있습니다. PDS에는 세가지 기본 매니저가 있습니다. 또한 PDS 환경에 임의의 매니저를 추가할 수 있습니다. 세가지 기본 매니저는 다음과 같습니다.&lt;br id="hv1o"&gt;From the point of view of the PDS application programmer, PDS applications execute in an apparently monothreaded, event-driven model. The code handling the event appears to the coder to have sole ownership of any data it modifies. Thus, execution is both race-proof and deadlock-proof. Under most conditions there is no need to synchronize application code and, in fact, attempting to use the synchronized keyword in Managed Objects1 can cause subtle bugs.&lt;br id="ib0c"&gt;In actuality, the system has many threads of control all simultaneously processing their own events. These threads of control are called tasks. The system keeps track of what data each task accesses. Should a conflict arise, the younger task is aborted and scheduled for retry at a later date so that the older task can complete and get out of the way. (“Younger” and “older” refer to the time at which the task was queued for execution.)&lt;br id="lo7s"&gt;Tasks are created by PDS managers. a PDS application uses these managers to effect actions in the PDS environment and the outside world. There are three standard managers in the system. In addition, arbitrary managers may be coded and added to the PDS environment. The standard managers are:&lt;br id="f:il"&gt;&lt;ul id="up0k"&gt;&lt;li id="sqzu"&gt;Task Manager&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div id="y85j" style="margin-left: 80px;"&gt;태스크 매니저를 사용하여 PDS 어플리케이션에서 큐를 사용할 수 있습니다. 한 태스크는 자식 태스크를 생성할 수 있습니다. 즉시 또는 지연 후 실생되거나 주기적으로 실생되기 위해 큐에 추가될 수 있습니다. 형제 태스크라고 말할 수 있는 다중 자식 태스크는 같은 한 부보 태스크에 의해 큐에 추가됩니다.&lt;br id="uvkr"&gt;&lt;/div&gt;&lt;div id="xemr" style="margin-left: 80px;"&gt;A PDS application can use the Task Manager to queue tasks of its own. Tasks can be queued for immediate execution, delayed execution, or periodic execution. Tasks created from within other tasks are called child tasks. The task that queued the child task is called the parent task. Multiple child tasks queued by the same parent task are called sibling tasks.&lt;/div&gt;&lt;div id="y_qy" style="margin-left: 40px;"&gt;&lt;ul id="n7su"&gt;&lt;li id="kezm"&gt;Data Manager&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div id="e55s" style="margin-left: 80px;"&gt;PDS 어플리캐이션은 데이터 매니저를 사용하여 Managed Object라고 하는 퍼시스턴스 클래스 또는 분산 자바 오브젝트를 생성할 수 있습니다.&lt;br id="gmn_"&gt;&lt;/div&gt;&lt;div id="j5.t" style="margin-left: 40px;"&gt;&lt;div id="y045" style="margin-left: 40px;"&gt;A PDS application can use the Data Manager to create and access persistent, distributed Java objects called Managed Objects. The PDS application is itself composed of Managed Objects&lt;/div&gt;&lt;ul id="d6k6"&gt;&lt;li id="zm1i"&gt;Channel Manager&lt;/li&gt;&lt;/ul&gt;&lt;div id="y:qa" style="margin-left: 40px;"&gt;채널 매니저는 데이터 채널을 컨트롤 하기 위하여 사용됩니다. 이 데이터 채널은 보통 서로 다른 클라이언트나 서버-클라이언트의 통신을 위해 사용됩니다.&lt;br id="ugp1"&gt;A PDS application can use the Channel Manager to create and control publish/subscribe data channels. These data channels are used to communicate between different clients and between clients and the server.&lt;br id="r2v3"&gt;&lt;/div&gt;PDS 어플리케이션은 AppContext class를 사용하여 다른 매니저를 접근하는 PDS 핵심 기능에 접근합니다.&lt;br id="trw_"&gt;A PDS application gets access to core PDS functionality through the AppContext class, which provides methods to obtain references to the various managers.&lt;br id="duy."&gt;&lt;/div&gt;&lt;br id="s8d0"&gt;&lt;br id="twpo"&gt;&lt;div id="u2pn" style="margin-left: 40px;"&gt;&lt;b id="e7pp"&gt;태스크 정리하기 (Task Ordering)&lt;/b&gt;&lt;br id="xxnh"&gt;클라이언트로부터 생성된 이벤트를 핸들링하는 태스크는 특정 규칙에 의해 실행이 보증됩니다. 한 클라이언트의 이전 이벤트가 모두 끝나기 전에는 그 이후 발생될 클라이언트 이벤트를 핸들링하는 태스크가 실행하지 않을 것입니다. 자식 태스크는 그 부모 태스크를 주목하고 있으나 형제 태스크에 관하여는 그렇지 않습니다. 이것은 자식 태스크의 실행이 부모 태스크의 실행이 끝나기 전 까지 시작되지 않는 것을 의미합니다. 그러나 형제 태스크에 관한 순서에 대한 보증은 존재하지 않습니다. &lt;br id="uqba"&gt;중요 : PDS에서 이외의 다른 태스크 순서에 대한 보증은 더이상 있지 않습니다. 실제적으로, 서로 다른 유저의 이벤트를 핸들링에 대한 실행은 한 서버 안에서도 각각의 다른 태스크의 실행 시작 순서를 보증하지 않습니다. &lt;br id="onl2"&gt;Tasks that handle events created by a client are guaranteed to execute in order. A task to handle a client event that occurred later in time will not start executing until the tasks to handle all earlier events generated by the same client have finished. A child task is ordered with regard to its parent task, but not with regard to its siblings. This means that execution of a child task will not begin until execution of the parent has completed. There are, however, no guarantees among sibling tasks as to order of execution.&lt;br id="cs.:"&gt;Important: There are no other order guarantees in the system. In particular, execution of tasks to handle events of different users are not guaranteed to start executing relative to each other in the order they arrived at the server.&lt;br id="f.9i"&gt;&lt;br id="g879"&gt;&lt;/div&gt;&lt;div id="ehfi" style="margin-left: 40px;"&gt;&lt;b id="i43w"&gt;태스크 생명주기 Task Lifetime&lt;/b&gt;&lt;br id="srsu"&gt;다른 태스크에 요청될 수 있는 자원들의 과도한 요청으로 블럭되지 않기 위해 태스크는 짧은 주기로 제공됩니다. PDS 자체는 최대한의 실행시간으로 설정되어 있습니다(디폴트 1분). 각각의 설정대로 아직 종료되지 않은 다른 태스크는 시스템에 의해 강제로 종료될 것입니다. 만약 어떤 태스크의 실행 기간이 너무 길다면 실행시간을 줄일 수 있는 두가지 방법이 제공됩니다.&lt;br id="h8h9"&gt;Tasks are intended to be short-lived so that they do not block access for an inordinate amount of time to resources that might be needed by other tasks. The PDS is configured by its operator with a maximum task execution time (the default is one minute). Any task that does not finish within that time will be forcibly terminated by the system.&lt;br id="afsx"&gt;If you have a task that runs too long, there are two approaches to reducing its execution time:&lt;br id="il7d"&gt;&lt;ul id="xvq4"&gt;&lt;li id="bbtz"&gt;자식 태스크의 연결로 각각 나누거나, 문제되는 한 부분마다 핸들러를 추가하거나 다음 태스크로 설정하여 순차적으로 큐에 넣는 것입니다. 보통 continuation-passing style 이라고 알려진 방법입니다.(연결-통과 스타일? -_-)&lt;br id="jqts"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div id="x:hg" style="margin-left: 40px;"&gt;Split it up into a chain of child tasks, each of which handles one discrete portion of the problem, and then queues the next task in sequence. This is known as continuation-passing style.&lt;/div&gt;&lt;ul id="nwh-"&gt;&lt;li id="nsh2"&gt;소비되는 시간의 계산이 종료되었을 때의 결과를 갖는 태스크를 큐에 넣어 처리하는 방법입니다. &lt;br id="ts51"&gt;&lt;/li&gt;&lt;li id="s3ye"&gt;Move the time-consuming calculations into a custom manager that queues a result-task when the calculations are complete.&lt;/li&gt;&lt;/ul&gt;이 접근법들은 각각 장단점이 있습니다. 첫번째 방법은 태스크들을 잘게 쪼갤 수 있을 때 문제를 해결하는데 더 쉽습니다. 주의할 것은, 각 단계가 실행될 때 어떠한 정확한 보증도 없기 때문에, 데이터를 포함한 각각의 태스크가 민감하고 불안한 상태로 있게 된다는 것입니다. 이 접근 방법의 특별한 경우는 여러 문제의 부분들이 각각 다른 위치에 개별적이고 핸들링 가능한 경우입니다. 이러한 경우, 종료까지 필요한 시간은 각각 병렬로 실행되는 태스크의 연결상태에 의해 줄어들 수도 있습니다. 그러나 이 별개의 연결상태는 각각 서로 정확하지 않은 순서로 있을 수 있으므로 그 상태의 태스크들의 수행은 반드시 서로 독립적이어야 합니다. 두번째 접근법은 태스크를 작은 상태로 분해할 수 없을 때 적용하기 쉽습니다. 그러나 이 방법은 여러분이 커스텀 PDS 매니저를 만들고 설치하여야 합니다. (커스텀 PDS 매니저를 만드는 것은 'PDS 환경을 확장하는 방법'에 관한 문서를 보시기 바랍니다.)&lt;br id="isi4"&gt;특별히 중요한 경우는 태스크의 실행주기가 좀 더 긴 것을 블럭하기 위해 시스템 콜을 호출하는 경우입니다. 이 경우 반드시 정교한 커스텀 매니저를 개발하는 것이 필요합니다.&lt;br id="eltf"&gt;Each approach has its advantages and disadvantages. The first is easier for simple problems that lend themselves to serial decomposition. Care must be taken that each task ends with the data in a sensible and usable state, because there is no guarantee as to exactly when the next step will be executed. A special case of this approach is where parts of the problem are separable and handleable in parallel. In this case, the time to complete may be reduced by launching parallel chains of tasks. These parallel chains, however,&lt;br id="dfmx"&gt;have no guaranteed ordering in relation to each other, so the work they perform must really be independent of each other, The second approach is easier for problems that don't decompose well into small, discrete components; however, it requires the writing and installation of a custom PDS manager. (Writing custom PDS managers will be covered by a separate document explaining how to extend the PDS environment.)&lt;br id="lcbd"&gt;A particularly important case is code that has to go into system calls that can block for more then the task execution lifetime. These must be implemented through a custom manager in order to produce a robust PDS application.&lt;br id="q56u"&gt;&lt;/div&gt;&lt;br id="s7:i"&gt;&lt;br id="vc7x"&gt;&lt;div id="hao_" style="margin-left: 40px;"&gt;&lt;font id="pduv" size="4"&gt;Managed Objects and Managed References (역자주 : 원어 그대로 사용하는 용어이고 다른 용어가 생각나질 않아서 그대로 둡니다.)&lt;/font&gt;&lt;br id="boi6"&gt;데이터 매니저는 오브젝트 스토어라고 하는 오프젝트의 풀에 저장된 매니지드 오브젝트의 퍼시스턴스 셋을 보존하고 있습니다. 보통 자바 오브젝트와 같이, 각 매니지드 오브젝트는 데이터와 데이터를 처리하기 위한 메소드를 포함합니다. 매니지드 오브젝트를 작성하려면 ManagedObject와 Serializable 인터페이스를 상속하여야 합니다. 매니지드 오브젝트는 오브젝트 풀에 해당 오브젝트가 있는 동안 오브젝트 소토어의 풀의 한 부분이 되지 않습니다. 이는 매니지드 레퍼런스를 상속받은 오브젝트 또는 오브젝트를 상속받은 오브젝트는 데이터 매니저에 의해 결정된다는 것입니다.&lt;br id="eqj2"&gt;매니지드 레퍼런스는 전형적인 J2SE(tm)의 레퍼런스 오브젝트와 같습니다(예를 들면, SoftReference, WeakReference). 매니지드 오브젝트는 반드시 다른 매니지드 레퍼런스를 통하여 다른 매니지드 오브젝트를 참조하여야 합니다. 이는 매니지드 오브젝트의 한 상태의 부분인 매니지드 오브젝트의 컴포넌트 오브젝트를 레퍼런스 하는 것과, 자신의 상태를 포함한 서로 다른 매니지드 오브젝트를 레퍼런스 하는 것에 대한 차이점을 데이터 매니저가 어떻게 표할 수 있는지에 대한 것입니다.&lt;br id="n:13"&gt;매니지드 오브젝트가 데이터 매니저에서 getBinding 을 호출하는 또다른 태스크에 의해 오브젝트 스토어로부터 갱신될 수도 있을 만큼, 이 바인딩한 이름은 매니지드 오브젝트와 함께 스트링에 첨가시킵니다.&lt;br id="bpup"&gt;The Data Manager maintains a persistent set of Managed Objects stored in a pool of objects called the Object Store. Like a normal Java object, each Managed Object contains both data and the methods to act upon that data. In order to be a Managed Object, the object must implement both the ManagedObject and Serializable interfaces. A Managed Object does not become part of the Object Store's pool until the pool is made aware of the object. This is done by using the Data Manager either to request a Managed Reference to the object or to bind a name to the object.&lt;br id="gy2l"&gt;A Managed Reference is a reference object that looks much like the J2SE(tm) reference objects (for example, SoftReference, WeakReference). Managed Objects must refer to other Managed Objects through Managed References. This is how the Data Manager can tell the difference between a reference to a component object of the Managed Object (for instance, a list) that is part of that Managed Object's state, and a reference to a separate Managed Object with a state of its own.&lt;br id="dq8s"&gt;A name binding associates a string with the Managed Object such that the object may be retrieved from the Object Store by other tasks using the getBinding call on the Data Manager.&lt;br id="fzqo"&gt;&lt;br id="ex_q"&gt;&lt;b id="x:hd"&gt;매니지드 레퍼런스를 통하여서 매니지드 오브젝트 억세스하기 (Accessing Managed Objects through Managed References)&lt;/b&gt;&lt;br id="sgok"&gt;매니지드 레퍼런스는 get과 getForUpdate 두 개의 메소드를 억세스할 수 있습니다. 두 메소드 모두 오브젝트의 복사본을 리턴합니다. 두 메소드의 차이점은 다음과 같습니다.&lt;br id="g3tm"&gt;The Managed Reference has two access methods: get and getForUpdate. Both methods return a task-local copy of the object. The difference between the two methods is:&lt;br id="b-u:"&gt;&lt;ul id="kyrr"&gt;&lt;li id="kw.4"&gt;getForUpdate는 매니지드 오브젝트의 상태가 변경될 것이라고 시스템에 통보합니다.&lt;br id="wwac"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div id="krbx" style="margin-left: 40px;"&gt;getForUpdate informs the system that you intend to modify the state of the Managed Object.&lt;/div&gt;&lt;ul id="thkb"&gt;&lt;li id="cak8"&gt;get은 단지 상태를 read할 때 사용됩니다.&lt;br id="gmjc"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div id="r0h0" style="margin-left: 40px;"&gt;get says you intend only to read the state but not write it.&lt;br id="vsua"&gt;&lt;/div&gt;다른 매니지드 오브젝트의 모든 변경점이 변경되지 않는다 하여도(get을 통한 억세스를 포함하여), 여러분이 특정 시간에 매니지드 오브젝트의 상태가 변경될 것을 예상하고 있다면 getForUpdate를 사용하는 것이 좀 더 효율적입니다. 이는 시스템이 태스크와 훨씬 유효하고 빨리 생성된 핸들러와 태스크 사이의 충돌을 탐지하는 것을 가능하게 합니다.&lt;br id="ouhv"&gt;반대로 말하면, 매니지드 오브젝트의 상태가 변경되지 않을 것이라면 get을 사용하는 것이 더 낫습니다. get을 호출하는 것은 다중 태스크가 동작하는 상태에서 매니지드 오브젝트에 대하여 좀 더 병렬적으로 접근하는 것을 가능하게 합니다. 여러분이 오브젝트의 상태를 수정하는 것을 알고 있는 시점이라면, 데이터 매니저의 markForUpdate를 호출하여 get에서 getForUpdate까지 접근을 올릴 수 있습니다. (업데이트를 하기 위해 똑같은 매니지드 오브젝트를 확인하는 다중 호출은 위험하지 않습니다.)&lt;br id="fhag"&gt;같은 태스트 내의 동등한 매니지드 레퍼런스상의 get 또는 getForUpdate 호출로의 Subsequent 호출은 같은 태스크의 복사본을 리턴할 것입니다.&lt;br id="w0w9"&gt;getBinding을 호출하여 바인딩된 이름의 오브젝트를 갱신할 수 있습니다. 이는 매니지드 오브젝트의 get을 호출하는 것과 같아서, 해당 오브젝트를 변경할 예정이라면 여러분은 그 오브젝트를 갱신한 후 markForUpdate를 호출하여야 할 것입니다.&lt;br id="twr7"&gt;오브젝트 스토어 내의 매니지드 오브젝트들은 가비지 컬렉션에 영향을 받지 않습니다. 일단 매내지드 오브젝트가 스토어에 있다는 것만 알려주면, 데이터 매니저의 removeObject를 호출하여 오브젝트 스토어에서 명시적으로 제거되기 전까지 해당 오브젝트의 상태가 유지됩니다. 이는 어플리케이션이 더이상 필요 없을 때 오브젝트 스토어에서 오브젝트를 제거하고 생명주기를 관리하여야 한다는 것을 말합니다. 이를 잘못한다면 성능과 메모리 낭비라는 결과를 초래할 수 있습니다. 마찬가지로, 네임 바인딩은 removeBinding을 호출하여 제거하기 전까지 메모리상에 있을 것입니다. 네임 바인딩은 제거된 오브젝트를 참조하고 있을 때에도 사라지지 않습니다.&lt;br id="nuo4"&gt;Although all changes to any Managed Object are persistent (even those accessed via get), it is more efficient to use getForUpdate if you know at that time that you are going to want to modify the Managed Object's state. This allows the system to detect conflicts between tasks and handle them earlier and with greater efficiency.&lt;br id="rqe6"&gt;Conversely, it is better to use get if the state of the Managed Object may not be modified. The get call can allow for more parallel access to the Managed Object from multiple tasks. If you reach a point later in the execution where you know you are going to modify the object's state, you can upgrade your access from get to getForUpdate by calling the markForUpdate method on the Data Manager. (Multiple calls to mark the same Managed Object for update are harmless.)&lt;br id="q-ny"&gt;Subsequent calls to get or getForUpdate on equivalent Managed References in the same task will return the same task-local copy.&lt;br id="p5lv"&gt;You can also retrieve an object with a bound name by calling getBinding. This is equivalent to a get call on a Managed Reference to the object, so, if you intend to modify the object's state, you should call markForUpdate after retrieving the object.&lt;br id="sami"&gt;&lt;i id="lrbv"&gt;Managed Objects in the Object Store are not garbage-collected&lt;/i&gt;. Once the store is made aware of a Managed Object, it keeps the state of that object until it is explicitly removed from the object store with a call to the removeObject call on the Data Manager. It is up to the application to manage the life cycle of Managed Objects and to remove them from the Object Store when they are no longer needed. &lt;b id="yaqz"&gt;Failure to do so may result in garbage building up in your Object Store and impacting its performance&lt;/b&gt;. Likewise, name bindings are stored until explicitly destroyed with removeBinding. A name binding is not removed when the object it refers to is removed.&lt;br id="k1b2"&gt;&lt;/div&gt;&lt;br id="zb9v"&gt;&lt;br id="uu8l"&gt;&lt;br id="maem"&gt;&lt;div id="qxa:" style="margin-left: 40px;"&gt;&lt;font id="k4pn" size="4"&gt;자신만의 매니지드 오브젝트 설계하기 (Designing Your Managed Objects)&lt;/font&gt;&lt;br id="h3d_"&gt;일반적으로 매니지드 오브젝트는 세가지 타입입니다.&lt;br id="mt93"&gt;Managed Objects typically fall into three general types of entity:&lt;br id="yj67"&gt;&lt;ul id="taka"&gt;&lt;li id="wx_i"&gt;칼, 몬스터, 활동공간(예를들면 방) 등과 같은 게임상의 가상환경에 동작하는 오브젝트.&lt;br id="i63t"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div id="dsvi" style="margin-left: 40px;"&gt;Actual objects in your game's simulated environment, such as a sword, a monster, or a play-space (such as a room).&lt;/div&gt;&lt;ul id="yhcu"&gt;&lt;li id="jhj:"&gt;근접 계산을 위한 quau-tree나 이동 경로 결정 work-mesh와 같은 로직 또는 데이터 구조. &lt;br id="fihi"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div id="f_ic" style="margin-left: 40px;"&gt;Purely logical or data constructs such as a quad-tree for determining player-proximity or a walk-mesh to determine movement paths.&lt;/div&gt;&lt;ul id="qn8z"&gt;&lt;li id="s3fb"&gt;게임 플레이어를 위한 매니지드 오브젝트 프록시&lt;br id="t.gu"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div id="zqz1" style="margin-left: 80px;"&gt;Proxies for human players in the world of Managed Objects.&lt;br id="qm.o"&gt;&lt;/div&gt;&lt;div id="x7tr" style="margin-left: 40px;"&gt;Figure 1) 한 방안의 두명의 게임 플레이어와 칼 하나를 포함한 방의 간단한 월드 구조 개요&lt;br id="fks3"&gt;Figure 1 below illustrates a very basic world consisting of a single room that contains two players and a sword.&lt;br id="da6o"&gt;&lt;div id="nus4" style="padding: 1em 0pt; text-align: center;"&gt;&lt;a id="vjro" href="http://docs.google.com/File?id=ddcfsnv_12gm5zzmf4" target="_blank"&gt;&lt;img id="qos3" style="width: 389px; height: 373px;" src="http://docs.google.com/File?id=ddcfsnv_12gm5zzmf4"&gt;&lt;/a&gt;&lt;/div&gt;&lt;div id="arzp" style="text-align: center;"&gt;Figure 1: Example of a simple ManagedObject world&lt;br id="f9ih"&gt;&lt;/div&gt;&lt;br id="iqr7"&gt;&lt;/div&gt;&lt;div id="a5a_" style="margin-left: 40px;"&gt;다중 매니지드 오브젝트상의 데이터 전송을 결정할 때 다음 세가지를 고려하여야 합니다.&lt;br id="m4lc"&gt;When deciding where to break data up into multiple Managed Objects, consider these questions:&lt;br id="s_9m"&gt;&lt;ul id="wtdo"&gt;&lt;li id="efx."&gt;얼마나 큰 데이터입니까? 자신의 상태에 한 개의 매니지드 오브젝트를 포함하는 큰 데이터는 읽고 쓰는데 더 많은 시간을 요합니다.&lt;br id="ptt-"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div id="c9lc" style="margin-left: 40px;"&gt;How big is the data? The more data a single Managed Object encompasses in its state, the more time it takes to load and save.&lt;br id="jyne"&gt;&lt;/div&gt;&lt;ul id="x5ex"&gt;&lt;li id="effb"&gt;그 데이터의 결합도가 얼마나 가깝습니까? 일반적으로 공용으로 사용되는 데이터는 똑같은 매니지드 오브젝트에서 좀 더 효과적으로 저장됩니다. 독립적으로 사용되는 데이터는 다른 매니지드 오브젝트상으로 구분되기 위한 대상입니다. 핵심적으로 수정되어야 하는 데이터는 최우선적으로 같은 매니지드 오브젝트에 저장되어야 합니다.&lt;br id="wrxu"&gt;&lt;br /&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div id="dlus" style="margin-left: 40px;"&gt;&lt;br /&gt;How closely coupled is the data? Data that are generally accessed together are more efficiently stored in the same Managed Object. Data that are accessed independently are candidates for separation onto different Managed Objects. Data that have to be modified atomically are best stored in the same Managed Object.&lt;br id="fc9-"&gt;&lt;/div&gt;&lt;ul id="z:x4"&gt;&lt;li id="dztw"&gt;특정 데이터를 동시에 접근하여야 하는 태스크들이 얼마나 많습니까? 위에 언급한 것에 따르면, PDS는 가능한한 병렬로 실행되는 많은 태스크와 같이 실행되기 위한 최선책을 수행합니다. 다중 병령 수행되는 태스크가 같은 매니지드 오브젝트의 상태를 변경할 때 충돌을 피하는 것은 많은 비용이 소요됩니다.&lt;br id="csa:"&gt;&lt;br /&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div id="ux31" style="margin-left: 40px;"&gt;&lt;br /&gt;How many simultaneous tasks are going to need access to this data? As explained above, the PDS does its best to execute as many tasks in parallel as it can. Resolving the conflicts that arise when multiple parallel tasks want to change the state of the same ManagedObject can be expensive.&lt;br id="pww-"&gt;&lt;/div&gt;&lt;div id="inrq" style="margin-left: 40px;"&gt;get과 같이 공유될 수 있는 데이터를 업데이트하기 위하여 데이터에 lock을 거는 것이 데이터를 나누기 위한 최선책입니다. 단지 읽히는 데이터가 다중 태스크에 읽혀지는 것에의해 공유되는 것에 반하여, 업데이트되어야할 데이터는 업데이트하는 태스크에 의하여 수행되어야 합니다. 다중 태스크가 적어도 하나 이상의 태스크에 의해 업데이트되는 매니지드 오브젝트상의 항목들에 접근하여야 할 때, 매니지드 오브젝트는 병복에 걸릴 수 있습니다. 최고의 성능을 위하여 가능한한 적은 병목을 원할 것입니다.&lt;br id="k.j2"&gt;&lt;/div&gt;&lt;div id="jqt:" style="margin-left: 40px;"&gt;It is best to split up data that has to be locked for update from data that can be shared with a get. Data that is going to be updated has to be owned by the updating task, whereas data that is just read can be shared by multiple reading tasks. When multiple tasks have to access fields on a Managed Object that is being updated by at least one of them, that Managed Object becomes a potential bottleneck. For best performance, you want as few bottleneck Managed Objects as possible.&lt;br id="zd7t"&gt;&lt;/div&gt;이러한 고찰을 통하여 볼 때 세번째 고려사항은 잘 동작하는 PDS 어플리케이션을 작성하기 위하여 가장 크리티컬한 주제입니다.&lt;br id="k_hp"&gt;&lt;br /&gt;Of all these considerations, the third is the most critical to a well-running PDS application.&lt;br id="h.:a"&gt;&lt;/div&gt;&lt;br id="i7v4"&gt;&lt;div id="x6e0" style="margin-left: 40px;"&gt;&lt;font id="d1:d" size="4"&gt;플레이어 매니지드 오브젝트 (The Player Managed Object)&lt;/font&gt;&lt;br id="xmkm"&gt;외부에서 이벤트가 발생할 때 매니저에 의한 이벤트 핸들러가 get 메소드를 호출하기 위하여 매니지드 오브젝트는 그 자신을 등록할 것입니다. 첫번째 가장 중요한 매니지드 오브젝트 타입이 플레이어 매니지드 오브젝트 입니다. 플레이어 매니지드 오브젝트는 ClientSessionListener 인터페이스를 상속하고 AppListener의 loggedIn 콜백으로부터 리턴값을 받을 때 시스템에 리턴됩니다. 이 후, 어떤 입력되는 데이터 패킷과 게임 플레이어의 접속해제 이벤트에 의해 호출될 것입니다.&lt;br id="mm7-"&gt;플레이어 매니지드 오브젝트는 여러 매니지드 오브젝트 사이에서 마치 플레이어와 같이 동작을 수행할 것입니다. 게임 플레이어는 PDS Client API를 사용하여 서버로 데이터 패킷을 보냅니다. 이는 플레이어 매니지드 오브젝트의 userDataReceived 메소드를 호출하는 태스크의 결과로 시스템에서 userDataReceived 이벤트를 발생시킵니다. 플레이어 매니지드 오브젝트는 이를 수행함을 찾아내기 위해 패킷을 분석한 후, 필요한 자기 자신의 역할을 실행하며 요청된 태스크를 완료하기 위하여 다른 매니지드 오브젝트를 실행합니다.&lt;br id="h3f5"&gt;Managed Objects register themselves as event handlers with a manager in order to get called when outside events occur. One very important type of Managed Object is the Player Managed Object. A Player Managed Object implements the ClientSessionListener interface and is returned to the system as the return value from the loggedIn callback on the AppListener. From then on, it will get called for any incoming data packets and disconnect events from that player.&lt;br id="rgwh"&gt;The Player Managed Object acts as a proxy for the player in the world of Managed Objects. The player sends data packets to the server using the PDS Client API. This causes a userDataReceived event in the system, which results in a task that calls the Player Managed Object's userDataReceived method. The Player Managed Object should parse the packet to find out what it is supposed to do, and then act on itself and other Managed Objects in order to accomplish the requested task.&lt;br id="yjtu"&gt;&lt;/div&gt;&lt;br id="wwru"&gt;&lt;div id="ko05" style="margin-left: 40px;"&gt;Figure 2) 두 게임 플레이어가 PDS에 클라이언트로 연결되는 간단한 매니지드 오브젝트 구조&lt;br id="q-s."&gt;Figure 2 shows our simple Managed Object world, with two players connected to the PDS as clients.&lt;br id="lalg"&gt;&lt;/div&gt;&lt;br id="ifgk"&gt;&lt;div id="lrpw" style="padding: 1em 0pt; text-align: center;"&gt;&lt;a id="c_23" href="http://docs.google.com/File?id=ddcfsnv_13htmrjvc2" target="_blank"&gt;&lt;img id="m2i3" style="width: 389px; height: 406px;" src="http://docs.google.com/File?id=ddcfsnv_13htmrjvc2"&gt;&lt;/a&gt;&lt;/div&gt;&lt;div id="k58v" style="text-align: center;"&gt;Figure 2: Client connections to the simple ManagedObject world&lt;br id="uagf"&gt;&lt;/div&gt;&lt;br id="shb8"&gt;&lt;div id="w5bu" style="margin-left: 40px;"&gt;플레이어 매니지드 오브젝트는 룸 매니지드 오브젝트를 포인팅하는 매니지드 레퍼런스인 "current room" 필드를 갖고 있습니다. 룸 매니지드 오브젝트는 매니지드 레퍼런스의 리스트인 인벤토리 리스트를 갖고 있습니다. 현재, 이 리스트에는 세 아이템들이 있습니다. 두 게임 플레이어와 한 개의 칼입니다. 이들 각각은 매니지드 오브젝트를 표현하고 있습니다(Player 1 Managed Object, Player 2 Managed Object, and Sword Managed Object).&lt;br id="li75"&gt;The Player Managed Objects have a “current room” field, which is a Managed Reference that points to the Room Managed Object. The Room Managed Object has an inventory list, which is a list of Managed References. Currently, there are three items in the list: the two players and a sword. Each is represented by a Managed Object (Player 1 Managed Object, Player 2 Managed Object, and Sword Managed Object).&lt;br id="c_5g"&gt;&lt;/div&gt;&lt;br id="agxm"&gt;&lt;div id="jx_z" style="margin-left: 40px;"&gt;&lt;font id="tcr9" size="4"&gt;The AppListener&lt;/font&gt;&lt;br id="u4ut"&gt;룸 매니지드 오브젝트의 매니지드 오브젝트를 구성하는 월드 상위에, 소드 매니지드 오브젝트와 한 상의 플레이어 매니지드 오브젝트가 있습니다. 그러나 PDS에서 처음 게임을 시작할 때 매니지드 오브젝트의 월드는 이와같지 않습니다. 사실 그것은 다음과 같습니다.&lt;br id="wrye"&gt;Above we had a world of Managed Objects consisting of a Room Managed Object, a Sword Managed Object and a couple of Player Managed Objects. However, when we start the game in the PDS for the first time, the world of Managed Objects doesn't look like that. In fact it looks like this:&lt;br id="itn7"&gt;&lt;/div&gt;&lt;br id="kman"&gt;&lt;div id="h6ja" style="margin-left: 40px;"&gt;말하고자 하는 것은, 그렇습니다. 텅 비어 있다는 겁니다.&lt;br id="b1.6"&gt;첫번째로 오브젝트 스토어에 있는 매니지드 오브잭트가 얼마나 되겠습니까?&lt;br id="v-lz"&gt;그 때답은 AppListener라는 특별한 매니지드 오브젝트 하나입니다. AppListener를 특별하게 하는 두가지가 있습니다.&lt;br id="s09h"&gt;&lt;ul id="wz87"&gt;&lt;li id="ar7d"&gt;AppListener 인터페이스를 상속하면 다음 두 메소드를 정의하여야 합니다.&lt;/li&gt;&lt;ul id="rnni"&gt;&lt;li id="u_8e"&gt;initialize&lt;/li&gt;&lt;li id="vpki"&gt;loggedIn&lt;/li&gt;&lt;/ul&gt;&lt;li id="djxj"&gt;해당 어플리케이션의 AppListener에 상세히 기술되었습니다.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Which is to say, it is empty.&lt;br id="pwf2"&gt;How then do the Managed Objects get into the Object Store in the first place?&lt;br id="hxw8"&gt;The answer is a special Managed Object called the AppListener. There are two special things about the class that defines the AppListener:&lt;br id="jlsb"&gt;&lt;ul id="o1hc"&gt;&lt;li id="h3qh"&gt;It implements the AppListener interface. This interface defines two methods:&lt;/li&gt;&lt;ul id="jz5x"&gt;&lt;li id="fsu9"&gt;initialize&lt;/li&gt;&lt;li id="vw5j"&gt;loggedIn&lt;/li&gt;&lt;/ul&gt;&lt;li id="k-.z"&gt;It has been specified as the AppListener class for this application.&lt;/li&gt;&lt;/ul&gt;다음 방법을 따라 두가지 속성을 결합합니다.&lt;br id="ro2c"&gt;These two properties combine in the following way:&lt;br id="njdx"&gt;&lt;ul id="xxkd"&gt;&lt;li id="jst8"&gt;PDS가 부팅될 때(또는 PDS로 새로운 어플리케이션이 인스톨될 때), PDS는 오브젝트 스토어에 해당 어플리케이션에 동작하는 AppListener를 위치시킬 것입니다.&lt;br id="mnj4"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div id="gj7g" style="margin-left: 40px;"&gt;Upon the boot of the PDS (or the installation of a new application into the PDS), the PDS attempts to locate the AppListener for that application in the Object Store.&lt;/div&gt;&lt;ul id="fnv-"&gt;&lt;li id="q35l"&gt;어플리케이션이 이전에 부팅된 적이 없다면, 이 어플리케이션의 오브젝트 스토어는 공백상태가 될 것이며 PDS는 AppListener의 동작에 실패할 것입니다. 이러한 이유로 어플리케이션은 매니지드 오브젝트인 AppListener를 생성해야 하며 초기화를 호출하는 태스크를 시작하여야 합니다.&lt;br id="upfx"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div id="w0:n" style="margin-left: 40px;"&gt;If the application has never been booted before, then its Object Store in the PDS is blank (as in Figure 3), and the PDS will fail to find the AppListener. In that case, it creates the AppListener Managed Object itself, and then starts a task that calls initialize.&lt;/div&gt;&lt;ul id="l0lv"&gt;&lt;li id="qw4j"&gt;반대로, 어플리케이션이 적어도 한번 이상 부팅된 적이 있다면, 오브젝트 스토어는 이미 메니지드 오브젝트인 AppListener는 오브젝트 스토어내에 포함되어 있을 것입니다. 따라서, 시스템이 다운되었을 때, 새로운 연결이 시도되었을 때, 이전에 동작했었던 어떤 주기적인 태스크를 동작시키고자 할 때의 실행은 그냥 재시작만 하면 됩니다.&lt;br id="nbhs"&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div id="ues5" style="margin-left: 40px;"&gt;If, on the other hand, the application has been booted at least once, the Object Store will contain the AppListener Managed Object already. In this case, execution just resumes from where it left off when the system came down, listening for new connections and executing any periodic tasks that were running before.&lt;br id="z7qo"&gt;&lt;/div&gt;다음 데모 어플리케이션의 의사코드에서 이와 같은 점을 볼 수 있습니다.&lt;br id="fjn0"&gt;In the case of our little demo application, the boot method will have a block in it that, in pseudo-code, looks something like this:&lt;br id="luqx"&gt;&lt;/div&gt;&lt;div id="a.22"&gt;&lt;/div&gt;&lt;div id="cesj"&gt;&lt;br id="q90c"&gt;&lt;div id="s.f-"&gt;&lt;table id="l5xb" border="0" cellpadding="3" cellspacing="0" width="100%" class="zeroBorder"&gt;&lt;tbody id="pazl"&gt;&lt;tr id="ywbj"&gt;&lt;td id="pokv" width="100%"&gt;initialize {&lt;br id="d:8d"&gt;&lt;div id="edq9" style="margin-left: 40px;"&gt;&lt;br /&gt;CREATE ROOM MANAGED OBJECT&lt;br id="x5ax"&gt;&lt;br /&gt;CREATE SWORD MANAGED OBJECT&lt;br id="tz0_"&gt;&lt;br /&gt;ADD REF TO SWORD MANAGED OBJECT TO ROOM'S INVENTORY&lt;br id="k.mp"&gt;&lt;br /&gt;SAVE A MANAGED OBJECT REF TO ROOM FOR LATER&lt;br id="tu9x"&gt;&lt;/div&gt;&lt;br /&gt;}&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br id="fop8"&gt;&lt;/div&gt;&lt;div id="fkin" style="margin-left: 40px;"&gt;일반적으로, 처음 실행되는 동안의 매니지드 오브젝트의 초기화를 담당하는 것이 AppListener입니다.&lt;br id="qwzj"&gt;In general, it is the responsibility of the AppListener to create the initial world of Managed Objects during the first startup.&lt;br id="t1px"&gt;&lt;/div&gt;&lt;br id="zgbo"&gt;&lt;div id="an10" style="padding: 1em 0pt; text-align: center;"&gt;&lt;img id="ovzw" style="width: 389px; height: 392px;" src="http://docs.google.com/File?id=ddcfsnv_14frrdfbwf"&gt;&lt;/div&gt;&lt;div id="ujd1" style="text-align: center;"&gt;Figure 4: AppListener ManagedObject creates initial ManagedObject world&lt;br id="rcgo"&gt;&lt;/div&gt;&lt;br id="gywf"&gt;&lt;br id="mj6q"&gt;&lt;div id="jnks" style="text-align: left; margin-left: 40px;"&gt;이제 게임과 같은 윤곽이 드러났습니다. 그렇지만 아직 플레이어 매니지드 오브젝트는 없습니다. 여러분은 AppListener에서와 같은 방법으로 사용자 접속과 같은 플레이어 매니지드 오브젝트를 만들 것입니다. 보통 처음엔 사용자 로그인이 나타납니다. 그리고 그 사용자에 대한 플레이어 오브젝트를 생성시킵니다. 이후 매번 사용자가 로그인할 때 마다 존재하고 있는 해당 플레이어 매니지드 오브젝트를 연결하기만 하면 됩니다. 그러므로 시스템은 필요할 때 플레이어 매니지드 오브젝트를 생성하고 사용자 정보를 기억하고 있습니다.&lt;br id="k:bt"&gt;그렇다면 사용자가 로그인 할 때 어떤 작업을 수행하여야 하겠습니까?&lt;br id="vy1g"&gt;AppListener:loggIn 콜백이 그 해답입니다. 매번 사용자가 PDS 어플리케이션에 로그인할 때, 그 어플리케이션의 AppListener의 loggIn 메소드를 호출하는 태스크가 시작됩니다. AppListener의 loggIn 콜백이 호출된다면 다음 의사코드와 같이 기술된 코드에 따라 실행됩니다.&lt;br id="nzll"&gt;Now we have something that is beginning to look like our game. We still don't have Player Managed Objects, however. We will create the Player Managed Objects as users join, in much the same way the AppListener Managed Object was created. The first time we see a user log in, we create a new Player Managed Object for that user. After that, every time that user logs in, we just reconnect him to his existing Player Managed Object. Thus, the system creates Player Managed Objects as needed, and remembers user information between logins.&lt;br id="m-o3"&gt;So how do we find out when a user has logged in?&lt;br id="q9g4"&gt;The answer is the second callback on our AppListener: loggedIn. Every time a user logs into a PDS application, a task is started that calls the loggedIn method on the application's AppListener. When the loggedIn callback is called on our AppListener, it executes the following code, presented as pseudocode.&lt;br id="bxap"&gt;&lt;/div&gt;&lt;br id="qr.x"&gt;  &lt;div id="kz-o"&gt;&lt;table id="jc7p" border="0" cellpadding="3" cellspacing="0" width="100%" class="zeroBorder"&gt;&lt;tbody id="q58j"&gt;&lt;tr id="hh3q"&gt;&lt;td id="jsf5" width="100%"&gt;loggedIn {&lt;br id="d-ja"&gt;&lt;div id="t4ek" style="margin-left: 40px;"&gt;managedObject_name = “player_”+ SESSION.PLAYER_NAME;&lt;br id="y70j"&gt;IF MANAGED OBJECT EXISTS(managedObject_name){&lt;br id="gscv"&gt;&lt;div id="onxz" style="margin-left: 40px;"&gt;FIND MANAGED OBJECT(managedObject_name);&lt;br id="ml0g"&gt;&lt;/div&gt;} ELSE {&lt;br id="jo2k"&gt;&lt;div id="wvw6" style="margin-left: 40px;"&gt;CREATE NAMED PLAYER MANAGED OBJECT(managedObject_name);&lt;br id="iuzb"&gt;&lt;/div&gt;}&lt;br id="eukd"&gt;SET currentRoom on PLAYER MANAGED OBJECT&lt;br id="kya_"&gt;&lt;div id="ejot" style="margin-left: 40px;"&gt;TO SAVED MANAGED OBJECT REF TO ROOM&lt;br id="q:v_"&gt;&lt;/div&gt;GET ROOM MANAGED OBJECT&lt;br id="zda5"&gt;ADD PLAYER REF TO ROOM MANAGED OBJECT'S PLAYERS LIST&lt;br id="lbhd"&gt;REGISTER PLAYER MANAGED OBJECT AS SessionListener(SESSION);&lt;br id="acoq"&gt;&lt;/div&gt;}&lt;br id="l1b4"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br id="zctm"&gt;&lt;div id="lzsk" style="margin-left: 40px;"&gt;SessionListener는 또다른 이벤트 인터페이스입니다. 이는 서버로 데이터를 보내는 프로세스나 사용자의 로그아웃과 같은 client API를 사용하는 클라이언트의 액션에 대해 응답하는 태스크상의 get 메소드의 호출되는 메소드를 정의합니다.&lt;br id="kg4c"&gt;SessionListener is another event interface. It defines methods that get called on tasks to respond to actions the client takes with the client API, such as the client sending data to the server for processing and the client logging out.&lt;br id="ux-w"&gt;Figure 5) 매니지드 오브젝트들이 보여지기 시작되는 개요&lt;br id="g3vh"&gt;&lt;br /&gt;Figure 5 illustrates that our Managed Object world is starting to look the way we want it to.&lt;br id="s:d:"&gt;&lt;br /&gt;&lt;br id="gvvk"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div id="zqzl" style="padding: 1em 0pt; text-align: center;"&gt;&lt;img id="ai_s" style="width: 533px; height: 493px;" src="http://docs.google.com/File?id=ddcfsnv_15dqw6b4z4"&gt;&lt;/div&gt;&lt;div id="gjau" style="text-align: center;"&gt;Figure 5: Client sends data to server&lt;br id="sgwp"&gt;&lt;/div&gt;&lt;br id="vkfk"&gt;&lt;div id="maqm" style="margin-left: 40px;"&gt;두번째 사용자가 로그인 할 때 원래 월드가 이전에 있다는 것을 볼 수 있습니다.&lt;br id="yr9u"&gt;When a second user logs in, we will be back to our original world. &lt;br id="zumk"&gt;Figure 6) 이전 사용자를 포함한 게임상의 재시작 이후의 모형&lt;br id="ps.l"&gt;&lt;br /&gt;Figure 6 illustrates our world after restarting the game with our previous players:&lt;br id="qi_8"&gt;&lt;br /&gt;&lt;br id="lzt8"&gt;&lt;/div&gt;&lt;div id="bx5g" style="padding: 1em 0pt; text-align: center;"&gt;&lt;img id="k22v" style="width: 509px; height: 482px;" src="http://docs.google.com/File?id=ddcfsnv_16dtgfmxgm"&gt;&lt;/div&gt;&lt;div id="v3kx" style="text-align: center;"&gt;Figure 6: AppListener ManagedObject reestablishes simple world&lt;br id="jtfs"&gt;&lt;/div&gt;&lt;br id="atw6"&gt;&lt;div id="n_lf" style="margin-left: 40px;"&gt;지금까지 의사코드로만 로직이 보여졌습니다. 실행 가능한 코드는 부록A SwordWorld 어플리케이션과 같이 수록되어 있습니다. 실행 가능한 어플리케이션 코드는 간단한 명령어의 구현보다 이상의 것이며 사용자로부터 보내지는 명령들을 어떻게 핸들링해야 하는지를 보여줄 것입니다.&lt;br id="hrkp"&gt;&lt;/div&gt;&lt;div id="uoes" style="margin-left: 40px;"&gt;So far, the logic has been laid out in pseudo-code. The actual code to implement this application is included in Appendix A as the SwordWorld application. The actual application code goes a bit further in that it also implements a look command, to show you how the Player Managed Object actually handles commands being sent from the client.&lt;br id="cwzu"&gt;&lt;/div&gt;&lt;br id="ua:8"&gt;&lt;br id="rn_x"&gt;&lt;font id="ka65" size="4"&gt;서버 API 클래스 위치시키기 (Locating the Server API Classes)&lt;/font&gt;&lt;br id="ct8u"&gt;모든 PDS API 클래스는 com.sun.sgs.app.* 패키지에 포함되어 있습니다.&lt;br id="tk91"&gt;다음은 Project Darkstar Server API 클래스 상세입니다.&lt;br id="ao2e"&gt;All the Project Darkstar Server API classes are in the com.sun.sgs.app.* package.&lt;br id="yf45"&gt;These are the Project Darkstar Server API classes with brief descriptions:&lt;br id="du0y"&gt;&lt;br id="ywhg"&gt;&lt;div id="kkvc" style="margin-left: 40px;"&gt;&lt;b id="e-vu"&gt;System Classes and Interfaces&lt;/b&gt;&lt;br id="jm_s"&gt;&lt;div id="c5g2"&gt;&lt;table id="fmc:" border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" class="" width="100%"&gt;&lt;tbody id="zsc-"&gt;&lt;tr id="v4bq"&gt;&lt;td id="i5n5" style="background-color: rgb(255, 255, 255);" width="10%"&gt;Class&lt;br id="i7o2"&gt;&lt;/td&gt;&lt;td id="e6:2" style="background-color: rgb(255, 255, 255);" width="50%"&gt;Description&lt;br id="gp_s"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="d-y6"&gt;&lt;td id="elze" style="background-color: rgb(255, 255, 255);" width="10%"&gt;AppContext&lt;br id="xuyt"&gt;&lt;/td&gt;&lt;td id="qyci" style="background-color: rgb(255, 255, 255);" width="50%"&gt;해당 어플리케이션에서 가용한 자원 접근의 편의성을 제공합니다. 최초에 레퍼런스를 찾기 위해 매니저가 사용합니다. 이는 시스템에 어플리케이션의 코드를 실행하는 시작점입니다.&lt;br id="albp"&gt;Provides access to facilities available in the current application. Primarily used to find references to managers. This is the starting point for the application code to talk to the system.&lt;br id="x2j5"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="itwe"&gt;&lt;td id="naw0" style="background-color: rgb(255, 255, 255);" width="10%"&gt;AppListener&lt;br id="g7-l"&gt;&lt;/td&gt;&lt;td id="fjl3" style="background-color: rgb(255, 255, 255);" width="50%"&gt;어플리케이션 레벨의 이벤트를 위한 리스너를 제공하는 인터페이스입니다. 이 리스너는 어플리케이션이 최초 실행될 때 그리고 사용자 세션이 로그인 될 때 호출됩니다.&lt;br id="wma9"&gt;Interface representing a listener for application-level events. This listener is called when the application is started for the first time, and when client sessions log in.&lt;br id="c2py"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="exc1"&gt;&lt;td id="idl:" style="background-color: rgb(255, 255, 255);" width="10%"&gt;ManagerNotFoundException&lt;br id="a8qk"&gt;&lt;/td&gt;&lt;td id="ywym" style="background-color: rgb(255, 255, 255);" width="50%"&gt;요청된 매니저를 찾을 수 없을 때 발생합니다.&lt;br id="ob_y"&gt;Thrown when a requested manager is not found.&lt;/td&gt;&lt;/tr&gt;&lt;tr id="hxyh"&gt;&lt;td id="xgzz" style="background-color: rgb(255, 255, 255);" width="10%"&gt;ClientSession&lt;br id="j5yl"&gt;&lt;/td&gt;&lt;td id="h3mv" style="background-color: rgb(255, 255, 255);" width="50%"&gt;사용자와 서버간의 로그인 세션을 위해 하나씩 제공되는 인터페이스입니다.&lt;br id="jxko"&gt;Interface representing a single, connected login session between a client and the server.&lt;br id="x-eg"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="pw:w"&gt;&lt;td id="hc9_" style="background-color: rgb(255, 255, 255);" width="10%"&gt;ClientSessionListener&lt;br id="u:q4"&gt;&lt;/td&gt;&lt;td id="fi4e" style="background-color: rgb(255, 255, 255);" width="50%"&gt;서버에 참여한 클라이언트 세션으로부터 보내지는 메시지를 처리하기 위한 리스너입니다.&lt;br id="v1dg"&gt;Listener for messages sent from an associated client session to the server.&lt;br id="ew5e"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br id="cqua"&gt;&lt;div id="w_2e"&gt;&lt;/div&gt;&lt;/div&gt;&lt;br id="otyl"&gt;&lt;div id="vacq" style="margin-left: 40px;"&gt;&lt;b id="ttra"&gt;Task Manager Classes and Interfaces&lt;/b&gt;&lt;br id="s_au"&gt;&lt;div id="b7ax"&gt;&lt;table id="fmc:" border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" class="" width="100%"&gt;&lt;tbody id="dc4b"&gt;&lt;tr id="kuum"&gt;&lt;td id="blcb" style="background-color: rgb(255, 255, 255);" width="10%"&gt;Class&lt;br id="dsti"&gt;&lt;/td&gt;&lt;td id="y1jk" style="background-color: rgb(255, 255, 255);" width="50%"&gt;Description&lt;br id="mjxy"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="o4jz"&gt;&lt;td id="wize" style="background-color: rgb(255, 255, 255);" width="10%"&gt;TaskManager&lt;br id="bwjp"&gt;&lt;/td&gt;&lt;td id="qk-g" style="background-color: rgb(255, 255, 255);" width="50%"&gt;스케쥴된 태스크들의 편의성을 제공합니다.&lt;br id="dfvx"&gt;Provides facilities for scheduling tasks.&lt;br id="o4sz"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="h:xa"&gt;&lt;td id="ekci" style="background-color: rgb(255, 255, 255);" width="10%"&gt;Task&lt;br id="o0gs"&gt;&lt;/td&gt;&lt;td id="t6dv" style="background-color: rgb(255, 255, 255);" width="50%"&gt;태스크 매니저에 의해 실행되는 어플리케이션의 동작의 정의입니다.&lt;br id="tyml"&gt;Defines an application operation that will be run by the Task Manager.&lt;br id="m88y"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="ntfm"&gt;&lt;td id="d8sh" style="background-color: rgb(255, 255, 255);" width="10%"&gt;PeriodicTaskHandle&lt;br id="x:l4"&gt;&lt;/td&gt;&lt;td id="c-8t" style="background-color: rgb(255, 255, 255);" width="50%"&gt;주기적으로 실행되는 태스크 매니저의 태스크 스케줄에 대한 관리를 용이하게 합니다.&lt;br id="c4:b"&gt;Provides facilities for managing a task scheduled with the Task Manager to run periodically.&lt;br id="dvqf"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="v11a"&gt;&lt;td id="s5lk" style="background-color: rgb(255, 255, 255);" width="10%"&gt;TaskRejectedException&lt;br id="x_qq"&gt;&lt;/td&gt;&lt;td id="ypwe" style="background-color: rgb(255, 255, 255);" width="50%"&gt;자원의 제한으로 요청한 태스크를 거부하여 실패된 작업을 스케쥴링할 때 발생합니다. &lt;br id="ncxk"&gt;Thrown when an attempt to schedule a task fails because the Task Manager refuses to accept the task due to resource limitations.&lt;br id="lkhg"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="z0t9"&gt;&lt;td id="vmxz" style="background-color: rgb(255, 255, 255);" width="10%"&gt;ExceptionRetryStatus&lt;br id="cgyj"&gt;&lt;/td&gt;&lt;td id="ziaq" style="background-color: rgb(255, 255, 255);" width="50%"&gt;재요청이 필요한 예외가 발생할 때의 동작이 필요한 클래스의 예외 클래스의 구현입니다.&lt;br id="h4pf"&gt;Implemented by exception classes that want to control whether an operation that throws an exception of that exception should be retried.&lt;br id="arm_"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br id="erk7"&gt;&lt;/div&gt;&lt;br id="mu4a"&gt;&lt;div id="yhki" style="margin-left: 40px;"&gt;&lt;b id="hzbn"&gt;Data Manager Classes and Interfaces&lt;/b&gt;&lt;br id="vgbc"&gt;&lt;div id="renv"&gt;&lt;table id="fmc:" border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" class="" width="100%"&gt;&lt;tbody id="o0vf"&gt;&lt;tr id="jeg_"&gt;&lt;td id="tz6d" style="background-color: rgb(255, 255, 255);" width="10%"&gt;Class&lt;br id="xmtj"&gt;&lt;/td&gt;&lt;td id="n:a7" style="background-color: rgb(255, 255, 255);" width="50%"&gt;Description&lt;br id="z43q"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="twfj"&gt;&lt;td id="msk2" style="background-color: rgb(255, 255, 255);" width="10%"&gt;DataManager&lt;br id="ua_y"&gt;&lt;/td&gt;&lt;td id="hg7e" style="background-color: rgb(255, 255, 255);" width="50%"&gt;공유/퍼시스턴스 오브젝트 접근 관리의 편의성을 제공합니다.&lt;br id="h_f0"&gt;Provides facilities for managing access to shared,persistent objects.&lt;br id="tv9:"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="t7-0"&gt;&lt;td id="pxjg" style="background-color: rgb(255, 255, 255);" width="10%"&gt;ManagedObject&lt;br id="t6ls"&gt;&lt;/td&gt;&lt;td id="i7no" style="background-color: rgb(255, 255, 255);" width="50%"&gt;데이터 매니저에 의해 관리되는 공유/퍼스시턴스 오브젝트와 같은 인터페이스의 구현체입니다.&lt;br id="rp7-"&gt;A marker interface implemented by shared, persistent objects managed by the Data Manager.&lt;br id="dnze"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="l4yl"&gt;&lt;td id="g5tk" style="background-color: rgb(255, 255, 255);" width="10%"&gt;ManagedReference&lt;br id="of45"&gt;&lt;/td&gt;&lt;td id="rr.p" style="background-color: rgb(255, 255, 255);" width="50%"&gt;매니지드 오브젝트의 레퍼런스를 제공합니다.&lt;br id="hhxh"&gt;Represents a reference to a managed object.&lt;br id="ahji"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="j-8n"&gt;&lt;td id="bm7t" style="background-color: rgb(255, 255, 255);" width="10%"&gt;ObjectIOException&lt;br id="l223"&gt;&lt;/td&gt;&lt;td id="e8hi" style="background-color: rgb(255, 255, 255);" width="50%"&gt;매니지드 오브젝트를 접근시 I/O 오류가 있을 때 발생합니다.&lt;br id="bhaf"&gt;Thrown when an operation fails because of an I/O failure when attempting to access a Managed Object.&lt;br id="f5tp"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="utao"&gt;&lt;td id="a93b" style="background-color: rgb(255, 255, 255);" width="10%"&gt;ObjectNotFoundException&lt;/td&gt;&lt;td id="sy5:" style="background-color: rgb(255, 255, 255);" width="50%"&gt;매니지드 오브젝트를 접근할 때 그 오브젝트를 찾을 수 없을 때 발생합니다.&lt;br id="r5ls"&gt;Thrown when an operation fails because it attempted to refer to a Managed Object that was not found.&lt;br id="ok_e"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="n71w"&gt;&lt;td id="u3qt" style="background-color: rgb(255, 255, 255);" width="10%"&gt;TransactionAbortedException&lt;br id="qqo7"&gt;&lt;/td&gt;&lt;td id="jycn" style="background-color: rgb(255, 255, 255);" width="50%"&gt;어떤 동작에서 그 때의 트랜션이 시스템에 의해 중지되었을 때 발생합니다.&lt;br id="b5ga"&gt;Thrown when an operation fails because the system aborted the current transaction during the operation.&lt;br id="l6ou"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="ga9w"&gt;&lt;td id="g17s" style="background-color: rgb(255, 255, 255);" width="10%"&gt;TransactionConflictException&lt;br id="nt.d"&gt;&lt;/td&gt;&lt;td id="na0x" style="background-color: rgb(255, 255, 255);" width="50%"&gt;어떠한 동작이 다른 트랜잭션과 충돌이 일어나서 시스템이 해당 유효한 트랜잭션을 중지시켰을 때 발생합니다.&lt;br id="gl1g"&gt;Thrown when an operation fails because the system aborted the current transaction when it detected a conflict with another transaction.&lt;br id="ml-q"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="swny"&gt;&lt;td id="ll1p" style="background-color: rgb(255, 255, 255);" width="10%"&gt;TransactionException&lt;br id="qyer"&gt;&lt;/td&gt;&lt;td id="hfx_" style="background-color: rgb(255, 255, 255);" width="50%"&gt;유효한 트랜잭션이 오류를 일으켰을 때 발생합니다.&lt;br id="smkk"&gt;Thrown when an operation fails because of a problem with the current transaction.&lt;br id="x2k5"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="o8j2"&gt;&lt;td id="g_o5" style="background-color: rgb(255, 255, 255);" width="10%"&gt;TransactionNotActiveException&lt;br id="f.8:"&gt;&lt;/td&gt;&lt;td id="furk" style="background-color: rgb(255, 255, 255);" width="50%"&gt;유효하지는 않지만 동작하고 있는 트랜잭션이 오류를 일으켰을 때 발생합니다.&lt;br id="c88."&gt;Thrown when an operation fails because there is no current, active transaction.&lt;br id="q64s"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="nib5"&gt;&lt;td id="lf7g" style="background-color: rgb(255, 255, 255);" width="10%"&gt;TransactionTimeoutException&lt;br id="c5ci"&gt;&lt;/td&gt;&lt;td id="sjfq" style="background-color: rgb(255, 255, 255);" width="50%"&gt;허용된 최대의 트랜잭션 숫자를 넘어서 유효한 동작을 시스템이 중지시켰을 때 발생합니다.&lt;br id="ogau"&gt;Thrown when an operation fails because the system aborted the current transaction when it exceeded the maximum permitted duration.&lt;br id="d0jn"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="sjxu"&gt;&lt;td id="ipp-" style="background-color: rgb(255, 255, 255);" width="10%"&gt;NameNotBoundException&lt;br id="y5rz"&gt;&lt;/td&gt;&lt;td id="sh9d" style="background-color: rgb(255, 255, 255);" width="50%"&gt;바운드되지 않은 오브젝트를 참조하였을 때 발생합니다.&lt;br id="kzao"&gt;Thrown when an operation fails because it referred to a name that was not bound to an object.&lt;br id="o2dz"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br id="acal"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br id="t5fq"&gt;&lt;div id="ipuh" style="margin-left: 40px;"&gt;&lt;b id="t2-:"&gt;Channel Manager Classes and Interfaces&lt;/b&gt;&lt;br id="q1xt"&gt;&lt;div id="g_pi"&gt;&lt;table id="fmc:" border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" class="" width="100%"&gt;&lt;tbody id="nfsd"&gt;&lt;tr id="qfb7"&gt;&lt;td id="ntfv" style="background-color: rgb(255, 255, 255);" width="10%"&gt;Class&lt;br id="xsjd"&gt;&lt;/td&gt;&lt;td id="t5wq" style="background-color: rgb(255, 255, 255);" width="50%"&gt;Description&lt;br id="ichc"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="fp92"&gt;&lt;td id="ti52" style="background-color: rgb(255, 255, 255);" width="10%"&gt;ChannelManager&lt;br id="qb-f"&gt;&lt;/td&gt;&lt;td id="akfn" style="background-color: rgb(255, 255, 255);" width="50%"&gt;채널을 획득하거나 생성하기 위한 매니저입니다.&lt;br id="ot.p"&gt;Manager for creating and obtaining channels.&lt;br id="g8gf"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="ymiu"&gt;&lt;td id="vlmi" style="background-color: rgb(255, 255, 255);" width="10%"&gt;Channel&lt;br id="cwvt"&gt;&lt;/td&gt;&lt;td id="rb3t" style="background-color: rgb(255, 255, 255);" width="50%"&gt;다중 사용자 세션과 서버간에 존재하는 통신그룹을 제공하는 인터페이스입니다.&lt;br id="lnr-"&gt;Interface representing a communication group, a channel consisting of multiple client sessions and the server.&lt;/td&gt;&lt;/tr&gt;&lt;tr id="q8ps"&gt;&lt;td id="hadw" style="background-color: rgb(255, 255, 255);" width="10%"&gt;ChannelListener&lt;br id="g_ss"&gt;&lt;/td&gt;&lt;td id="rb.2" style="background-color: rgb(255, 255, 255);" width="50%"&gt;한 채널은 ChannelListener에 의해 생성될 수 있으며, ChannelListener는 어떠한 사용자 세션에서 한 채널로 메시지를 보냈을 때 이를 통지합니다. 추가적으로 서버는 한 세션당 한 리스너를 지정할 수 있습니다.(채널에 사용자 세션이 참가하였을 때 채널상의 각 사용자 세션에 의해 보내지는 메제지를 통지할 수도 있습니다.)&lt;br id="n.e5"&gt;A channel can be created with a ChannelListener, which is notified when any client session sends a message on that channel. Additionally, a server can specify a per-session listener (to be notified when messages are sent by an individual client session on a channel when joining a client session to a channel).&lt;/td&gt;&lt;/tr&gt;&lt;tr id="l3w1"&gt;&lt;td id="pe7o" style="background-color: rgb(255, 255, 255);" width="10%"&gt;Delivery&lt;br id="e5lw"&gt;&lt;/td&gt;&lt;td id="huaa" style="background-color: rgb(255, 255, 255);" width="50%"&gt;메세지 전달 요청을 제공합니다.  하나의 전달요청은 하나의 채널을 생성합니다. &lt;br id="vhhp"&gt;Representation for message delivery requirements. A channel is created with a delivery requirement.&lt;/td&gt;&lt;/tr&gt;&lt;tr id="px1y"&gt;&lt;td id="tyug" style="background-color: rgb(255, 255, 255);" width="10%"&gt;NameExistsException&lt;br id="pzm:"&gt;&lt;/td&gt;&lt;td id="n-v:" style="background-color: rgb(255, 255, 255);" width="50%"&gt;바운드되지 않은 오브젝트를 참조하였을 때 발생합니다.&lt;br id="i38m"&gt;Thrown when an operation fails because it referred to a name that is currently bound to an object.&lt;/td&gt;&lt;/tr&gt;&lt;tr id="c6v:"&gt;&lt;td id="h2md" style="background-color: rgb(255, 255, 255);" width="10%"&gt;NameNotBoundException&lt;br id="ti68"&gt;&lt;/td&gt;&lt;td id="hhbo" style="background-color: rgb(255, 255, 255);" width="50%"&gt;ChannelManager.getChannel()로 채널의 이름을 지정할 때 채널이 바운드되지 않는다면 NameNotBoundException이 발생합니다.&lt;br id="vg7t"&gt;Thrown if a channel is not bound to a name specified to ChannelManager.getChannel().&lt;br id="u2k4"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br id="ptuu"&gt;&lt;/div&gt;&lt;br id="fytw"&gt;&lt;br id="ukro"&gt;&lt;br id="ds9a"&gt;&lt;br id="jn_o"&gt;&lt;font id="dyhq" size="5"&gt;Lesson One: Hello World!&lt;/font&gt;&lt;br id="n07k"&gt;전통적으로 어떠한 튜토리얼이던지 첫번째 예제는 콘솔에 "HelloWorld"를 출력하는 간단한 프로그램입니다. 이는 아무리 간단한 어플리케이션이라도 어플리케이션 로직의 진짜 세상에 도달하기 전 요구되는 추측들을 예상할 수 있게 합니다. 간단하게 시작하기 위하여, 이번 레슨과 다음 두 레슨은 client-server 네트웍을 시작하는 것 보다느 그냥 서버 콘촐에 출력하는 방법을 따릅니다. 클라이언트가 접속되어 있다 하여도, 서버측 로그 메세지는 어플리케이션을 모니터링하는 것과 디버깅에 매우 중요합니다.&lt;br id="w-6r"&gt;It is traditional in any programming tutorial for the first example to be a simple program that prints “HelloWorld” to the console. This lets a programmer see the plumbing required to start even a basic application before diving into real-world application logic. For simplicity, this lesson and the two that follow it print their output on the server console, rather than starting&lt;br id="qv4b"&gt;off with client-server networking. Even when a client is connected, server-side log messages are invaluable for debugging and monitoring the application.&lt;br id="yz3k"&gt;&lt;br id="xvvy"&gt;&lt;font id="cjuf" size="4"&gt;HelloWorld 코딩하기 (Coding HelloWorld)&lt;/font&gt;&lt;br id="gf3r"&gt;모든 PDS 어플리케이션은 AppListener와 함께 시작합니다. AppListener는 어플리케이션의 시작과 사용자 로그인 이벤트를 핸들링하는 객체입니다. 어플리케이션의 AppListener는 AppListener 인터페이스의 간단한 구현 클래스입니다. AppListener 또한 매니지드 오브젝트이지만 AppListener는 마커 인터페이스인 Serializable 인터페이스를 반드시 상속하여야 합니다.&lt;br id="yojn"&gt;위에 언급한 내용에 따르면, AppListener는 두 메소드를 포함합니다. initialize와 loggedIn 입니다. 어플리케이션의 오브젝트 스토어가 비어있든 그렇지 않든 initialize 메소드는 어플리케이션이 처음 시작할 때 호출됩니다. 어플리케이션의 오브젝트 스토어가 삭제되거나 시스템이 깨끗한 "전혀 실행된 적이 없는" 상태가 아닌 이상, 관례적으로 이 뜻은 어플리케이션 하나당 한번 생성된다는 뜻입니다.&lt;br id="w9-n"&gt;HelloWorld AppListener는 다음과 같습니다.&lt;br id="k2av"&gt;All PDS applications start with an AppListener. An AppListener is the object that handles an application's startup and client login events. An application's AppListener is simply a class that implements the AppListener interface. Since an AppListener is also a Managed Object, it must implement the Serializable marker interface as well.&lt;br id="thfg"&gt;As mentioned above, AppListener contains two methods: initialize and loggedIn. The initialize method gets called on the startup of the application if and only if the Object Store for this application is empty. The AppListener is automatically created in the Object Store by the system the first time the application is started up; in practice, this means that it is created once per application, unless the Object Store for this application is deleted and the system is returned to its pristine “never having run this application” state. 6&lt;br id="htdq"&gt;A “Hello World” AppListener looks like this:&lt;br id="xca-"&gt;&lt;br id="sd::"&gt;&lt;div id="s481"&gt;&lt;table id="kcsw" border="0" cellpadding="3" cellspacing="0" width="100%" class="zeroBorder"&gt;&lt;tbody id="rk77"&gt;&lt;tr id="v.8y"&gt;&lt;td id="ozqt" width="100%"&gt;&lt;font id="m9p3" size="4"&gt;HelloWorld&lt;/font&gt;&lt;br id="k7vo"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="xmnn"&gt;&lt;td id="ne2p" width="100%"&gt;/*&lt;br id="up:j"&gt;* Copyright 2007 Sun Microsystems, Inc.&lt;br id="oej9"&gt;*&lt;br id="ltze"&gt;* This file is part of Project Darkstar Server.&lt;br id="urm3"&gt;*&lt;br id="l2gp"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;br id="ohnp"&gt;* and/or modify it under the terms of the GNU General Public License&lt;br id="bzsa"&gt;* version 3 as published by the Free Software Foundation and&lt;br id="m2gs"&gt;* distributed hereunder to you.&lt;br id="u2kp"&gt;*&lt;br id="bgb3"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;br id="geur"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br id="r59v"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;br id="z4qi"&gt;* GNU General Public License for more details.&lt;br id="z21l"&gt;*&lt;br id="k3d2"&gt;* You should have received a copy of the GNU General Public License&lt;br id="fsu:"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;br id="cosy"&gt;*/&lt;br id="nc04"&gt;package com.sun.sgs.tutorial.server.lesson1;&lt;br id="pdvb"&gt;import java.io.Serializable;&lt;br id="jiw2"&gt;import java.util.Properties;&lt;br id="b97u"&gt;import com.sun.sgs.app.AppListener;&lt;br id="z_.t"&gt;import com.sun.sgs.app.ClientSession;&lt;br id="tm_b"&gt;import com.sun.sgs.app.ClientSessionListener;&lt;br id="eelx"&gt;/**&lt;br id="ltyb"&gt;* Hello World example for the Project Darkstar Server.&lt;br id="dbi0"&gt;* Prints {@code "Hello World!"} to the console the first time it's&lt;br id="dcve"&gt;* started.&lt;br id="uo0x"&gt;*/&lt;br id="utsu"&gt;public class HelloWorld implements AppListener, // to get called during application startup.&lt;br id="z93g"&gt;                                              Serializable // since all AppListeners are ManagedObjects.&lt;br id="dxz5"&gt;{&lt;br id="kq0g"&gt;&lt;div id="s5vr" style="margin-left: 40px;"&gt;/** The version of the serialized form of this class. */&lt;br id="ente"&gt;private static final long serialVersionUID = 1L;&lt;br id="z_xl"&gt;&lt;br id="k_73"&gt;/**&lt;br id="v7gh"&gt;* {@inheritDoc}&lt;br id="y487"&gt;* &amp;lt;p&gt;&lt;br id="htk7"&gt;* Prints our well-known greeting during application startup.&lt;br id="y6yb"&gt;*/&lt;br id="gi9a"&gt;public void initialize(Properties props) {&lt;br id="g-ib"&gt;&lt;div id="d_s6" style="margin-left: 40px;"&gt;System.out.println("Hello World!");&lt;br id="v40_"&gt;&lt;/div&gt;}&lt;br id="h_aj"&gt;&lt;br id="d7q6"&gt;/**&lt;br id="d2q3"&gt;* {@inheritDoc}&lt;br id="z9.h"&gt;* &amp;lt;p&gt;&lt;br id="lvj2"&gt;* Prevents client logins by returning {@code null}.&lt;br id="fh:s"&gt;*/&lt;br id="p.es"&gt;public ClientSessionListener loggedIn(ClientSession session) {&lt;br id="m_72"&gt;&lt;div id="nt90" style="margin-left: 40px;"&gt;return null;&lt;br id="w864"&gt;&lt;/div&gt;}&lt;br id="ganm"&gt;&lt;/div&gt;}&lt;br id="okmi"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br id="x04f"&gt;&lt;br id="dsev"&gt;&lt;font id="rchm" size="4"&gt;HelloWorld 실행하기 (Running HelloWorld)&lt;/font&gt;&lt;br id="b51t"&gt;HelloWorld를 실행하려면 다음과 같은 것이 필요합니다.&lt;br id="of_v"&gt;To run HelloWorld you need the following:&lt;br id="o.t4"&gt;&lt;ul id="ip49"&gt;&lt;li id="gwqz"&gt;여러분의 시스템에 Project Darkstar Server가 설치되어야 합니다.&lt;br id="g32v"&gt;&lt;/li&gt;&lt;li id="u6sl"&gt;The Project Darkstar Server installed on your system.&lt;/li&gt;&lt;li id="el0q"&gt;1.5.0_11 이상의 JDK™ 5 가 설치되어야 합니다. 설치된 버전은 다음 명령으로 확인할 수 있습니다.&lt;br id="zr5:"&gt;&lt;/li&gt;&lt;li id="c0ab"&gt;A JDK™ 5 installation, version 1.5.0_11 or better. The version can be found with:&lt;/li&gt;&lt;/ul&gt;&lt;div id="hiam" style="margin-left: 120px;"&gt;java -version&lt;br id="x.n2"&gt;&lt;/div&gt;&lt;div id="bh:h" style="margin-left: 40px;"&gt;path에 자바가 걸려있지 않다면 JAVA_HOME에 자바가 설치된 경로의 root를 설정하여야 합니다.&lt;br id="mc91"&gt;If java is not in your default execution path, you will need to set JAVA_HOME to point to the root of its installation on your system.&lt;br id="zcqt"&gt;&lt;br id="er_5"&gt;&lt;div id="qfc:"&gt;&lt;table id="m08l" bgcolor="#cccccc" border="0" cellpadding="3" cellspacing="0" class="zeroBorder"&gt;&lt;tbody id="y28a"&gt;&lt;tr id="dc-8"&gt;&lt;td id="lfu2" width="100%"&gt;&lt;div id="rp8e" style="text-align: center;"&gt;&lt;font id="bnga" size="4"&gt;Path 규칙(Path Conventions)&lt;/font&gt;&lt;br id="m.sg"&gt;&lt;/div&gt;Unix 또는 Unix와 같은 시스템은 디렉토리의 경로를 슬래쉬(/)로 구분합니다. 그러나 Win32에서는 역슬래쉬(\)로 표기합니다. 이 문서는 특별히 윈도우즈의 표기법을 설명하지 않는 한 Unix의 표기법을 따릅니다.&lt;br id="p82s"&gt;여러분이 윈도우즈에서 작업한다면 슬래쉬로 표기된 경로를 바꾸어야 한다는 것을 기억하십시오.&lt;br id="ug95"&gt;Unix and many Unix-derived systems use a forward slash (/) to show subdirectories in a file path. Win32, however, uses a backslash (\) for this purpose. Throughout this document we use the Unix convention for file paths unless it is in a Windows-specific example.&lt;br id="rvm4"&gt;Please remember that you may have to substitute backslashes for forward slashes in the generic examples if you are working in Windows.&lt;br id="mqcp"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br id="vtj2"&gt;&lt;/div&gt;튜토리얼의 폴더를 보시면 컴파일된 tutorial.jar 파일에서 모든 튜토리얼의 예제를 찾을 수 있습니다. 모든 각각의 예제는 오브젝트 스토어의 데이터를 포함한 데이터 서브디렉토리가 포함되어 있습니다.&lt;br id="g5hh"&gt;The tutorial.jar file in the tutorial folder contains pre-compiled .class files for all the tutorial examples. The data directory contains subdirectories for the object store data for all the different examples.&lt;br id="za:d"&gt;&lt;br id="q0dn"&gt;여러분의 컴퓨터에 PDS가 인스톨되어 있는 루트 디록토리에서 sgs 스크립트를 실행하여 튜토리얼 예제를 실행할 수 있습니다. &lt;br id="qtil"&gt;You run a tutorial example by using the sgs script in the root of the PDS installation on your computer. It has the following form:&lt;br id="y1_n"&gt;&lt;ul id="m1_f"&gt;&lt;li id="uhb1"&gt;For Unix:&lt;/li&gt;&lt;/ul&gt;&lt;div id="mhqq" style="margin-left: 80px;"&gt;sgs.sh app_classpath app_config_file …&lt;br id="edi0"&gt;&lt;/div&gt;&lt;ul id="t00h"&gt;&lt;li id="hcun"&gt;For Windows:&lt;/li&gt;&lt;/ul&gt;&lt;div id="mofv" style="margin-left: 80px;"&gt;sgs app_classpath app_config_file …&lt;br id="ltqa"&gt;&lt;/div&gt;app_classpath는 어플리케이션 클래스들이 위치하고 있는 디폴트 경로이고, app_config_file은 실행하고자 하는 각 어플리케이션의 설정파일입니다.(이 튜토리얼에서는 일반적으로 한번에 한번 실행할 것입니다.) 설정된 경로에 기본 설정 파일이 제공되어 있을 것입니다. 해당 경로는 SDK가 설치된 경로의 tutorial 폴더에 있습니다. 이제 설정된 경로에서 HelloWorld를 실행하기위해 다음을 따르십시오.&lt;br id="zuv4"&gt;Where app_classpath is a default classpath in which to find the application classes, and app_config_file … are configuration files for each application you want to launch. (In this tutorial you will generally only launch one at a time.)&lt;br id="zqph"&gt;We have provided default configuration files that use relative paths. These paths assume your working directory is the tutorial folder in the SDK. So, to run HelloWorld as it is shipped to you in the tutorial directories, do the following:&lt;br id="s.z5"&gt;&lt;ol id="af4t"&gt;&lt;li id="xuw."&gt;PDS가 설치되어 있는 경로로 SGSHOME 환경변수를 추가합니다. Add the environment variable SGSHOME to your environment and set it to the directory where you installed the Project Darkstar Server.&lt;/li&gt;&lt;li id="uwk0"&gt;SGSHOME 환경변수를 path에 추가합니다. Add SGSHOME to your execution path, where SGSHOME is your PDS install directory.&lt;/li&gt;&lt;li id="yjsj"&gt;쉘을 엽니다. Open a Unix shell, a Windows command window, or whatever you do to get a command line on your development system.&lt;/li&gt;&lt;li id="vrp4"&gt;튜토리얼 디렉토리로 이동합니다. 유닉스 환경이라면 다음과 같이 명령을 낼 것입니다. Change your working directory to the tutorial directory of your PDS. In Unix, the command might be something like this:&lt;/li&gt;&lt;/ol&gt;&lt;div id="xkck" style="margin-left: 80px;"&gt;cd ~/sgs/tutorial&lt;br id="zfz6"&gt;&lt;/div&gt;&lt;ol id="jj6n" start="5"&gt;&lt;li id="icsh"&gt;다음을 타이핑 하십시오. Type the following:&lt;/li&gt;&lt;/ol&gt;&lt;ul id="w0ky" style="margin-left: 40px;"&gt;&lt;li id="u9:e"&gt;For Unix:&lt;/li&gt;&lt;/ul&gt;&lt;div id="abvm" style="margin-left: 120px;"&gt;sgs.sh tutorial.jar HelloWorld.properties&lt;/div&gt;&lt;ul id="gc7i" style="margin-left: 40px;"&gt;&lt;li id="lwtm"&gt;For Windows:&lt;/li&gt;&lt;/ul&gt;&lt;div id="nbvt" style="margin-left: 120px;"&gt;sgs tutorial.jar HelloWorld.properties&lt;br id="orz6"&gt;&lt;/div&gt;&lt;ol id="yqjg"&gt;&lt;li id="x5re"&gt;Add the environment variable SGSHOME to your environment and&lt;br /&gt;set it to the directory where you installed the Project Darkstar Server.&lt;/li&gt;&lt;li id="y.1t"&gt;Add SGSHOME to your execution path, where SGSHOME is your PDS install directory.&lt;/li&gt;&lt;li id="f_0j"&gt;Open a Unix shell, a Windows command window, or whatever you do to get a command line on your development system.&lt;/li&gt;&lt;li id="w:6o"&gt;Change your working directory to the tutorial directory of your PDS. In Unix, the command might be something like this:&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div id="qgwz" style="margin-left: 80px;"&gt;cd ~/sgs/tutorial&lt;br id="mmr_"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;ol id="e1wy" start="5"&gt;&lt;li id="et.f"&gt;Type the following:&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;ul id="wcb_" style="margin-left: 40px;"&gt;&lt;li id="d_fy"&gt;For Unix:&lt;/li&gt;&lt;/ul&gt;&lt;div id="w45_" style="margin-left: 120px;"&gt;sgs.sh tutorial.jar HelloWorld.properties&lt;/div&gt;&lt;ul id="qzdd" style="margin-left: 40px;"&gt;&lt;li id="n.2_"&gt;For Windows:&lt;/li&gt;&lt;/ul&gt;&lt;div id="qd3j" style="margin-left: 120px;"&gt;sgs tutorial.jar HelloWorld.properties&lt;br id="mg:s"&gt;&lt;/div&gt;여러분은 "HelloWorld!"라는 출력을 표준출력으로 볼 수 있을 것이고 이후는 동작하지 않을  것입니다. 이 시점에서 여러분은 어플리케이션을 강제종료할 수 있읍니다. 유닉스 또는 윈도우즈 환경에서 Ctrl-c를 눌러 서버를 종료하고 프롬프트로 돌아갈 수 있습니다. 구미가 당긴다면 PDS 어플리케이션의 시작 스크립트인 sgs.bat 또는 sgs.sh를 시험해볼 수 있고, PDS에서 어플리케이션 설정이 어떻게 되어 있는지에 대한 상세한 내용을 HelloWorld.properties 파일을 통하여 볼 수 있습니다.&lt;br id="bnpm"&gt;You should see the application print out “Hello World!” to standard output (as well as a couple of PDS startup log messages) and then sit doing nothing. At this point you can kill the application; in Unix or Win32, just type Ctrl-c in the shell window to stop the server and get the prompt back. If you are interested, you can examine the script files sgs.bat and sgs.sh to see how to run PDS applications, and the HelloWorld.properties file to see the details of how you set up an application configuration to run in the PDS.&lt;br id="xytj"&gt;&lt;br id="pnb4"&gt;&lt;div id="k62s"&gt;&lt;table id="stfi" bgcolor="#cccccc" border="0" cellpadding="3" cellspacing="0" width="100%" class="zeroBorder"&gt;&lt;tbody id="j1tt"&gt;&lt;tr id="p051"&gt;&lt;td id="u8_t" width="100%"&gt;(역자주:PDS 어플리케이션이 동작하고 개발환경을 설정하기 위해, 또 PDS 소스로부터 sgs.jar로 컴파일하려고 한동안 삽질했었습니다. 또 다른 뉴비가 삽질하지 않도록 실행, 디버그 환경을 설정하는 방법을 남깁니다.)&lt;br id="n08x"&gt;&lt;br /&gt;개발 OS는 Windows XP이고, JDK 1.6, eclipse 3.2 입니다.&lt;br id="r9y8"&gt;&lt;br /&gt;&lt;ol id="cfk7"&gt;&lt;li id="cj77"&gt;CLASSPATH가 제대로 되어 있는지 확인하세요.&lt;/li&gt;&lt;li id="sh-m"&gt;eclipse가 제대로 구동되는지 확인하세요.&lt;/li&gt;&lt;li id="ln2:"&gt;Project Darkstar Server 바이너리(sgs-0.9.5.1-r3730.zip)를 다운로드하고 압축을 풀면 다음과 같은 디렉토리를 볼 수 있습니다.&lt;/li&gt;&lt;ol id="ju8f"&gt;&lt;li id="hf__"&gt;bdb-4.5.20&lt;br id="lxu."&gt;&lt;br /&gt; &lt;/li&gt;&lt;li id="jrpd"&gt;mina-1.1&lt;/li&gt;&lt;li id="xdnm"&gt;sgs-0.9.5.1-r3730&lt;/li&gt;&lt;li id="l200"&gt;slf4j-1.4.0&lt;/li&gt;&lt;/ol&gt;&lt;li id="xqa7"&gt;sgs-0.9.5.1-r3730 디렉토리를 eclipse의 workplace에 복사하고 darkstar라고 디렉토리명을 바꾸세요.&lt;br id="cyi2"&gt;&lt;br /&gt; &lt;/li&gt;&lt;li id="jjqj"&gt;bdb-4.5.20 디렉토리의 이름을 bdb로 변경하고 darkstar\lib에 bdb 디렉토리를 통채로 복사하세요. 그러면 darkstar\lib\bdbdb.jar, darkstar\lib\bdb\win32-x86 와 같이 디렉토리, 파일이 설정될 겁니다.&lt;/li&gt;&lt;li id="l2bi"&gt;환경변수에 SGSHOME을 설정하세요, 제 경우는 D:\src\workplace\darkstar 이렇게 되었습니다.&lt;/li&gt;&lt;li id="xf-c"&gt;PATH에도 SGSHOME을 추가해주세요.&lt;/li&gt;&lt;li id="twpi"&gt;eclipse를 실행하시고 새 프로젝트를 만듭니다. 이클립스의 메뉴에 File -&gt; New -&gt; Java Project 를 선택하시면 됩니다.&lt;/li&gt;&lt;li id="gw76"&gt;Content 박스에 Create project from existing source를 선택하시고, Browse 버튼을 클릭하여 SGSHOME로 설정한 PDS를 설치한 경로를 선택하세요.&lt;/li&gt;&lt;li id="e7om"&gt;Project Name은 반드시 darkstar가 되어야 할 겁니다. 그렇게하고 Finish 버튼을 눌러 프로젝트를 만들면 알아서 lib등의 경로를 검색하여 프로젝트를 구성할 겁니다.&lt;/li&gt;&lt;li id="y9:i"&gt;SGSHOME 디렉토리에 새 파일을 만들어 이름을 Main.launch라고 지정합니다.&lt;/li&gt;&lt;li id="pvgy"&gt;Main.luanch을 텍스트 에디터로 열어 http://www.projectdarkstar.com/wiki/doku.php/darkstar.launch 의 내용을 기록하고 저장하세요.&lt;/li&gt;&lt;li id="xak_"&gt;이클립스의 Package Editor를 리프레쉬(F5)하면 Main.luanch 파일이 추가되어 있을 것이고 Run 버튼에 Main 메뉴가 추가되었을 것입니다. &lt;br id="liys"&gt;&lt;br /&gt; &lt;/li&gt;&lt;li id="rpk1"&gt;Run 버튼을 누르면 파일을 선택할 다이얼로그가 보일 것인데, *.properties 파일을 선택하시면 PDS가 실행될 것입니다.&lt;/li&gt;&lt;ol id="jwl7"&gt;&lt;li id="id28"&gt;여기서 잠깐! .properties 파일을 열어보면 com.sun.sgs.app.root=data/HelloWorld 라고 적혀 있는것을 볼 수 있습니다.&lt;/li&gt;&lt;li id="szq3"&gt;SGSHOME은 D:\src\workplace\darkstar 이라고 설정되었을때 어플리케이션의 루트(com.sun.sgs.app.root)는 D:\src\workplace\darkstar이고 튜토리얼의 .properties에 기술된 대로 실행된다면 D:\src\workplace\darkstar\data\HelloWorld에서 어플리케이션을 실행하려고 하여 에러가 뜹니다. &lt;/li&gt;&lt;li id="biw_"&gt;정상적으로 실행하려면 .properties의 com.sun.sgs.app.root=data/HelloWorld를 com.sun.sgs.app.root=tutorial/data/HelloWorld로 바꾸시거나 tutorial의 모든 파일과 디렉토리를 SGSHOME에 복사하셔야 합니다. 전 전자를 택했습니다.&lt;br id="r7ed"&gt;&lt;br /&gt; &lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br id="e_t_"&gt;&lt;br id="exfb"&gt;&lt;br id="s5ty"&gt;&lt;br id="z7w9"&gt;&lt;br id="w4-2"&gt;&lt;br id="b97t"&gt;&lt;div id="t9h:" style="margin-left: 40px;"&gt;&lt;b id="n4gf"&gt;HelloWorld 재시작하기 (Rerunning HelloWorld)&lt;/b&gt;&lt;br id="lqt8"&gt;PDS를 중지하고 HelloWorld 어플리케이션을 다시 동작시키려 한다면, "HelloWorld!" 출력이 나오질 않고 에러를 보게 될 것입니다. 이는 오브젝트 스토어에 이전에 동작하고 있던 AppListener가 이미 존재하므로 호출되지 않았던 초기화를 하여야 합니다. &lt;br id="g_n."&gt;HelloWorld를 다시 동작하고 싶다면, 여러분은 오브젝트 스토어의 내용을 지워야 합니다&lt;br id="a6eb"&gt;&lt;ul id="ggff"&gt;&lt;li id="rmw6"&gt;For Unix:&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div id="zkro" style="margin-left: 80px;"&gt;rm -r data/HelloWorld/dsdb/*&lt;br id="ix2l"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;ul id="qy6s"&gt;&lt;li id="vt::"&gt; For Windows:&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div id="b46q" style="margin-left: 80px;"&gt;del /s data\HelloWorld\dsdb\*.*&lt;br id="dkz4"&gt;&lt;br /&gt;&lt;/div&gt;(역자주 : 저도 지우려고 했는데 잘 지워지지 않더군요. JVM을 Kill해도 dll로 호출된(bds)것들이 아직 메모리상에서 동작하기 때문에 종료할 때 까지 기다려줘야 합니다. Darkstar 포럼에서는 10초 이후 파일을 지울 수 있다고 합니다만, PDS 소스를 확인해보는 수 밖에 없습니다.)&lt;br id="fckz"&gt;If you stop the PDS and then run the HelloWorld application again, you will notice that you don't get a “HelloWorld!” output the second time. This is because the AppListener already exists in the Object Store from the previous run, and thus the initialize method on it is never called.&lt;br id="em2v"&gt;If you want to see “Hello World” again, you can do it by clearing the Object Store with the following commands:&lt;br id="pfgd"&gt;&lt;ul id="c.i:"&gt;&lt;li id="epod"&gt;For Unix:&lt;/li&gt;&lt;/ul&gt;&lt;div id="ii7y" style="margin-left: 80px;"&gt;rm -r data/HelloWorld/dsdb/*&lt;br id="twcs"&gt;&lt;/div&gt;&lt;ul id="smel"&gt;&lt;li id="b5ly"&gt; For Windows:&lt;/li&gt;&lt;/ul&gt;&lt;div id="exep" style="margin-left: 80px;"&gt;del /s data\HelloWorld\dsdb\*.*&lt;br id="o7st"&gt;&lt;/div&gt;&lt;br id="xf8x"&gt;&lt;/div&gt;&lt;br id="ejzb"&gt;&lt;br id="lamu"&gt;&lt;font id="dyhq" size="5"&gt;Lesson Two: Hello Logger!&lt;/font&gt;&lt;br id="n07k"&gt;&lt;br&gt;&lt;font id="cjuf" size="4"&gt;HelloLogger 코딩하기 (Coding HelloLogger)&lt;/font&gt;&lt;br id="gf3r"&gt;&lt;div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;&lt;div&gt;PDS는 java.util.logging.* 패키지의 자바 로깅 메커니즘 표준을 지원합니다. 이는 유연하고 설정하기 쉬운 로깅 API이며 자바로 작성된 대부분의 서버에서 사용됩니다. PDS 서버는 다양한 내부 상태와 이벤트를 기록하기 위하여 스스로 로거를 사용합니다.&lt;/div&gt;&lt;div&gt;아래에 표준출력 보다는 로거로 "Hello World!"를 보내는 HelloWorld 프로그램이 재작성되어 있습니다. &lt;/div&gt;&lt;div&gt;The PDS supports the standard Java logging mechanisms in the java.util.logging.* package. This is a flexible and configurable logging API used by most servers written in Java. The PDS server itself uses the logger to report various internal states and events. It is highly recommended that applications use the same logging mechanisms for their reporting.&lt;/div&gt;&lt;div&gt;Below is a rewrite of HelloWorld that sends the “Hello World!” string to the logger rather than to standard out:&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;table id="ro4-" width="100%" cellpadding="3" cellspacing="0" border="0" class="zeroBorder"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;p&gt;&lt;font size="4"&gt;HelloLogger&lt;/font&gt;&lt;br&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Copyright 2007-2008 Sun Microsystems, Inc.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This file is part of Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* and/or modify it under the terms of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* version 2 as published by the Free Software Foundation and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* distributed hereunder to you.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* GNU General Public License for more details.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* You should have received a copy of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;package com.sun.sgs.tutorial.server.lesson2;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.io.Serializable;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.Properties;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Level;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Logger;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSession;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSessionListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Hello World with Logging example for the Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* It logs {@code "Hello World!"} at level {@link Level#INFO INFO}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* when first started.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public class HelloLogger&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;implements AppListener, // to get called during application startup.&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;Serializable // since all AppListeners are ManagedObjects.&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;{&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;/** The version of the serialized form of this class. */&lt;br&gt;private static final long serialVersionUID = 1L;&lt;br&gt;/** The {@link Logger} for this class. */&lt;br&gt;private static final Logger logger = Logger.getLogger(HelloLogger.class.getName());&lt;br&gt;/**&lt;br&gt;* {@inheritDoc}&lt;br&gt;* &amp;lt;p&gt;&lt;br&gt;* Logs our well-known greeting during application startup.&lt;br&gt;*/&lt;br&gt;public void initialize(Properties props) {&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;logger.log(Level.INFO, "Hello World!");&lt;br&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;}&lt;br&gt;/**&lt;br&gt;* {@inheritDoc}&lt;br&gt;* &amp;lt;p&gt;&lt;br&gt;* Prevents client logins by returning {@code null}.&lt;br&gt;*/&lt;br&gt;public ClientSessionListener loggedIn(ClientSession session) {&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;return null;&lt;br&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;}&lt;br&gt;&lt;/blockquote&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;font size="4"&gt;로깅 속성 파일(The Logging Properties File)&lt;/font&gt;&lt;/div&gt;&lt;div&gt;자바 로깅 API는 엄격한 메세지 레벨로 고려되어 있습니다. 우리가 로깅하려는 엄격한 info level에서의 메세지 시스템이 Level.INFO에 설명됩니다.&lt;/div&gt;&lt;div&gt;로깅 속성 파일에 의해 자바 로거가 동작합니다. 여러분이 어플리ㅔ이션을 동작하시키기 위하여 사용하는 sgs-boot.jar 파일은 PDS가 설치된 conf 디렉토리상에 제공되는 sgs-logging.properties 파일을 사용합니다. 이는 PDS 프로세스의 자바 커맨드 라인의 java.util.logging.config.file의 속성을 셋팅하여 완성됩니다.&lt;/div&gt;&lt;div&gt;이 파일의 디폴트 레벨은 info입니다. 이는 "fine"과 같은 디버깅 메세지 등의 info 레벨의 아래에 있는 로깅 메세지는 출력되지 않다는 것을 뜻합니다. 이 파일을 설정하는 더 자세한 설명은 JDK™ 6 API documentation을 참조하시기 바랍니다.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;The Logging Properties File&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;The Java logging API has a concept of message severity level. By logging at Level.INFO, we are telling the system we want to log this message at the info level of severity.&lt;/div&gt;&lt;div&gt;The Java logger's behavior is controlled by a logging properties file. The sgs-boot.jar file you use to run your applications uses the file sgs-logging.properties that is present in the conf directory of your PDS installation.&lt;/div&gt;&lt;div&gt;This is accomplished by setting the java.util.logging.config.file property on the java command line of the PDS process.&lt;/div&gt;&lt;div&gt;By default this file sets the logging level to info. This means that logging messages below the level of info, such as “fine” debugging messages, will not be printed. You can change this by editing the sgs-logging.properties file. For more information on how to edit this file, please see the JDK™ 6 API documentation.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="5"&gt;Lesson 3: Tasks, Managers, and Hello Timer!&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="4"&gt;태스크(Tasks)&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Lesson 1, 2에서 PDS 시스템은 이벤트의 응답(이 케이스에서는 새로 설치된 PDS 어플리케이션의 초기화 동작)으로 초기화 메소드를 자동으로 호출하였습니다. 이는 PDS 환경과 함께 실행되는 것을 뜻합니다.&lt;/div&gt;&lt;div&gt;PDS 환경에서 모든 코드의 실행은 태스크의 한 부분이 되어야 합니다. 어플리케이션 개발자 관점에서 보면, 태스크는 단일 스레드이고, 트랜잭션으로 동작하며 이벤트 모델의 코드입니다. 이는 태스가 단지 한순간 실행되는 태스크라는 것과 전체가 아니면 아무것도 실행되지 않는 것과 같이 데이터의 변경이 종료되는 것을 뜻합니다.&lt;/div&gt;&lt;div&gt;In Lessons 1 and 2, the system automatically invoked the initialize method for us in response to an event (in this case, the initial run of a newly installed PDS application). This meant executing code within the PDS environment.&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;All code run in the PDS environment must be part of a task. From the point of view of the application coder, a task is a piece of monothreaded, transactional, event-driven code. This means that the task runs as if it were the only task executing at that moment, and all actions done by the task to change data occur in an all-or-nothing manner.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="4"&gt;태스크 실행의 실체(The realities of task execution)&lt;/font&gt;&lt;/div&gt;&lt;div&gt;각각의 태스크는 단일 스레드로 실행됩니다. 그러나 우리가 차례대로 실행하지 않는 다면, 한 태스크가 각각의 태스크를 이전에 끝나는 것과 다음 시작하는 것을 기다릴때, 그 태스크는 PDS 제공자를 조정되지 못할 것입니다.&lt;/div&gt;&lt;div&gt;&lt;div&gt;그 대신에 PDS는 수많은 단일 스레드 태스크를 동시에 실행하고 각 매니지드 오브젝트의 경쟁 상태를 주시합니다. 두 매니지드 오브젝트가 경쟁하고 있다면, 한 태스크는 멈추게 되고 다른 태스크가 끝나기를 기다릴 것입니다.&lt;/div&gt;&lt;div&gt;많은 태스크가 경쟁상태가 아닌 상태로 같은 시간에 같은 매니지드 오브젝트로 읽혀질 수 있습니다. 만약 어떤 태스크가 매니지드 오브젝트로 사용되어야 한다면 경쟁상태가 되더라도 같은 매니지드 오브젝트로 읽혀지거나 사용됩니다.&lt;/div&gt;&lt;div&gt;&lt;div&gt;최적화된 성능을 위해, 데이터 구조와 가능한한 잠재적 오프젝트 경쟁을 포함한 게임 로직을 디자인 하는 것은 중요합니다. 동시에 발생하는 그리고 똑같은 매니지드 오브젝트로 쓰여져야만 할 지도 모르는 다중 태스크의 공간을 효율적으로 또 세심하게 설계하시기 바랍니다. 모든 태스크는 run 메소드를 갖고 있는 Task 인터페이스를 PDS 스캐쥴러에 등록됩니다.&lt;/div&gt;&lt;div&gt;&lt;div&gt;태스크는 가능한한 빨리 또는 최소 지연시간 이후에 실행되기 위하여 스캐줄러에 등록됩니다. 태스크는 한번 실행되고 끝나거나 반복될 수 있습니다. 반복되는 태스크라면 반복 주기가 설정되어 있을 것입니다.&lt;/div&gt;&lt;div&gt;반복되는 태스크는 전통적인 게임 시스템에서의 "timer" 또는 "heartbeat"와 같습니다. 이는 여러분이 밀리세컨드 단위로 설정된 이벤트를 효율적으로 생성할 수 있게 합니다.&lt;/div&gt;&lt;div&gt;Each individual task executes in a monothreaded manner. However, if we executed them serially,&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;waiting for each one to finish before the next one started, it would not be possible to get the kind of scaling the PDS provides.&lt;/div&gt;&lt;div&gt;Instead, the PDS executes many of these monothreaded tasks simultaneously and watches for&lt;/div&gt;&lt;div&gt;contention on the individual Managed Objects. If two tasks contend for control over a Managed&lt;/div&gt;&lt;div&gt;Object, one task will be held up and will wait for the other to finish before it can proceed.&lt;/div&gt;&lt;div&gt;Many tasks can read the state of the same Managed Object at the same time without causing&lt;/div&gt;&lt;div&gt;contention. If any of them wants to write to it, however, that can cause contention with tasks that read from or write to the same Managed Object.&lt;/div&gt;&lt;div&gt;To achieve optimal performance, it is important to design your data structures and game logic&lt;/div&gt;&lt;div&gt;with as little potential object-contention as possible. Be especially wary of places where multiple tasks that are likely to occur simultaneously might have to write to the same Managed Object.&lt;/div&gt;&lt;div&gt;All tasks registered with the PDS scheduler implement the interface Task, which has one method on it . run.6&lt;/div&gt;&lt;div&gt;A task may be submitted to the scheduler to be executed either as soon as possible, or after a minimum delay time. A task can be one-shot or repeating. If it is a repeating task, it is also submitted with a period of repeat.&lt;/div&gt;&lt;div&gt;A repeating task is the same thing as a “timer” or “heartbeat” in traditional game systems; it lets you effectively generate an event to be handled every specified number of milliseconds.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="4"&gt;매니저(Managers)&lt;/font&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;&lt;div&gt;서버 어플리케이션의 게임로직과 외부와의 모든 통신은 매니저를 통하여 완료됩니다. 아래에 세가지 타입의 매니저가 기술되어 있습니다.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;● 태스크 매니저 Task Manager&lt;br&gt;● 데이터 매니저 Data Manager&lt;br&gt;● 채널 내니저 Channel Manager&lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;인스톨 특화 매니저가 있을 수 있습니다. 이는 다른 서버 어플리케이션의 개발자에 의해 작성되고 PDS의 백엔드로 배포된 것일 수 있습니다. AppContext 클래스상의 고정 호출 흐름은 매니저와 통신하는 서버 어플리케이션 코드에서 사용됩니다. AppListener와 같은 이벤트 핸들링 인터페이스가 태스크를 구현하지 않더라도, 이 리스너는 일반 PDS 어플리케이션 코드와 같이 내부 태스크로 호출 될 수 있습니다.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;● getTaskManager()&lt;br&gt;● getDataManager()&lt;br&gt;● getChannelManager()&lt;br&gt;● getManager(managerClass)&lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;이 튜토리얼은 처음의 세가지를 포함합니다. 그 마지막은 인스톨 특화 매니저의 호출이며 이는 다음 버전의 Project Darkstar Server Extension Manual에 포함될 것입니다.&lt;/div&gt;&lt;div&gt;IMPORTANT: 매니저 레퍼런스는 호출된 매니저안의 태스크 전에에 대한 유일한 검증입니다. 그러므로 여러분은 AppContext로부터 호출하는 것 대신에 외부로부터 매니저를 참조하는 것을 시도하지 않는 것이 좋습니다.&lt;/div&gt;&lt;div&gt;태스크 매니저는 스캐줄러를 포함하는 PDS의 한 부분이고 우리가 사용할 스캐쥴 태스크입니다. 실행된 태스크와 같이 태스크 매니저 내에 스캐쥴링 되기 위하여, 오브젝트는 반드시 직렬화되어야 하며 Task 인터페이스를 상속하여야 합니다. 0.5초 주기를 갖고 5초 딜레이 이후 "Hello Timer" 메세지를 로깅하는 AppListener의 예제가 하단에 있습니다.&lt;/div&gt;&lt;div&gt;IMPORTANT: PDS 스택이 스케쥴링에서 태스크를 실행하기 위하여 가장 많은 노력을 기울이는 동안, 과부하가 걸린 태스크가 반복 실행되는 동안 한 태스크가 밀려날 수 있습니다. 이런 상황에서 해당 태스크는 그 기간에 실행을 스킵할 것이고 다음 스캐쥴링에서 실행될 것입니다. 추가로 매니지도 오브젝트의 경쟁은 지연된 태스크의 원인이 될 수도 있습니다.&lt;/div&gt;&lt;div&gt;스캐쥴링된 태스크의 요청된 반복 주기는 복잡한 그래픽일 수록 낮은 수로 실행되는 게임 클라이언트의 목표 프레임율과 비슷합니다. 여러분의 어플리케이션 로직이 일정 시간내에 실행되지 않을 정도로 타이트하다면 여러분은 설정된 시간과 그 실행 로직에서 스킵된 부분을 점검하고 핸들링할 것입니다.&lt;/div&gt;&lt;div&gt;All communication between your server application's game logic and the world outside of it is accomplished through managers. As described above, there are three standard managers:&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;● Task Manager&lt;br&gt;● Data Manager&lt;br&gt;● Channel Manager&lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;There can also be installation-specific managers; these can be written by the author of the server application and deployed with the application into a PDS back end. The following static calls on the AppContext class are used by server application code to get a reference to a manager to talk to:&lt;/div&gt;&lt;div&gt;Although the event-handling interfaces like AppListener do not implement Task, these listeners get called from an internal Task just like regular PDS application code.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;● getTaskManager()&lt;br&gt;● getDataManager()&lt;br&gt;● getChannelManager()&lt;br&gt;● getManager(managerClass)&lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;The first three are covered in this tutorial. The last is a generic call to get an installation-specific manager; it will be covered in the forthcoming Project Darkstar Server Extension Manual.&lt;/div&gt;&lt;div&gt;IMPORTANT: A Manager Reference is valid only for the life of the task within which the get manager call was invoked. Therefore, you should not try to cache manager references for use outside of that one invocation chain; get them from the AppContext instead.&lt;/div&gt;&lt;div&gt;The Task Manager is the part of the PDS that contains the scheduler, and thus what we use to schedule tasks. In order to be scheduled with the Task Manager as a task to be run, an object must be serializable and must implement the Task interface.7 The example below turns our AppListener into a task and starts it logging “Hello Timer” messages after a five-second delay at a half-second repeat period.&lt;/div&gt;&lt;div&gt;IMPORTANT: While the PDS stack makes a best effort to run tasks on schedule, it may back off execution of repeating tasks under heavy load. In that case, the task will skip execution of this period and reschedule to the next period. Additionally, contention for Managed Objects may cause a timed task to delay its execution.&lt;/div&gt;&lt;div&gt;The requested repeat frequency of a timed task is similar to a target frame rate in a game client, where frames may be dropped if they are taking too long to compute. If your application logic is tied to elapsed time or absolute number of “beats” in a given period of time, you'll need to check the elapsed time and handle skipped periods in your run logic.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="4"&gt;HelloTimer 코딩하기(Coding HelloTimer)&lt;/font&gt;&lt;/div&gt;&lt;div&gt;아래의 HelloTimer 어플리케이션은 반복되는 태스크를 스케쥴링하기 위하여 TaskManager를 사용합니다. 해당 태스크는 500ms의 주기로 5000ms 지연 이후에 실행될 것입니다.&lt;/div&gt;&lt;div&gt;The HelloTimer application below uses the TaskManager to schedule a repeating task. The task will run after a delay of 5000ms at a frequency of once every 500ms.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="dq1a" width="100%" cellpadding="3" cellspacing="0" border="0" class="zeroBorder"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;font size="4"&gt;HelloTimer&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Copyright 2007-2008 Sun Microsystems, Inc.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This file is part of Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* and/or modify it under the terms of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* version 2 as published by the Free Software Foundation and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* distributed hereunder to you.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* GNU General Public License for more details.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* You should have received a copy of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;package com.sun.sgs.tutorial.server.lesson3;&lt;br&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;&lt;br&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.io.Serializable;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.Properties;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Level;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Logger;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppContext;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSession;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSessionListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.Task;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.TaskManager;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;&lt;br&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* A simple timed-task example for the Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* It uses the {@link TaskManager} to schedule itself as a periodic task&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* that logs the current timestamp on each execution.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;&lt;br&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public class HelloTimer&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;implements AppListener, // to get called during application startup.&lt;br&gt;Serializable, // since all AppListeners are ManagedObjects.&lt;br&gt;Task // to schedule future calls to our run() method.&lt;br&gt;&lt;/blockquote&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;/** The version of the serialized form of this class. */&lt;br&gt;private static final long serialVersionUID = 1L;&lt;br&gt;/** The {@link Logger} for this class. */&lt;br&gt;private static final Logger logger =&lt;br&gt;Logger.getLogger(HelloTimer.class.getName());&lt;br&gt;/** The delay before the first run of the task. */&lt;br&gt;public static final int DELAY_MS = 5000;&lt;br&gt;/** The time to wait before repeating the task. */&lt;br&gt;public static final int PERIOD_MS = 500;&lt;br&gt;// implement AppListener&lt;br&gt;&lt;br&gt;/**&lt;br&gt;* {@inheritDoc}&lt;br&gt;* &amp;lt;p&gt;&lt;br&gt;* Schedules the {@code run()} method to be called periodically.&lt;br&gt;* Since SGS tasks are persistent, the scheduling only needs to&lt;br&gt;* be done the first time the application is started. When the&lt;br&gt;* server is killed and restarted, the scheduled timer task will&lt;br&gt;* continue ticking.&lt;br&gt;* &amp;lt;p&gt;&lt;br&gt;* Runs the task {@value #DELAY_MS} ms from now,&lt;br&gt;* repeating every {@value #PERIOD_MS} ms.&lt;br&gt;*/&lt;br&gt;public void initialize(Properties props) {&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;TaskManager taskManager = AppContext.getTaskManager();&lt;br&gt;taskManager.schedulePeriodicTask(this, DELAY_MS, PERIOD_MS);&lt;br&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;}&lt;br&gt;&lt;br&gt;/**&lt;br&gt;* {@inheritDoc}&lt;br&gt;* &amp;lt;p&gt;&lt;br&gt;* Prevents client logins by returning {@code null}.&lt;br&gt;*/&lt;br&gt;public ClientSessionListener loggedIn(ClientSession session) {&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;return null;&lt;br&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;}&lt;br&gt;// implement Task&lt;br&gt;&lt;br&gt;/**&lt;br&gt;* {@inheritDoc}&lt;br&gt;* &amp;lt;p&gt;&lt;br&gt;* Logs the current timestamp whenever this {@code Task} gets run.&lt;br&gt;*/&lt;br&gt;public void run() throws Exception {&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;logger.log(Level.INFO,&lt;br&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;"HelloTimer task: running at timestamp {0,number,#}",&lt;br&gt;System.currentTimeMillis());&lt;br&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;}&lt;br&gt;&lt;/blockquote&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;이제 반복 이벤트를 만들었고 우리는 정지되고 재시작할 때 어떤 동작을 일으키는 첫번째 어플리케이션을 만들었습니다. 태스크 등록은 지속적이어야 합니다. 이는 다운되거나 재시동할 때 상태를 지속할 수 있습니다. 이 동작을 살펴보기 위해 서버를 정지시키고 재시작해보십시오.&lt;/div&gt;&lt;div&gt;주기적인 태스크는 오브젝트 스토어 내에 여러분의 오브젝트와 함께 저장된 정보입니다. 따라서 여러분이 데이터 디렉토리를 삭제하고 초기화되어있지 않은 처음의 상태로 되돌린다면 주기적인 태스크 또한 초기화될 것입니다.&lt;/div&gt;&lt;div&gt;이 행동은 여러분이 서버가 항상 동작하는 것 처럼 여러분의 코드를 작성하는 것을 허용하며, 여러분이 중요한 로직을 포함한 주기적 태스크의 동작 메소드 내의 경과된 시간을 점검하는 것에 주의를 요합니다.&lt;/div&gt;&lt;div&gt;어떻게 마지막 실행 시간 추적을 유지하는냐에대한 주제가 다음 레슨의 주제입니다.&lt;/div&gt;&lt;div&gt;Now that we have a repeating event, we have our first application that will do something when stopped and restarted. Task registration is persistent, which is to say, it survives a crash and reboot. Try stopping the server and restarting it again to see this in action.&lt;/div&gt;&lt;div&gt;The periodic task is information stored in the Object Store along with your managed objects, so if you clear the data directory and return it to its pristine, uninitialized state, the periodic tasks will also get cleared.&lt;/div&gt;&lt;div&gt;This behavior allows you to write your code as if the server were always up, with the caveat that you do have to check elapsed time in your periodic task's run method if a delay between that and the last time it was run has significance to your logic.&lt;/div&gt;&lt;div&gt;How you keep track of the last time run was called is the subject of the next lesson.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="5"&gt;Tutorial Lesson 4: Hello Persistence!&lt;/font&gt;&lt;/div&gt;&lt;div&gt;Lesson 3 explained that tasks that are run on a delay or repeat don't necessarily happen exactly at the time you asked for. They could happen a bit later if (for example) the system is very loaded, or a lot later if (for example) the entire data center has actually come down and had to be restarted.&lt;/div&gt;&lt;div&gt;To track the last time the run task was called and calculate the true time-delta, we need a way of storing the past time value so that it will survive the system going down. This is called persistent storage, and in real games it is very important. Imagine how your users would react if your machine went down and they all lost their characters and everything on them!&lt;/div&gt;&lt;div&gt;A Managed Object is an object for which the system tracks state and which the system makes persistent. We mentioned above that AppListener interface inherits the Managed Object interface and that your AppListener instance is automatically created by the system for you. The system also registers your AppListener as a Managed Object with the Data Manager. This means that its state will be preserved by the PDS for you.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Coding HelloPersistence&lt;/div&gt;&lt;div&gt;Since our HelloTimer task is a Managed Object, all we need to do is add a field to track the last time run was called. Below is the code for HelloPersistence.&lt;/div&gt;&lt;div&gt;Run HelloPersistence as a PDS application. Stop the PDS, wait a minute, and then start it again. You will see that the elapsed time reported includes the down time. This is because currentTimeMillis is based on the system clock, and time kept moving forward even when the PDS wasn't running.&lt;/div&gt;&lt;div&gt;Persistence is that simple and automatic in the PDS. Any non-transient field on a registered Managed Object will be persisted.10&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="t-iz" width="100%" cellpadding="3" cellspacing="0" border="0" class="zeroBorder"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;HelloPersistence&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Copyright 2007-2008 Sun Microsystems, Inc.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This file is part of Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* and/or modify it under the terms of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* version 2 as published by the Free Software Foundation and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* distributed hereunder to you.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* GNU General Public License for more details.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;8 A full Project Darkstar Server production environment provides failover mechanisms so that the loss of one server won't&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;bring the game down. In a true disaster, such as loss of power across the entire data center, it is possible the entire back&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;end might go off-line.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;9 Depending on your operating system, you may see the elapsed time reported by HelloPersistence while the PDS is&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;running to be a bit over or a bit under 500ms. This is because currentTimeMillis does not necessarily have a 1 ms&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;accuracy. In particular, Windows systems tend to have a lower currentTimeMillis accuracy than other Java™ SE&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;platforms.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;10 A transient field is one marked with the transient key word. Some values aren't valid beyond the task in which they are&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;used, and thus should be marked transient . for example, a field that caches a Manager during the current task.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Project Darkstar Server Application Tutorial 12/19/08 23&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* You should have received a copy of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;package com.sun.sgs.tutorial.server.lesson4;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.io.Serializable;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.Properties;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Level;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Logger;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppContext;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSession;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSessionListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ManagedObject;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.Task;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.TaskManager;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* A simple persistence example for the Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* As a {@link ManagedObject}, it is able to modify instance fields,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* demonstrated here by tracking the last timestamp at which a task&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* was run and displaying the time delta.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public class HelloPersistence&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;implements AppListener, // to get called during application startup.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Serializable, // since all AppListeners are ManagedObjects.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Task // to schedule future calls to our run() method.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The version of the serialized form of this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final long serialVersionUID = 1L;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The {@link Logger} for this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final Logger logger =&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Logger.getLogger(HelloPersistence.class.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The delay before the first run of the task. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public static final int DELAY_MS = 5000;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The time to wait before repeating the task. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public static final int PERIOD_MS = 500;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The timestamp when this task was last run. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private long lastTimestamp = System.currentTimeMillis();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// implement AppListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Schedules the {@code run()} method to be called periodically.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Since SGS tasks are persistent, the scheduling only needs to&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* be done the first time the application is started. When the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* server is killed and restarted, the scheduled timer task will&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* continue ticking.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Runs the task {@value #DELAY_MS} ms from now,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* repeating every {@value #PERIOD_MS} ms.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void initialize(Properties props) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;TaskManager taskManager = AppContext.getTaskManager();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;taskManager.schedulePeriodicTask(this, DELAY_MS, PERIOD_MS);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;24 12/19/08 Project Darkstar Server Application Tutorial&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Prevents client logins by returning {@code null}.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public ClientSessionListener loggedIn(ClientSession session) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;return null;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// implement Task&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Each time this {@code Task} is run, logs the current timestamp and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* the delta from the timestamp of the previous run.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void run() throws Exception {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;long timestamp = System.currentTimeMillis();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;long delta = timestamp - lastTimestamp;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// Update the field holding the most recent timestamp.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;lastTimestamp = timestamp;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.INFO,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;"timestamp = {0,number,#}, delta = {1,number,#}",&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;new Object[] { timestamp, delta }&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Coding HelloPersistence2While we could put all the fields of our application on the AppListener, there are many good reasons not to do this. As any Managed Object grows larger, it takes more time for the system to store and retrieve it. Also, although PDS task code is written as if it were monothreaded, many tasks are actually executing in parallel at any given time. Should the tasks conflict in what data they have to modify, then one will either have to wait for the other to finish or, in a worst-case situation, actually abandon all the work it had done up to that point and try again later.&lt;/div&gt;&lt;div&gt;For these reasons, an application will want to create other Managed Objects of its own. Luckily, that's easy to do!&lt;/div&gt;&lt;div&gt;All Managed Objects must meet two criteria:&lt;/div&gt;&lt;div&gt;● They must be Serializable.&lt;/div&gt;&lt;div&gt;● They must implement the ManagedObject marker interface. (AppListener actually inherits the&lt;/div&gt;&lt;div&gt;ManagedObject marker interface for you.)&lt;/div&gt;&lt;div&gt;One good way to break your application up into multiple Managed Objects is by the events they handle. A Managed Object can handle only one event at a time, so you want to separate all event handlers for events that might occur in parallel into separate Managed Objects. Below is the code to HelloPersistence2. It creates a separate TrivialTimedTask Managed Object from the AppListener to handle the timed task.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="fj60" width="100%" cellpadding="3" cellspacing="0" border="0" class="zeroBorder"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;HelloPersistence2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Copyright 2007-2008 Sun Microsystems, Inc.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This file is part of Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* and/or modify it under the terms of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* version 2 as published by the Free Software Foundation and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* distributed hereunder to you.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* GNU General Public License for more details.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* You should have received a copy of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;package com.sun.sgs.tutorial.server.lesson4;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.io.Serializable;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.Properties;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Level;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Logger;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppContext;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSession;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSessionListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.TaskManager;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* A simple persistence example for the Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public class HelloPersistence2&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;implements AppListener, Serializable&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The version of the serialized form of this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final long serialVersionUID = 1L;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The {@link Logger} for this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final Logger logger =&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Logger.getLogger(HelloPersistence2.class.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The delay before the first run of the task. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public static final int DELAY_MS = 5000;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The time to wait before repeating the task. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public static final int PERIOD_MS = 500;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// implement AppListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Creates a {@link TrivialTimedTask} and schedules its {@code run()}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* method to be called periodically.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Since SGS tasks are persistent, the scheduling only needs to&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* be done the first time the application is started. When the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;26 12/19/08 Project Darkstar Server Application Tutorial&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* server is killed and restarted, the scheduled timer task will&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* continue ticking.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Runs the task {@value #DELAY_MS} ms from now,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* repeating every {@value #PERIOD_MS} ms.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void initialize(Properties props) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;TrivialTimedTask task = new TrivialTimedTask();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.INFO, "Created task: {0}", task);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;TaskManager taskManager = AppContext.getTaskManager();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;taskManager.schedulePeriodicTask(task, DELAY_MS, PERIOD_MS);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Prevents client logins by returning {@code null}.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public ClientSessionListener loggedIn(ClientSession session) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;return null;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="eose" width="100%" cellpadding="3" cellspacing="0" border="0" class="zeroBorder"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;TrivialTimedTask&lt;br&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;This is the Managed Object we are going to have respond to the repeating task.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/*&lt;br&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Copyright 2007-2008 Sun Microsystems, Inc.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This file is part of Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* and/or modify it under the terms of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* version 2 as published by the Free Software Foundation and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* distributed hereunder to you.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* GNU General Public License for more details.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* You should have received a copy of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;package com.sun.sgs.tutorial.server.lesson4;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppContext;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.io.Serializable;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Level;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Logger;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ManagedObject;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.Task;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* A simple repeating Task that tracks and prints the time since it was&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* last run.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Project Darkstar Server Application Tutorial 12/19/08 27&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public class TrivialTimedTask&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;implements Serializable, // for persistence, as required by ManagedObject.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;ManagedObject, // to let the SGS manage our persistence.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Task // to schedule future calls to our run() method.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The version of the serialized form of this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final long serialVersionUID = 1L;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The {@link Logger} for this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final Logger logger =&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Logger.getLogger(TrivialTimedTask.class.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The timestamp when this task was last run. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private long lastTimestamp = System.currentTimeMillis();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// implement Task&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Each time this {@code Task} is run, logs the current timestamp and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* the delta from the timestamp of the previous run.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void run() throws Exception {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// We will be modifying this object.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;AppContext.getDataManager().markForUpdate(this);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;long timestamp = System.currentTimeMillis();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;long delta = timestamp - lastTimestamp;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// Update the field holding the most recent timestamp.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;lastTimestamp = timestamp;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.INFO,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;"timestamp = {0,number,#}, delta = {1,number,#}",&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;new Object[] { timestamp, delta }&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Coding HelloPersistence3&lt;br&gt;&lt;/div&gt;&lt;div&gt;A Managed Object does not actually become managed by the Data Manager, and thus persistent, until the Data Manager is made aware of it. The reason HelloPersistence2 works is because the Task Manager persisted the TrivialTimedTask object for us. In order to persist other Managed Objects, though, an application needs to take on the responsibility of informing the Data Manager itself. One way the Data Manager can become aware of a Managed Object is through a request for a Managed Reference.&lt;/div&gt;&lt;div&gt;Managed Objects often need to refer to other Managed Objects. This is done with a Managed Reference. It is very important that the only fields on one Managed Object that reference another Managed Object be Managed References. This is how the Data Manager knows that it is a reference to a separate Managed Object. If you store a simple Java reference to the second Managed Object in a field on the first Managed Object, the second object will become part of the first object's state when the first object is stored. The result will be that, the next time the&lt;/div&gt;&lt;div&gt;first object tries to access the second, it will get its own local copy and not the real second Managed Object.&lt;/div&gt;&lt;div&gt;HelloPersistence3 below illustrates this by creating a second persistent object that is called from the TrivialTimedTask and that keeps the last-called time as part of its persistent state.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="cjxx" width="100%" cellpadding="3" cellspacing="0" border="0" class="zeroBorder"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;HelloPersistence3&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;HelloPersistence3, below, is a task that delegates to a sub-task (a TrivialTimedTask that is not scheduled to run on its own). The sub-task is stored in a Managed Reference on HelloPersistence3.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Copyright 2007-2008 Sun Microsystems, Inc.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This file is part of Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* and/or modify it under the terms of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* version 2 as published by the Free Software Foundation and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* distributed hereunder to you.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* GNU General Public License for more details.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* You should have received a copy of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;package com.sun.sgs.tutorial.server.lesson4;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.io.Serializable;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.Properties;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Level;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Logger;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppContext;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSession;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSessionListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.DataManager;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ManagedReference;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.Task;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.TaskManager;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* A simple persistence example for the Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public class HelloPersistence3&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;implements AppListener, Serializable, Task&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The version of the serialized form of this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final long serialVersionUID = 1L;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The {@link Logger} for this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final Logger logger =&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Logger.getLogger(HelloPersistence3.class.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The delay before the first run of the task. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public static final int DELAY_MS = 5000;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The time to wait before repeating the task. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public static final int PERIOD_MS = 500;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** A reference to our subtask, a {@link TrivialTimedTask}. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private ManagedReference&amp;lt;TrivialTimedTask&gt; subTaskRef = null;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Project Darkstar Server Application Tutorial 12/19/08 29&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Gets the subtask this task delegates to. Dereferences a&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@link ManagedReference} in this object that holds the subtask.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This null-check idiom is common when getting a ManagedReference.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* @return the subtask this task delegates to, or null if none is set&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public TrivialTimedTask getSubTask() {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;if (subTaskRef == null)&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;return null;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;return subTaskRef.get();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Sets the subtask this task delegates to. Stores the subtask&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* as a {@link ManagedReference} in this object.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This null-check idiom is common when setting a ManagedReference,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* since {@link DataManager#createReference createReference} does&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* not accept null parameters.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* @param subTask the subtask this task should delegate to,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* or null to clear the subtask&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void setSubTask(TrivialTimedTask subTask) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;if (subTask == null) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;subTaskRef = null;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;return;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;DataManager dataManager = AppContext.getDataManager();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;subTaskRef = dataManager.createReference(subTask);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// implement AppListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Schedules the {@code run()} method of this object to be called&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* periodically.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Since SGS tasks are persistent, the scheduling only needs to&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* be done the first time the application is started. When the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* server is killed and restarted, the scheduled timer task will&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* continue ticking.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Runs the task {@value #DELAY_MS} ms from now,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* repeating every {@value #PERIOD_MS} ms.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void initialize(Properties props) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// Hold onto the task (as a managed reference)&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;setSubTask(new TrivialTimedTask());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;TaskManager taskManager = AppContext.getTaskManager();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;taskManager.schedulePeriodicTask(this, DELAY_MS, PERIOD_MS);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Prevents client logins by returning {@code null}.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;30 12/19/08 Project Darkstar Server Application Tutorial&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public ClientSessionListener loggedIn(ClientSession session) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;return null;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// implement Task&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Calls the run() method of the subtask set on this object.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void run() throws Exception {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// Get the subTask (from the ManagedReference that holds it)&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;TrivialTimedTask subTask = getSubTask();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;if (subTask == null) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.WARNING, "subTask is null");&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;return;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// Delegate to the subTask's run() method&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;subTask.run();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Another way to register a Managed Object to the Data Manager is with the setBinding call. This call does not return a Managed Reference, but instead binds the Managed Object to the string passed in with it to the call.&lt;/div&gt;&lt;div&gt;Once a Managed Object has a name bound to it, the Managed Object may be retrieved by passing the same name to the getBinding call. Note that name bindings must be distinct. For each unique string used as a name binding by an application, there can be one and only one Managed Object bound.&lt;/div&gt;&lt;div&gt;Retrieving a Managed Object by its binding has some additional overhead, so it's better to keep Managed References to Managed Objects in the other Managed Objects that need to call them. There are, however, some problems that are best solved with a name-binding convention; one common example is finding the player object for a particular player at the start of his or her session.&lt;/div&gt;&lt;div&gt;There are a number of other interesting methods on the Data Manager. You might want to look at the Javadoc now, but discussion of them will be put off until required by the tutorial applications.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Lesson 5: Hello User!&lt;/div&gt;&lt;div&gt;Up till now the tutorial lessons have focused on getting your logic up and running in the PDS. But there is another side to the online game equation ─ the users and their computers. This lesson shows how to start communicating between clients and the PDS.&lt;/div&gt;&lt;div&gt;In this tutorial, the server side of that communication will be explained and illustrated using a simple pre-built client. For the client-side coding, please see the Project Darkstar Client Tutorial.&lt;/div&gt;&lt;div&gt;Knowing When a User Logs In The first step in communicating with users is knowing who is available to communicate with. The PDS provides a callback method on the AppListener for this: loggedIn. The loggedIn method gets passed an object that describes the user; this object is called a ClientSession.11&lt;/div&gt;&lt;div&gt;Below is the code for HelloUser, a trivial application that logs the login of a user.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="e275" width="100%" cellpadding="3" cellspacing="0" border="0" class="zeroBorder"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;HelloUser&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/*&lt;br&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Copyright 2007-2008 Sun Microsystems, Inc.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This file is part of Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* and/or modify it under the terms of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* version 2 as published by the Free Software Foundation and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* distributed hereunder to you.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* GNU General Public License for more details.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* You should have received a copy of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;package com.sun.sgs.tutorial.server.lesson5;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.io.Serializable;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.Properties;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Level;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Logger;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSession;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSessionListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Simple example of listening for user {@linkplain AppListener#loggedIn login}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* in the Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs each time a user logs in, then kicks them off immediately.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;11 In fact, ClientSession describes the new connection session, the user being one of those parameters. This distinction is&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;important, in that you cannot save a ClientSession object and expect it to be valid after the session has ended, which is&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;when the user disconnects.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;32 12/19/08 Project Darkstar Server Application Tutorial&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public class HelloUser&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;implements AppListener, // to get called during startup and login.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Serializable // since all AppListeners are ManagedObjects.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The version of the serialized form of this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final long serialVersionUID = 1L;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The {@link Logger} for this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final Logger logger =&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Logger.getLogger(HelloUser.class.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// implement AppListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** {@inheritDoc} */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void initialize(Properties props) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// empty&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs a message each time a new session tries to login, then&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* kicks them out by returning {@code null}.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public ClientSessionListener loggedIn(ClientSession session) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// User has logged in&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.INFO, "User {0} almost logged in", session.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// Kick the user out immediately by returning a null listener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;return null;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Direct Communication&lt;br&gt;&lt;/div&gt;&lt;div&gt;You will note that, when you run the server application above and connect to it with a client, the client is immediately logged out. This is because we are returning null from loggedIn. The PDS interprets this as our rejecting the user. To accept the user and allow him or her to stay logged in, you need to return a valid ClientSessionListener. To be valid, this object must implement both ClientSessionListener and Serializable.&lt;/div&gt;&lt;div&gt;Below is HelloUser2, which does this.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="f0x5" width="100%" cellpadding="3" cellspacing="0" border="0" class="zeroBorder"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;HelloUser2&lt;br&gt;HelloUser2 is identical to HelloUser except for the loggedIn method:&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Copyright 2007-2008 Sun Microsystems, Inc.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This file is part of Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* and/or modify it under the terms of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* version 2 as published by the Free Software Foundation and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* distributed hereunder to you.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Project Darkstar Server Application Tutorial 12/19/08 33&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* GNU General Public License for more details.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* You should have received a copy of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;package com.sun.sgs.tutorial.server.lesson5;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.io.Serializable;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.Properties;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Level;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Logger;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSession;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSessionListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Simple example of listening for user {@linkplain AppListener#loggedIn login}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* in the Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs each time a user logs in, and sets their listener to a&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* new {@link HelloUserSessionListener}.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public class HelloUser2&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;implements AppListener, // to get called during startup and login.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Serializable // since all AppListeners are ManagedObjects.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The version of the serialized form of this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final long serialVersionUID = 1L;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The {@link Logger} for this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final Logger logger =&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Logger.getLogger(HelloUser2.class.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// implement AppListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** {@inheritDoc} */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void initialize(Properties props) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// empty&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs a message each time a new session logs in.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public ClientSessionListener loggedIn(ClientSession session) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// User has logged in&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.INFO, "User {0} has logged in", session.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// Return a valid listener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;return new HelloUserSessionListener(session);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="tnna" width="100%" cellpadding="3" cellspacing="0" border="0" class="zeroBorder"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;HelloUserSessionListener&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Copyright 2007-2008 Sun Microsystems, Inc.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;34 12/19/08 Project Darkstar Server Application Tutorial&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This file is part of Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* and/or modify it under the terms of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* version 2 as published by the Free Software Foundation and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* distributed hereunder to you.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* GNU General Public License for more details.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* You should have received a copy of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;package com.sun.sgs.tutorial.server.lesson5;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.io.Serializable;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.nio.ByteBuffer;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Level;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Logger;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppContext;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSession;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSessionListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ManagedReference;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Simple example {@link ClientSessionListener} for the Project Darkstar&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs each time a session receives data or logs out.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;class HelloUserSessionListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;implements Serializable, ClientSessionListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The version of the serialized form of this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final long serialVersionUID = 1L;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The {@link Logger} for this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final Logger logger =&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Logger.getLogger(HelloUserSessionListener.class.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The session this {@code ClientSessionListener} is listening to. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private final ManagedReference&amp;lt;ClientSession&gt; sessionRef;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The name of the {@code ClientSession} for this listener. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private final String sessionName;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Creates a new {@code HelloUserSessionListener} for the given session.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* @param session the session this listener is associated with&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public HelloUserSessionListener(ClientSession session) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;if (session == null)&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;throw new NullPointerException("null session");&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;sessionRef = AppContext.getDataManager().createReference(session);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;sessionName = session.getName();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Project Darkstar Server Application Tutorial 12/19/08 35&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Returns the session for this listener.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* @return the session for this listener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;protected ClientSession getSession() {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// We created the ref with a non-null session, so no need to check it.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;return sessionRef.get();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs when data arrives from the client.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void receivedMessage(ByteBuffer message) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.INFO, "Message from {0}", sessionName);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs when the client disconnects.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void disconnected(boolean graceful) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;String grace = graceful ? "graceful" : "forced";&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.INFO,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;"User {0} has logged out {1}",&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;new Object[] { sessionName, grace }&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;HelloUserSessionListener is a glue object that listens for either data from the user or the disconnect of the user;&lt;br&gt;&lt;/div&gt;&lt;div&gt;it allows our server code to respond to these events. So far, all we do is log some information, but in a complete PDS application, these would both be important events to which we would want to respond.&lt;/div&gt;&lt;div&gt;There are two kinds of communication in the PDS:&lt;/div&gt;&lt;div&gt;● Direct Communication&lt;/div&gt;&lt;div&gt;● Channel Communication&lt;/div&gt;&lt;div&gt;Direct Communication is built into the core of the system and provides a pipe for the flow of data between a single user client and its PDS application.&lt;/div&gt;&lt;div&gt;Channel Communication is provided by a standard manager, the Channel Manager, and provides for publish/subscribe group communications. While there is nothing in the Channel Manager's functionality that could not be implemented on top of the Direct Communication mechanisms, putting the channel functionality in a manager allows for a much more efficient implementation.&lt;/div&gt;&lt;div&gt;The HelloEcho PDS application echoes back to the user anything the user sends to the application. Besides the name, there is only one line difference in HelloEchoSessionListener from HelloUserSessionListener: the addition of a session.send call.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="fkil" width="100%" cellpadding="3" cellspacing="0" border="0" class="zeroBorder"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;HelloEchoSessionListener&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Copyright 2007-2008 Sun Microsystems, Inc.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;36 12/19/08 Project Darkstar Server Application Tutorial&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This file is part of Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* and/or modify it under the terms of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* version 2 as published by the Free Software Foundation and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* distributed hereunder to you.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* GNU General Public License for more details.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* You should have received a copy of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;package com.sun.sgs.tutorial.server.lesson5;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.io.Serializable;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.nio.ByteBuffer;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Level;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Logger;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppContext;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSession;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSessionListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ManagedReference;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Simple example {@link ClientSessionListener} for the Project Darkstar&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs each time a session receives data or logs out, and echoes&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* any data received back to the sender.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;class HelloEchoSessionListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;implements Serializable, ClientSessionListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The version of the serialized form of this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final long serialVersionUID = 1L;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The {@link Logger} for this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final Logger logger =&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Logger.getLogger(HelloEchoSessionListener.class.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The session this {@code ClientSessionListener} is listening to. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private final ManagedReference&amp;lt;ClientSession&gt; sessionRef;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The name of the {@code ClientSession} for this listener. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private final String sessionName;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Creates a new {@code HelloEchoSessionListener} for the given session.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* @param session the session this listener is associated with&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public HelloEchoSessionListener(ClientSession session) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;if (session == null)&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;throw new NullPointerException("null session");&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;sessionRef = AppContext.getDataManager().createReference(session);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;sessionName = session.getName();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Project Darkstar Server Application Tutorial 12/19/08 37&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Returns the session for this listener.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* @return the session for this listener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;protected ClientSession getSession() {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// We created the ref with a non-null session, so no need to check it.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;return sessionRef.get();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs when data arrives from the client, and echoes the message back.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void receivedMessage(ByteBuffer message) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;ClientSession session = getSession();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.INFO, "Message from {0}", sessionName);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// Echo message back to sender&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;session.send(message);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs when the client disconnects.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void disconnected(boolean graceful) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;ClientSession session = getSession();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;String grace = graceful ? "graceful" : "forced";&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.INFO,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;"User {0} has logged out {1}",&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;new Object[] { sessionName, grace }&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Running the Examples&lt;br&gt;&lt;/div&gt;&lt;div&gt;To try all the examples in this part of the server tutorial, you need a simple client capable of logging in, as well as direct client/server communication. You can find this client as part of Lesson 1 of the Project Darkstar Client Tutorial (com.sun.sgs.tutorial.client.lesson1.HelloUserClient in the tutorial-client.jar file).&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Lesson 6: Hello Channels!&lt;/div&gt;&lt;div&gt;The previous lessons have introduced the Task Manager and Data Manager. The final standard manager is the Channel Manager. The core of the PDS provides us with basic client/server communications. For simple games, this may be enough. However, for games that organize players into groups, either to isolate game sessions (such as in many casual and fast action games), or to tame the n-squared user-to-user communications scaling issues inherent in massive numbers of simultaneous players, something with lower overhead and more control is&lt;/div&gt;&lt;div&gt;required.&lt;/div&gt;&lt;div&gt;The Channel Manager provides publish/subscribe channels. The server application can create these channels and then assign users to one or more of them. Communication between users in a channel does not involve the Task or Data Manager.&lt;/div&gt;&lt;div&gt;Coding HelloChannels&lt;/div&gt;&lt;div&gt;The HelloChannels Managed Object is similar to our previous AppListener implementations with the addition&lt;/div&gt;&lt;div&gt;that it opens two reliable channels, Foo and Bar.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="vori" width="100%" cellpadding="3" cellspacing="0" border="0" class="zeroBorder"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;HelloChannels&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Copyright 2007-2008 Sun Microsystems, Inc.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This file is part of Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* and/or modify it under the terms of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* version 2 as published by the Free Software Foundation and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* distributed hereunder to you.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* GNU General Public License for more details.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* You should have received a copy of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;package com.sun.sgs.tutorial.server.lesson6;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.io.Serializable;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.Properties;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Level;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Logger;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppContext;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.Channel;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ChannelManager;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSession;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSessionListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.Delivery;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ManagedReference;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Simple example of channel operations in the Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Project Darkstar Server Application Tutorial 12/19/08 39&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Extends the {@code HelloEcho} example by joining clients to two&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* channels.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public class HelloChannels&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;implements Serializable, AppListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The version of the serialized form of this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final long serialVersionUID = 1L;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The {@link Logger} for this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final Logger logger =&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Logger.getLogger(HelloChannels.class.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/* The name of the first channel {@value #CHANNEL_1_NAME} */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;static final String CHANNEL_1_NAME = "Foo";&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/* The name of the second channel {@value #CHANNEL_2_NAME} */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;static final String CHANNEL_2_NAME = "Bar";&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* The first {@link Channel}. The second channel is looked up&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* by name.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private ManagedReference&amp;lt;Channel&gt; channel1 = null;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Creates the channels. Channels persist across server restarts,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* so they only need to be created here in {@code initialize}.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void initialize(Properties props) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;ChannelManager channelMgr = AppContext.getChannelManager();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// Create and keep a reference to the first channel.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Channel c1 = channelMgr.createChannel(CHANNEL_1_NAME,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;null,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Delivery.RELIABLE);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;channel1 = AppContext.getDataManager().createReference(c1);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// We don't keep a reference to the second channel, to demonstrate&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// looking it up by name when needed. Also, this channel uses a&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// {@link ChannelListener} to filter messages.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;channelMgr.createChannel(CHANNEL_2_NAME,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;new HelloChannelsChannelListener(),&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Delivery.RELIABLE);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Returns a {@link HelloChannelsSessionListener} for the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* logged-in session.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public ClientSessionListener loggedIn(ClientSession session) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.INFO, "User {0} has logged in", session.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;return new HelloChannelsSessionListener(session, channel1);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;The HelloChannelsSessionListener is identical to HelloEchoSessionListener except for the constructor. When we create the session listener, we also join its session to two channels. One channel is passed in, while the second is looked up by name.&lt;/div&gt;&lt;div&gt;The first channel.join is passed null for a ChannelListener, so all communication on it is only received by clients. The second channel joined however is given a channel listener. This will be called back whenever a message from this session is posted to that channel. The listener can examine the message and sender and decide to discard the message, send a different message to the channel, or send the original, unmodified message to the channel.&lt;/div&gt;&lt;div&gt;Note that, with this code, each session has it own listener for messages on the second channel. This is preferable to registering a single channel-wide listener, since messages from different clients can be processed in parallel.&lt;/div&gt;&lt;div&gt;However, if your design really requires a single listener to all messages sent by any client on a channel, you would declare the listener as the second parameter to the createChannel call.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="x60n" width="100%" cellpadding="3" cellspacing="0" border="0" class="zeroBorder"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;HelloChannelsSessionListener&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Copyright 2007-2008 Sun Microsystems, Inc.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This file is part of Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* and/or modify it under the terms of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* version 2 as published by the Free Software Foundation and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* distributed hereunder to you.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* GNU General Public License for more details.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* You should have received a copy of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;package com.sun.sgs.tutorial.server.lesson6;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.io.Serializable;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.nio.ByteBuffer;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Level;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Logger;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.AppContext;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.Channel;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ChannelManager;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSession;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSessionListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.DataManager;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ManagedReference;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Simple example {@link ClientSessionListener} for the Project Darkstar&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs each time a session receives data or logs out, and echoes&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* any data received back to the sender.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;class HelloChannelsSessionListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;implements Serializable, ClientSessionListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Project Darkstar Server Application Tutorial 12/19/08 41&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The version of the serialized form of this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final long serialVersionUID = 1L;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The {@link Logger} for this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final Logger logger =&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Logger.getLogger(HelloChannelsSessionListener.class.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The session this {@code ClientSessionListener} is listening to. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private final ManagedReference&amp;lt;ClientSession&gt; sessionRef;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The name of the {@code ClientSession} for this listener. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private final String sessionName;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Creates a new {@code HelloChannelsSessionListener} for the session.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* @param session the session this listener is associated with&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* @param channel1 a reference to a channel to join&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public HelloChannelsSessionListener(ClientSession session,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;ManagedReference&amp;lt;Channel&gt; channel1)&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;if (session == null)&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;throw new NullPointerException("null session");&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;DataManager dataMgr = AppContext.getDataManager();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;sessionRef = dataMgr.createReference(session);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;sessionName = session.getName();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// Join the session to all channels. We obtain the channel&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// in two different ways, by reference and by name.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;ChannelManager channelMgr = AppContext.getChannelManager();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// We were passed a reference to the first channel.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;channel1.get().join(session);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// We look up the second channel by name.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Channel channel2 = channelMgr.getChannel(HelloChannels.CHANNEL_2_NAME);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;channel2.join(session);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Returns the session for this listener.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* @return the session for this listener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;protected ClientSession getSession() {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;// We created the ref with a non-null session, so no need to check it.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;return sessionRef.get();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs when data arrives from the client, and echoes the message back.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void receivedMessage(ByteBuffer message) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;ClientSession session = getSession();&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;if (logger.isLoggable(Level.FINE)) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.FINE, "Message from {0}", sessionName);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;session.send(message);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;42 12/19/08 Project Darkstar Server Application Tutorial&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs when the client disconnects.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void disconnected(boolean graceful) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;String grace = graceful ? "graceful" : "forced";&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.INFO,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;"User {0} has logged out {1}",&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;new Object[] { sessionName, grace }&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;HelloChannelsChannelListener is a simple skeletal listener that just logs what it receives.&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;table id="j9lw" width="100%" cellpadding="3" cellspacing="0" border="0" class="zeroBorder"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;HelloChannelsChannelListener&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Copyright 2007-2008 Sun Microsystems, Inc.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* This file is part of Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is free software: you can redistribute it&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* and/or modify it under the terms of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* version 2 as published by the Free Software Foundation and&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* distributed hereunder to you.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Project Darkstar Server is distributed in the hope that it will be useful,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* GNU General Public License for more details.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* You should have received a copy of the GNU General Public License&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&gt;.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;package com.sun.sgs.tutorial.server.lesson6;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.io.Serializable;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Level;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.util.logging.Logger;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.Channel;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ChannelListener;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import com.sun.sgs.app.ClientSession;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;import java.nio.ByteBuffer;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Simple example {@link ChannelListener} for the Project Darkstar Server.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs when a channel receives data.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;class HelloChannelsChannelListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;implements Serializable, ChannelListener&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The version of the serialized form of this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final long serialVersionUID = 1L;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Project Darkstar Server Application Tutorial 12/19/08 43&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/** The {@link Logger} for this class. */&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;private static final Logger logger =&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;Logger.getLogger(HelloChannelsChannelListener.class.getName());&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;/**&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* {@inheritDoc}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* &amp;lt;p&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* Logs when data arrives on a channel. A typical listener would&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* examine the message to decide whether it should be discarded,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;* modified, or sent unchanged.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;*/&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;public void receivedMessage(Channel channel,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;ClientSession session,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;ByteBuffer message)&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;{&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;if (logger.isLoggable(Level.INFO)) {&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;logger.log(Level.INFO,&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;"Channel message from {0} on channel {1}",&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;new Object[] { session.getName(), channel.getName() }&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;channel.send(session, message);&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px"&gt;}&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Running HelloChannels&lt;br&gt;&lt;/div&gt;&lt;div&gt;To try HelloChannels you need a client that will connect and allow you to talk on selected channels. One is provided in Lesson 2 of the Project Darkstar Client Tutorial&lt;/div&gt;&lt;div&gt;(com.sun.sgs.tutorial.client.lesson2.HelloChannelClient in tutorial-client.jar).&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Conclusion&lt;/div&gt;&lt;div&gt;At this point you know all the basics of writing PDS applications. The applications you write using the PDS API on a single-node system will operate unmodified in exactly the same way on a large-scale multiple-node PDS production back end. In that environment they will scale out horizontally, handle failover, and be fault-tolerant.&lt;/div&gt;&lt;div&gt;There are, however, some best practices to follow to ensure optimal scalability for your application. Failing to follow these can seriously limit how many users your application will be able to support at once.&lt;/div&gt;&lt;div&gt;Best Practices&lt;/div&gt;&lt;div&gt;● Do not design with bottleneck Managed Objects.&lt;/div&gt;&lt;div&gt;You can think of each Managed Object as an independent worker who can only do one task at a time.&lt;/div&gt;&lt;div&gt;When one task is modifying the state of a Managed Object, any other tasks that want to read or change its state must wait. A Managed Object may have many readers at once if no one is writing to it, but any writing turns it into a potential bottleneck. In general, a pattern of one writer and many readers is the best configuration, although it is not always possible.&lt;/div&gt;&lt;div&gt;In the worst case, multiple lockers of the same objects will cause potential deadlock situations that are computationally more expensive to resolve and can result in processing delays (additional latency).&lt;/div&gt;&lt;div&gt;● Avoid contending for object access.&lt;/div&gt;&lt;div&gt;Although the PDS will detect and resolve contentions for write access to objects between parallel events such that your code never actually stops processing, this deadlock avoidance can significantly load the CPU and slow response time to the users. In the worst case, contention can actually prevent parallel processing, seriously impacting the scalability of your code.&lt;/div&gt;&lt;div&gt;A classic example of a deadlock is two combatants who have to modify both their own data and that of their enemies when resolving an attack. If all the data is on a combatant Managed Object, then both combat tasks need to lock both objects, typically in the opposite order, which is a formula for deadlock.&lt;/div&gt;&lt;div&gt;One solution is to divide the combatants' combat statistics into two groups, the ones they modify themselves and the ones modified by an attacker, and store them on separate Managed Objects. The combatant object would then retain Managed References to these objects, and only lock them as needed.&lt;/div&gt;&lt;div&gt;Another practical solution is partial serialization of the problem. This is especially appropriate if you want the combatants attacks to be processed in a fixed order. Here you have a single “combat clock” task (generally a repeating task) that processes in sequence all the attacks from all the combatants in a given battle.&lt;/div&gt;&lt;div&gt;Not all contention situations are this easy to spot and design around. The PDS gives you feedback at runtime as to what objects are deadlocking. Use this to tune your application.&lt;/div&gt;&lt;div&gt;● Give all serializable objects a fixed serialVersionUID.&lt;/div&gt;&lt;div&gt;The PDS uses Serialization internally. If you don't give your Serializable classes a serialVersionUID,&lt;/div&gt;&lt;div&gt;then any change to their public interface could invalidate the stored copies, leading to a need to delete the entire Object Store. Giving them a fixed serialVersionUID will allow you to make “compatible changes” without invalidating your existing store. (For what constitutes a compatible change, please see the JDK™ documents on Serialization.)&lt;/div&gt;&lt;div&gt;● Avoid inner classes in Serializable objects.&lt;/div&gt;&lt;div&gt;Serialization of objects whose classes contain non-static inner classes gets complicated. It is best to avoid inner classes, including anonymous inner classes. If you must use them, the safest thing is to declare them as static inner classes.&lt;/div&gt;&lt;div&gt;● Do not create non-final static fields on Managed Objects.&lt;br&gt;&lt;/div&gt;&lt;div&gt;The most important reason for this is that static fields exist only within the scope of a single VM, and a PDS back end floats Managed Objects between many different VMs.&lt;/div&gt;&lt;div&gt;● Do not use the synchronized keyword in Managed Objects.&lt;/div&gt;&lt;div&gt;First, this is unnecessary in a PDS application. Synchronization is used to prevent contention over data between multiple parallel threads of control. The PDS programming model handles this transparently for you. Second, it won't work, since synchronization is relative to a single VM and a full PDS back-end operates over many VM instances simultaneously. Finally, it causes interactions between tasks that can defeat the system's deadlock-proofing feature and actually cause your code to lock up.&lt;/div&gt;&lt;div&gt;Any task that locks up for too long will be forced by the PDS to yield its control of Managed Objects back to the system, but this is a last-ditch safety feature and will result in significant delays in code execution.&lt;/div&gt;&lt;div&gt;● Do not make blocking I/O calls or stay in a loop for a long period.&lt;/div&gt;&lt;div&gt;The system contains the assumption that tasks are short-lived. If a task lives too long, it will be forcibly terminated by the back end. The right way to do blocking I/O and the like is to create an extension manager, do the blocking calls in it, and submit a task to the Task Manager to handle the results when done. (Writing and installing custom managers will be covered in the Project Darkstar Server Extension Manual.)&lt;/div&gt;&lt;div&gt;● Do not catch java.lang.Exception.&lt;/div&gt;&lt;div&gt;Instead, catch the explicit exceptions you are expecting. The PDS also uses exceptions to communicate exceptional states to the execution environment. Although the system does its best to do the right thing even if you hide these exceptions from it, it will operate more efficiently if you don't.&lt;/div&gt;&lt;div&gt;● Do not carry a non-transient Java reference on a Managed Object to another Managed Object.&lt;/div&gt;&lt;div&gt;Instead, use a Managed Reference. Any object that is referred to by a Java reference chain that starts at the Managed Object is assumed to be part of the private state of that particular Managed Object. This means that, while you may set two Java references on two different Managed Objects to the same Java object during a task, they will each end up with their own copy of that object at the termination of the task.&lt;/div&gt;&lt;div&gt;● Never try to save a Manager Instance on a non-transient field of a Managed Object.&lt;/div&gt;&lt;div&gt;This is because Manager References are only valid for the life of the task that fetched them. Manager instances are not serializable objects. Any attempt to save a reference to one in your Managed Object will cause the Data Manager to throw a non-retriable exception and the entire task to be abandoned.&lt;/div&gt;&lt;div&gt;● Carefully manage the life cycle of your Managed Objects.&lt;/div&gt;&lt;div&gt;Remember that the Object Store does no garbage collection for you. Managed Objects are “real objects” in the simulation sense. They don't exist until explicitly created, exist in one and only one state at any given time, and persist until explicitly destroyed. These are very good properties from a simulation programming stance, but if you go wild creating Managed Objects and don't destroy them when they are no longer useful, you can load down the Object Store with garbage and potentially impact performance.&lt;/div&gt;&lt;div&gt;Be aware that any PDS API call that accepts a Managed Object may create a Managed Reference to that object. If this is the first time the Data Manager has been made aware of the Managed Object, this will result in the Managed Object being added to the Object Store. It is still the developer's responsibility to remove the Managed Object from the Object Store when it is no longer in use. For this reason, it is best to avoid passing Managed Objects that your application is not explicitly managing into the PDS APIs.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Things Not Covered in This TutorialThis tutorial is intended to introduce you to the fundamentals of coding a PDS application. Although we present all basic uses of the standard managers, these managers have additional functions and capabilities not covered here. Please see the Javadoc for those other functions.&lt;/div&gt;&lt;div&gt;As discussed, the list of managers in a given PDS back end is extensible. This tutorial does not cover writing or using plug-in managers. For that, see the forthcoming document on PDS extensions.&lt;/div&gt;&lt;div&gt;Although we use PDS client programs in Lessons 5 and 6, this tutorial does not explain how those are written.&lt;/div&gt;&lt;div&gt;For those explanations, please see the Project Darkstar Client Tutorial.&lt;/div&gt;&lt;div&gt;Finally, for the sake of clarity, this tutorial shows very simple examples. For more complex patterns of PDS&lt;/div&gt;&lt;div&gt;usage, please see the community examples at www.projectdarkstar.com.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Appendix A: SwordWorld Example Code - 뺍니다. PDS 홈페이지에서 다운받으세요&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;br id="mto_"&gt;&lt;br id="qmxp"&gt;&lt;br id="blen"&gt;&lt;br id="yzwc"&gt;&lt;div id="vllo" style="margin-left: 40px;"&gt;&lt;/div&gt;&lt;br id="gr_y"&gt;&lt;br id="cfft"&gt;&lt;br id="usf5"&gt;&lt;br id="zsiu"&gt;&lt;br id="zkr1"&gt;&lt;br id="sm10"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-7428656882510326883?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/7428656882510326883/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2009/01/project-darkstar-server-tutorial-ko.html#comment-form' title='1개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7428656882510326883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7428656882510326883'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2009/01/project-darkstar-server-tutorial-ko.html' title='Project Darkstar server tutorial 번역'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-5591453456601927113</id><published>2009-01-14T14:01:00.001+09:00</published><updated>2009-01-14T14:04:48.654+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>수트를 제대로 입는 Tip 95가지 -GQ</title><content type='html'>&lt;&lt; 수트를 제대로 입는 Tip 95가지 -GQ &gt;&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1. 재킷에 달린 단추 갯수가 두개든, 세개든 단추를 잠글 때는하나만 잠근다.&lt;br /&gt;&lt;br /&gt;2. 즉, 2버튼 수트는 윗단추를, 3번튼 수트는 가운데 단추를 잠그는 것이다.&lt;br /&gt;&lt;br /&gt;3. 베스트를 입는다고 꼭 뚱뚱해 보이는 것은 아니다.그러나 가능하면 베스트 자체를 입지 말 것.&lt;br /&gt;&lt;br /&gt;4. 만약 당신이 수트를 한 벌만 가질수 있다면 그것은 차콜그레이어야 한다.&lt;br /&gt;&lt;br /&gt;5. 만약 당신이 다행히도 수트를 두 벌 가질수 있다면 그것은 차콜그레이와 네이비블루이어야 한다.&lt;br /&gt;&lt;br /&gt;6. 만약 당신이 신 혹은 부모님, 재벌 여자친구의 도움으로 수트를 세 벌 맘대로 가질 수있다면 그것은 차콜그레이, 네이비블루, 그리고 그레이어야 한다.&lt;br /&gt;&lt;br /&gt;7. 남자가 여자보다 더 신중해 보인다면 그것은 남자의 옷 색깔이 여자의 옷 색깔보다 더 진하기 때문이다.&lt;br /&gt;&lt;br /&gt;8. 처음에 사는수트들은 무늬가 없는 것이 좋고, 점점 스트라이프나 체크같은 페턴을 시도해본다.&lt;br /&gt;&lt;br /&gt;9. 키가 커 보이고 싶은 남자에게는짙은 색상의 2버튼 수트가 좋다.&lt;br /&gt;&lt;br /&gt;10. 좀 날씬해 보일 필요가 있는 남자도 짙은 색 3버튼 수트를입어라.&lt;br /&gt;&lt;br /&gt;11. 좀 뚱뚱한 사람이라면 더블이 좋다. 색상도 어둡게.&lt;br /&gt;&lt;br /&gt;12. 왜소한 체격을 감추기 위해 헐렁하게 입은 수트는 당신을 더욱 왜소하고 초라하며 결국에는 자신감도 취향도 없는 이상한 사람으로보이게 만든다.&lt;br /&gt;&lt;br /&gt;13.다른 사람이 입은 수트 상표를 안다고 하더라도 그것을 화제에 올리지 마라. 설사 그가 아라비아 왕자들만 입는 지구 최고급 수트를 입고 있다 할지라도..&lt;br /&gt;&lt;br /&gt;14. 입어보지 않고 수트를 사는 것은 얼굴 한 번 보지 못한 여자와 결혼하는 것과 같다.&lt;br /&gt;&lt;br /&gt;15. 수트 재킷에는 골드 컬러 단추를 달지 않는다. 왜냐면 그건 블레이저용이니까.&lt;br /&gt;&lt;br /&gt;16. 재킷 주머니에는 가능한 한 아무것도 넣지 마라.&lt;br /&gt;&lt;br /&gt;17. 재킷 가슴 포켓에 넣을 수 있는 건 포켓스퀘어 뿐이다.&lt;br /&gt;&lt;br /&gt;18. 바지 길이는 아무리 길어도 구두 뒷굽을 덮지 않아야 한다. 지금보다 3cm 줄여라. 4cm 줄여도 무방한 사람이 대부분일 것이다.&lt;br /&gt;&lt;br /&gt;19. 수트엔 긴 소매 드레스셔츠를 입는 것이 기본이다.&lt;br /&gt;&lt;br /&gt;20. 셔츠 안에 러닝셔츠를 입지 말아라. 그렇게하면 구속되는 법이 입안되기를 소망한다.&lt;br /&gt;&lt;br /&gt;21. 꼭 러닝셔츠를 입어야겠다면 아예 수트를 입지 말아라.&lt;br /&gt;&lt;br /&gt;22. 수트에는 반드시 흰색 셔츠만 입어야 한다는 고정관념을 버려라.&lt;br /&gt;&lt;br /&gt;23. 그렇다고 하와이언 셔츠처럼 화려한 셔츠를 입으려는 생각은 더욱 버려라.&lt;br /&gt;&lt;br /&gt;24. 아시다시피 셔츠 깃과 소매 끝은 늘 청결해야 한다.&lt;br /&gt;&lt;br /&gt;25. 셔츠 소매는 약 1.5cm정도 재킷 소매 밖으로 나오게 입는 것이 적당하다.&lt;br /&gt;&lt;br /&gt;26. 제대로 다려지지 않은 셔츠를 입고 출근하느니, 셔츠를 다려 입은 다음 상사에게 지각에 대한 주의를 듣는 편이 낫다. 단, 이 사항은 회사 문화와도 관련있으므로 탄력적으로 적용!&lt;br /&gt;&lt;br /&gt;27. 아무리 주말이라 할지라도 수트 속에 터틀넥을 입는 것은 곤란하다. 수트는 Formal. 터틀넥같은 Kniw는 Casual.&lt;br /&gt;&lt;br /&gt;28. 비지니스 수트에 실크 셔츠는 전혀 어울리지 않는다.&lt;br /&gt;&lt;br /&gt;29. 버튼 다운 칼라 셔츠도 모든 수트에 어울리지 않는다. 그것은 재킷과는 매치가 가능하다.&lt;br /&gt;&lt;br /&gt;30. 반팔 셔츠를 입고 넥타이 매고자 하는 사람도 아까 런닝입는 사람과 함께 구속했으면 좋겠다.&lt;br /&gt;&lt;br /&gt;31. 여행을 다닐 때는 반드시 수트 케이스를 따로 챙겨 간다. 언제 어느 상황에서 품위있는 레스토랑에 초청될지 모른다.&lt;br /&gt;&lt;br /&gt;32. 어떠한 상황에서도 바지 밑단을 걷어올리지 마라.&lt;br /&gt;&lt;br /&gt;33. 수트를 입을 때 반드시 벨트를 매어야 한다.&lt;br /&gt;&lt;br /&gt;34. 벨트 색깔은 반드시 블랙 아니면 브라운이어야 한다. 게다가 벨트 색상과 구두 색상 정도는 맞춰주는 센스.&lt;br /&gt;&lt;br /&gt;35. 요란한 디자인의 금색 벨트는 정말이지 곤란하다. 조폭이시라면뭐 할수 없고.&lt;br /&gt;&lt;br /&gt;36. 정장용 벨트를 청바지에 하는 것은 웃기지만 캐주얼용 벨트를 정장에 매는 것은 더 웃기다.&lt;br /&gt;&lt;br /&gt;37. BY THE WAY 페라가모 벨트는 정말 별로다.페라가모의 로퍼는 더 후지다. 커다란 로고꼴 하고는....&lt;br /&gt;&lt;br /&gt;38. 벨트와 서스펜더는 함께 하지 않는다. 속옷을 두 개 입는 것과 같다.&lt;br /&gt;&lt;br /&gt;39. 수트 차림에 시간이 숫자로 표시되는 러버 잰드 시계는 어울리지 않는다.&lt;br /&gt;&lt;br /&gt;40. 디자인이 복잡하고 화려한 시계 역시 수트 차림에 어울리지 않는다.&lt;br /&gt;&lt;br /&gt;41. 수트에 어울리는 시계는 블랙 혹은 브라운 가죽 스트랩.&lt;br /&gt;&lt;br /&gt;42. 설사 구두를 닦으러 보낸 동안이라 하더라도 수트 차림에 슬리퍼를 신고 있지 말아라.&lt;br /&gt;&lt;br /&gt;43. 기온이 40도까지 올라간다 하더라도 수트 차림에 샌들을 신는 것은 금물이다.&lt;br /&gt;&lt;br /&gt;44. 스니커는 당신을 어려보이게 해주지만 때로는 당신을 코메디언처럼 보이게도 한다.&lt;br /&gt;&lt;br /&gt;45. 로퍼 역시 중요한 사업 파트너를 만나러 갈 때 신기엔 너무 캐주얼 하다.&lt;br /&gt;&lt;br /&gt;46. 한 켤레 구두를 이틀 연속해서 신는 것은 무조건 피하는 것이 좋다.&lt;br /&gt;&lt;br /&gt;47. 소위 말하는 '불광'을 이용해 구두를 닦는 곳에는 구두를 맡기지 마라. 구두 수명이 1/2로 단축된다.&lt;br /&gt;&lt;br /&gt;48. 여자들은 당신 구두가 얼마짜리인지 귀신같이 알아챈다. 단, 관리를 잘한다면 귀신도 모른다.&lt;br /&gt;&lt;br /&gt;49. 구두는 아무리 깨끗해도 지나치지 않다.&lt;br /&gt;&lt;br /&gt;50. 구두는 운동화와 다르다. 구겨신지 마라.&lt;br /&gt;&lt;br /&gt;51. 구두 소재는 반드시 천연가죽이어야 한다.&lt;br /&gt;&lt;br /&gt;52. 뱀피로 만들어진 신발은 레니 크레비츠를 위한 것이지 당신을 위한 것은 아니다.&lt;br /&gt;&lt;br /&gt;53. 악어 가죽 역시 마찬가지다.&lt;br /&gt;&lt;br /&gt;54. 흰 색 신발은 조깅화만으로도 충분하다.&lt;br /&gt;&lt;br /&gt;55. 어지러운 프린트의 실크 타이보다 검은 색 니트 타이가 훨씬 더 멋스럽다.&lt;br /&gt;&lt;br /&gt;56. 타이를 고를 때 신경 써야 할 것은 컬러와 패턴만이 아니다. 반드시 얼마나 모양이 잘 만들어지는지 살펴보아야 한다. 매어보지 못하게 하는 타이 매장은 두번 다시 가지 마라.&lt;br /&gt;&lt;br /&gt;57. 재킷 라펠 크기가 커지면 넥타이 매듭도 커져야 한다. 이 두가지는 함께 가는 것이다.&lt;br /&gt;&lt;br /&gt;58. 넥타이는 세탁하면 금방 망가진다. 세탁하지 않아도 되도록 깨끗하게 매라.&lt;br /&gt;&lt;br /&gt;59. 세로 줄무늬 타이는 사지 마라. 선물로 받았다면? 그래도 매지 마라.&lt;br /&gt;&lt;br /&gt;60. 보우 타이를 맬 수 있는 옷은 원칙적으로는 턱시도 뿐이다. 랄프로렌에서 디스플레이한다고 해서 직접 하려는 시도를? 용기만은 지지.&lt;br /&gt;&lt;br /&gt;61. 넥타이 끝은 젤대 벨트 가장 아랫부분보다 아랫쪽에 위치해서는 안된다.&lt;br /&gt;&lt;br /&gt;62. 헤비 메탈 가수나 로커 얼굴이 프린트되어있는 넥타이는 스무살이 넘은 남자에겐 어울리지 않는다.&lt;br /&gt;&lt;br /&gt;63. 자동차 안전벨트는 반드시 넥타이 밑에 있어야 한다.&lt;br /&gt;&lt;br /&gt;64. 어떤 상황에서도 넥타이 끝부분을 셔츠 가슴 포켓에 구겨 넣지마라. 차라리 풀어라.&lt;br /&gt;&lt;br /&gt;65. 넥타이 핀은 타이 뒷쪽 상표가 위치한 자리에 꽂아준다. 하지만 왠만하면 하지 마시라.&lt;br /&gt;&lt;br /&gt;66. 브리프케이스는 비지니스맨 필수품이다.&lt;br /&gt;&lt;br /&gt;67. 수트에 백팩을 메도 멋있는 건 정우성과 조인성 뿐이다.&lt;br /&gt;&lt;br /&gt;68. 싸구려 브리프케이스를 들고 다닐바에는 100원짜리 서류봉투를 들고 다녀라.&lt;br /&gt;&lt;br /&gt;69. 양말은 반드시 신어야 한다.&lt;br /&gt;&lt;br /&gt;70. 양말 색은 바지 색에 맞춘다.&lt;br /&gt;&lt;br /&gt;71. 표현을 하기 위해 일부러흰 양말을 선택한다면 굳이 말리지는 않겠다.&lt;br /&gt;&lt;br /&gt;72. 장지갑을 바지 뒷주머니에 꽂는 것은 소매치기를 유혹할 때나 하는 짓이다. 머니 클립을 이용해 보자.&lt;br /&gt;&lt;br /&gt;73. 바지 뒷주머니에는 잘 다려진 손수건을 넣어 두어라.&lt;br /&gt;&lt;br /&gt;74. 잘 정돈된 헤어스타일은 값비싼 수트처럼 당신을 멋져 보이게 한다.&lt;br /&gt;&lt;br /&gt;75. 헤어스타일은 적어도 한달에 한번, 가능하다면 한달에 두번 다듬어 준다.&lt;br /&gt;&lt;br /&gt;76. 반지는 하나면 충분하다.&lt;br /&gt;&lt;br /&gt;77. 장교 반지나 졸업 반지 등은 하나도 곤란하다.&lt;br /&gt;&lt;br /&gt;78. 타이 핀이나, 반지, 커프링크스 등 장신구 컬러는 통일하는 것이 좋다.&lt;br /&gt;&lt;br /&gt;79. 안경이 갑자기 부러질 때를 대비해서 사무실 서랍에 여벌의 안경을 준비해 놓는 것이 좋다. 수트를 입었다면 부드러운 표정을 지어라.&lt;br /&gt;&lt;br /&gt;80. 안경은 벨트와 구두 색깔에 맞추는 것이 좋다.&lt;br /&gt;&lt;br /&gt;81. 사람들은 당신의 수트가 얼마짜리인지 알아채기에 앞서 당신 코에 삐져나온 코털을 먼저 발견하게 된다.&lt;br /&gt;&lt;br /&gt;82. 면도가 잘되어 있는 턱은 깨끗한 셔츠만큼이나 중요하다.&lt;br /&gt;&lt;br /&gt;83. 간혹 턱은 깨끗하게 면도 하면서 코와 입 사이를 잊는 남자들이 있다. 거울은 장식품이 아니다.&lt;br /&gt;&lt;br /&gt;84. 지저분한 손톱은 당신의 수트까지 싸구려로 전락시킨다.&lt;br /&gt;&lt;br /&gt;85. 네일케어 숍에서 손톱을 정리하는 것도 나쁘지 않다. 메니큐어만 칠하지 않는다면..&lt;br /&gt;&lt;br /&gt;86. 입가에 허옇게 일어난 각질은 어깨 위에 떨어진 비듬보다 더 심각하게 당신의 이미지를 손상시킨다.&lt;br /&gt;&lt;br /&gt;87. 그렇다고 어깨위에 떨어진 비듬이 괜찮다는 건 절대 아니다.&lt;br /&gt;&lt;br /&gt;88. 지저분한 100만원짜리 브랜드보다 깨끗한 10만원짜리 시장 더 멋지게 보일수 있음&lt;br /&gt;&lt;br /&gt;89. 당신의 옷장에 적당한 여유 공간을 남겨두어야 수트가 숨을 쉴 수 있다.&lt;br /&gt;&lt;br /&gt;90. 수트를 걸어둘 땐 반드시 나무로 된 수트용 옷걸이를 사용한다.&lt;br /&gt;&lt;br /&gt;91. 수트 재킷 주머니에는 절대 손을 넣지 않는다.&lt;br /&gt;&lt;br /&gt;92. 바지 주머니에도 가급적 손을 넣지 않는 것이 좋다.&lt;br /&gt;&lt;br /&gt;93. 손이 시리면 장갑을 껴라.&lt;br /&gt;&lt;br /&gt;94. 수트에 어울리는 모자는 훌륭한 액세서리가 된다. 그러나 스틱은 당신이 예순이 될때까지는 잡지 않는 것이 좋다.&lt;br /&gt;&lt;br /&gt;95. 수트를 입었다고 신사가 되는 것은 아니다. 수트를 입을 때는 자신의행동이 수트차림에 어울리는 것인지 항상 생각해 보는 것이 좋다&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-5591453456601927113?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/5591453456601927113/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2009/01/tip-95-gq.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5591453456601927113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5591453456601927113'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2009/01/tip-95-gq.html' title='수트를 제대로 입는 Tip 95가지 -GQ'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-7948816700360319513</id><published>2008-12-03T14:31:00.000+09:00</published><updated>2008-12-03T14:33:32.722+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>프로그래머 십계명</title><content type='html'>&lt;blockquote&gt;1. 정보모음에 소홀히 하지 말고 설명서를 읽음에 게을리 하지 말지어다.&lt;br /&gt;&lt;br /&gt;오늘 필요 없는 정보는 내일 필요하리라. 가장 가치 있고도 저렴한 지식은 책 속에 있느니라. 서점과 동료의 책꽂이에 무엇이 꽂혀 있는지 때때로 살피어라. 무심코 흘렸던 종이 한 장이 너의 근심을 풀어 주었으리라. 설명서는 충분히, 꼼꼼히 읽을지어다. 모든 의문은 설명서를 안 보는데서 생기니라. 그렇더라도 모두 다 읽을 필요는 없느니라. 많은 정보가 능사는 아니니라. 정보의 가치를 찾는 법부터 배우라. 세상엔 너무나 많은 자료와 정보가 넘쳐난다.&lt;br /&gt;&lt;br /&gt;일일이 모두 끌어 모을 생각을 하기 보단 정보를 하나로 꿰는 법부터 먼저 배우는 것이 너의 근심에서 쉽게 벋어나게 하는 방법이 되리라. 일을 시작하기전에 필요한 정보를 꼼꼼히 먼저 챙기는 법부터 배워라. 너희는 먼저 개발 의뢰서를 꼼꼼히 읽을지어다. 만약 개발 의뢰서가 없다면 발주자에게 요구할 지어다. 개발 의뢰서 없는 프로그램은 존재하지 않으니라.&lt;br /&gt;&lt;br /&gt;2. 너의 PC가 안전하다고 믿지 말지어다.&lt;br /&gt;&lt;br /&gt;5분 후에 정전이 되고 내일 너의 하드가 맛이 가리라. 그러니 너의 소중한 소스코드는 정기적으로 여러 군데에 단계별로 백업해 두어라. PC는 평상시엔 안전하다. 그런 실수를 저지르는 것은 네 자신이거나 아니면 외부적인 요인에 기인한다. 항상 백업을 철저히 해두며 백업에 백업까지도 챙겨두라. 그리고 백업을 했다면 리스트를 작성하라. 쓸데없는 백업은 백해 무익하나니 리스트를 항상 유지할 지어다. 너희는 노트를 옆에 끼고 살 지어다. 노트는 너의 생명이며, 너희가 기억하지 못하는 모든 것을 상기시켜 줄지어다.&lt;br /&gt;&lt;br /&gt;3. 변하는 수를 다룰 때에는 늘 조심할지어다.&lt;br /&gt;&lt;br /&gt;정수가 절대로 그 한계를 넘지 않으리라 가정하는 것은 어리석음이라. 127 ,-128 ,255 ,32767 ,-32768 ,65535, 이 숫자들을 너의 골수에 새기어라. 0.0은 0이 아니니 실수는 원래부터 결코 정밀하지 않느니라. 부호 없는 것과 있는 것을 어울리거나 정수끼리 나눌 때에는 늘 조심하여라. 변수는 프로그램의 근원, 프로그램을 작성할때 가장 유의 할 것이 바로 변수의 이름 짓기니라. 이름보고도 성격을 알 수 있게 해두라. 그러나 변수는 성질이 드러우니 변수에 성격을 부여할때는 조심스럽게 할지어다. 너희는 코딩하기 이전에 계획을 할 지어다. 이는 프로그래머가 코더가 아닌 것이니라.&lt;br /&gt;&lt;br /&gt;4. 무슨 일을 반복시킬 때에는 처음과 끝에 유의할지어다.&lt;br /&gt;&lt;br /&gt;너의 컴퓨터는 1보다는 0을 좋아 하니라. 배열의 첨자가 그 범위를 넘지 않을지 손 댈 때마다 따져 보아라. 수식에 1을 더하거나 뺄 때에는 늘 긴장하라. 너의 프로그램은 단지 한 번 덜해서 틀리고 한 번 더해서 다운되느니라. 프로그램을 작성할 땐 계산, 판단, 비교를 그 모든 걸 컴에게 되도록 맡기지 말라. 네 손으로 미리 계산하고 그 결과를 사용하는 방법이 최선이니라. 컴퓨터는 의지가 없나니 네가 잘못하든 잘하든 아무런 상관이 없느라. 너희는 머리가 악세사리가 아님을 기억하고 항상 생각하고 항상 노트에 적을 지어다.&lt;br /&gt;&lt;br /&gt;5. 항상 모든 경우의 수를 고려하고 섣불리 생략하지 말지어다.&lt;br /&gt;&lt;br /&gt;절대로 일어 나지 않을 일은 반드시 일어나고, 가장 드물게 일어날 일이 가장 너를 괴롭히리라. 그러하니 언제나 논리에 구멍이 없는지 꼼꼼히 따져 보고, if를 쓸때에는 else 부터 생각하라. 논리적인 오류는 성급함에서 생기나니 처음엔 항상 원리와 원칙을 지키라. 생각은 네가 하라 그리고 그 결과를 컴에게 시켜라. IF를 쓰기전에 규칙을 세우라. 먼저 IF의 결과에 대한 규칙부터 세우고 따져라. 그리고 논리적인 계산을 IF문장안에서 하지 말라. 하나의 IF문장속에 수많은 논리연산은 버그의 원인이니라. 어느 정도의 프로그램에 대한 윤곽이 잡히면 프로토 타입을 만들지어다. 프로토타입은 프로그램에 대한 시뮬레이션이며 발주자의 요구를 빨리 수용 하는 방법이니라.&lt;br /&gt;&lt;br /&gt;6. 함수 안에서 매개 변수값은 결코 믿지 말지어다.&lt;br /&gt;&lt;br /&gt;지금 그 매개 변수가 결코 가질 수 없다는 값을 내일부터는 가지리라. 그러하니 매개 변수 값이 올바름을 항상 검사할지어다. 그렇더라도 처리 속도가 문제가 되는 경우는 예외이니라. 함수도 하나의 독립적인 프로그램이란 것을 잊지말며, 네가 프로그램을 작성할땐 모든 함수가 되도록이면 독립적으로 돌아가도록 할지어다. 함수의 매개변수는 항상 그 옆에 작은 코맨트와 초기화를 잊지말라. 처음부터 속도문제를 생각하지 말라. 모든 루틴을 최적화 할 수는 없다. 전체 프로그램중에 단 20%가 전체 실행시간에 80%를 점유한다. 프로토 타입에 대한 발주자의 의견을 꼼꼼히 들을 지어다. 이는 발주자에 대한 신뢰도의 척도니라.&lt;br /&gt;&lt;br /&gt;7. 오류를 알려 주는 기능은 있는 대로 모두 활용할지어다.&lt;br /&gt;&lt;br /&gt;컴파일러의 경고는 모두 켜두어라. 경고는 곧 오류이니라. 오류를 알리는 함수의 결과를 확인하지 않는 우를 범하지 말지어다. 모든 파일 입출력과 모든 메모리 할당은 조만간 실패할 것이라. 컴파일러가 모든 경고기능을 동원해도 알려주지 않는 것은 많다. 중요한 건 오류가 생기기전에 규칙을 지켰는지 생각하라. 파일의 입출력과 메모리의 할당은 항상 쌍으로 생각해서 열었다면 닫아주고 할당받았다면 돌려주라. 프로그램의 매인턴앤스를 게을리하지 말지어다. 이는 프로그램 만드는 일 보다 중요한 일이니라.&lt;br /&gt;&lt;br /&gt;8. 한 번의 수정과 재컴파일만으로 연관된 모든 것이 저절로, 강제로 바뀌도록 할지어다.&lt;br /&gt;&lt;br /&gt;어떠한 것을 수정했을 때에 연관된 것이 따라서 변하지 않는다면 그것이 곧 벌레이니라. 컴파일러로 하여금 매개 변수 리스트를 완전하게 검사하도록 하고 언젠가 손대야 하거나 따라서 변해야 하는 수치는 전부 매크로로 치환하며, 형 정의를 적극 활용하여라. 이미 완벽한 루틴을 손대지 말라. 프로그램이 무너지는 가장 첫번째이유는 도미노 현상 때문이나니 한번의 수정과 재컴파일로 쓸데없는 것을 손대게 하지 말라. 컴파일러가 매개변수 리스트를 챙기지 말게 하라. 프로그램에 들어가기 전엔 미리 함수명과 매개변수 리스트를 만들어라. 너희는 프로그램의 도큐멘트를 만드는 일에 게으르지 말지어다. 이는 사용자가 너의 프로그램에 대해서는 바보이기 때문이니라.&lt;br /&gt;&lt;br /&gt;9. 사용자가 알아서 잘 써 주리라고 희망하지 말지어다.&lt;br /&gt;&lt;br /&gt;너의 프로그램은 항상 바보만이 쓰느니라. 사용 설명서를 쓸 때에는 결코 빠뜨리지 말아라. 빠뜨린 만큼 사용자는 너를 괴롭힐 것이니라. 사용자는 나쁜놈이다. 쓸데없는 짓을 잘한다. 무식하다. 인간성도 더럽다. 대부분이 바보며 가끔 똑똑한 사람도 있는데 그 놈은 더 하다. 모든 것을 설명하지 말며 온갖기능을 가진 하나의 프로그램을 작성하려 들지 말라. 많은 기능이 필요한 프로그램은 나누어서 작게 따로 만들어주라. 너희는 공부하는데 게으르지 말지어다. 자고나면 새로운 하드웨어와 새로운 소프트웨어가 나오기 때문이니라.&lt;br /&gt;&lt;br /&gt;10. 매사에 겸손하고 항상 남을 생각할지어다.&lt;br /&gt;&lt;br /&gt;가장 완벽한 프로그램일수록 가장 완벽하게 숨은 벌레가 있느니라. 네가 이 세상 최고의 프로그래머라고 떠들며 자만할 때, 옆집 곳간에서는 훨씬 더 뛰어난 것을 묵묵히 만들고 있느니라. 아무렴 프로그래밍은 혼자 잘나서 할 게 아니니, 너로 인해 다른 사람들도 더불어 잘 되면 그 얼마나 좋은 것이냐. 프로그래머는 논리적으로 생각하여야 하지만 프로그램은 비논리적으로 작성하라. 프로그래머가 경지에 들면 누가 누가 잘하는지 알수가 없는 법, 또한 프로그래머로서의 '무지'에 대해서 잊지마라. 프로그래머의 '무지'는 생략하고, 선택하고, 단순화시키고, 명백하게하는 것이니라. 항상 새로운 아이디어와 새로운 생각으로 무장하라. 그리고 나누라 나누는곳에 기쁨있나니 너희는 모든 프로그램에 대해서 위의 프로시줘를 따를 지니라.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-7948816700360319513?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/7948816700360319513/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2008/12/blog-post.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7948816700360319513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7948816700360319513'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2008/12/blog-post.html' title='프로그래머 십계명'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-1379674775474030061</id><published>2008-11-24T11:03:00.003+09:00</published><updated>2008-11-24T11:23:13.333+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone and iPod'/><title type='text'>iPhone 사용자에 관한 연구 보고서</title><content type='html'>&lt;div&gt;출처 &lt;a href="http://cesuradb.tistory.com/entry/iPhone-사용자-연구-보고서"&gt;http://cesuradb.tistory.com/entry/iPhone-사용자-연구-보고서&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: rgb(136, 18, 128); font-family: -webkit-monospace; font-size: 13px; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;/div&gt;&lt;a href="http://rubiconconsulting.com/" target="_blank"&gt;루비콘 컨설팅&lt;/a&gt;(Rubicon Consultin) 기사다.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;이메일을 가장 많이 사용한다. 특히 쓰기보다 읽기를 중요하게 생각한다. &lt;br /&gt;웹브라우징을 많이 사용한다.&lt;br/&gt;사용자의 1/3은 세컨드 폰으로 음성/이메일을 사용한다.&lt;br/&gt;절반은 30세 미만, 15%는 학생이다.&lt;br/&gt;대부분의 사용자가 애플의 소비자였다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;루비콘 컨설팅의 보고서&lt;br /&gt;&lt;br/&gt;&lt;a title="iPhone Usage Survey" href="http://rubiconconsulting.com/insight/whitepapers/2008/04/the-apple-iphone-is-easily.html" target="_blank"&gt;[Rubicon Consulting] The Apple iPhone: Successes and Challenges for the Mobile Industry&lt;/a&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-1379674775474030061?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/1379674775474030061/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2008/11/iphone.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1379674775474030061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1379674775474030061'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2008/11/iphone.html' title='iPhone 사용자에 관한 연구 보고서'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2218582835635033278</id><published>2007-09-12T10:49:00.000+09:00</published><updated>2007-09-12T11:06:40.551+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='머리속 그림들'/><title type='text'>해왔던 일들 정리</title><content type='html'>SI에 몸담고 있다보면 여러가지 일을 격게된다.&lt;br /&gt;나는 개발자라고, 프로그램을 만든다고 말을 하고 일을 하고 있지만 사람을 기계의 부품 정도로 여기는 풍조나 좋은 프로그램이 아닌 적당히 굴러갈 수 있는 프로그램 제작에 관심을 기울일 수 밖에 없는 상황을 만나기도 한다.&lt;br /&gt;그리고 그것은 가끔의 상황이 아닌 자주 일어나는 일상이 되어버리곤 한다.&lt;br /&gt;컬럼니스트로 유명한 &lt;a href='http://goodhyun.com/archives/2007/08/691.php'&gt;김국현씨의 블로그&lt;/a&gt;에 쓰라린 이야기가가 있다.&lt;br /&gt;이러한 이야기는 김국현씨의 컬럼외에도 수없이 등장하는 얘기거리지만 다시 생각할 수 있는 시간을 만들어주었다.&lt;br /&gt;&lt;br /&gt;개발이라는 숙명을 갖고 있을지도 모른다. 나 또한 그 운명을 기쁘게 생각한다. 나는 기술이 사람을 행복하게 만들 수 있다는 확신을 갖고 있기 때문이다.&lt;br /&gt;그러나 과연 내 손으로 만들어진 것들이 내 신념이 그려졌던 것일까? 되돌아보고 싶었다.&lt;br /&gt;지금까지 2년이 조금 넘는 세월동안 한 일들을 곰곰히 생각해봤다. 과연 이 일을 해서 사람을 행복하게 했을지 그렇지 않을지.&lt;br /&gt;LGChem Beijing POP 구축 - 주어진 일을 했다. 받을 그들은 이 일로써는 행복이 무언지도 몰랐다.&lt;br /&gt;LG 화학 POP 개선 - 주어진 일을 했다. 단지 일을 위한 일이었다.&lt;br /&gt;LG 전자 MES - 사용자들은 프로그램이 좋던 나쁘던 사용을 강요받았다. 그래도 내가 만든 건 사람이 편하게 할 지도 몰랐다.&lt;br /&gt;LGChem Poland POP 구축 - 주어진 일을 했다. 그래도 그들이 행복하길 바랬지만 그렇지 못할 것이다.&lt;br /&gt;KT&amp;G PDA 개선 - 분명 이전보다 좋아진 것을 만들었다. 개선된 것에 대해선 행복을 느꼈을 것이다.&lt;br /&gt;LGChem Taiwan POP 구축 - 주어진 일을 했다. 이것도 일을 위한 일이었다.&lt;br /&gt;&lt;br /&gt;지금도 생각은 바뀌질 않는다. 기술은 사람을 기쁘게 하기 위해서 쓰여야 한다. 그리고 난 그 기술을 사용하며 더욱 갈고 닦고 싶다.&lt;br /&gt;지금 내가 탄 배가 그곳으로 나아가고 있을까? 이것은 그렇지 않다는 확신이 매번 든다. 그리고 계속 그렇지 않다는 증거만을 갈무리하여 머리속에 남겨나가고 있다.&lt;br /&gt;배에서 내리기 위해선 육지가 필요하다. 그렇지 않으면 다른 배가 필요하다. 내 손에는 깃발이 있고 어디엔가 꽂고 싶다.&lt;br /&gt;&lt;br /&gt;때와 장소를 찾자.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2218582835635033278?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2218582835635033278/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/09/blog-post.html#comment-form' title='1개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2218582835635033278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2218582835635033278'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/09/blog-post.html' title='해왔던 일들 정리'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-4195499189893282564</id><published>2007-08-27T16:53:00.000+09:00</published><updated>2007-08-27T16:56:18.741+09:00</updated><title type='text'>퇴근에 대한 소고</title><content type='html'>일하다 말고 이것저것 보다가 마음이 가는 글이 있어 써놓는다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;출처 - &lt;a href="http://www.okjsp.pe.kr/seq/102387"&gt;http://www.okjsp.pe.kr/seq/102387&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;큰일이다.&lt;br /&gt;&lt;br /&gt;퇴근하고 일터에서 내의지가 아닌 타인의 의지로 인해 움직였던 이 몸뚱아리를 이끌고 그위에는 일터에서의 일거리 스트레스밖에 남아있지 않은 머리를 달고 다시 집으로 무반사적으로 움직인다. &lt;br /&gt;&lt;br /&gt;어디쯤가면 지하철 표를 집어넣고 어디쯤 내려가서 지하철 몇번째 칸에 몸을 실고... &lt;br /&gt;&lt;br /&gt;그렇게 그렇게 집에 간다.&lt;br /&gt;&lt;br /&gt;집이다. 그나마 내 의지가 내 몸을 마음대로 다룰수 있는 곳이다.&lt;br /&gt;&lt;br /&gt;..라고 생각했다.&lt;br /&gt;&lt;br /&gt;그러나 그 생각은 단지 생각 뿐이다.&lt;br /&gt;&lt;br /&gt;혼자서 집에서 살림하느라 동네 아줌마들과 노느라 아기 키우느라 바쁜 아내가 내가 오기만을 기다린다.&lt;br /&gt;&lt;br /&gt;오자마자 씻고 시원한 에어컨 바람아래 늘어진다.&lt;br /&gt;&lt;br /&gt;그리고 아내의 하루 이야기... 재잘재잘... &lt;br /&gt;&lt;br /&gt;아... 아내는 나보다 더 바쁘게 하루를 살았구나... &lt;br /&gt;&lt;br /&gt;머리속에 더 이상 그 이야기들을 집어넣을 공간이 없다. 머리 아프다. 내 머리의 용량은 이미 한계를 넘었다.. &lt;br /&gt;&lt;br /&gt;그렇다고 아내한테 머리아프다고 말하기도 그렇다. 안들어주면 아내는 삐진다. &lt;br /&gt;&lt;br /&gt;아내는 그나마 가정의 식구이자 든든한 남편이 직장에서 축 늘어져서 오는 것을 보고 안쓰러워할테니 집에서라도 그나마 힘이 있어보여야 하는데.. 그게 쉽지 않다. &lt;br /&gt;&lt;br /&gt;하지만 건성으로 들어준다거나 대답하면 아내는 건성으로 한다고 또 삐진다.&lt;br /&gt;&lt;br /&gt;결혼하니까 아내한테 관심이 없어졌느니 결혼전에는 그렇게 다정한 남편이 결혼하니까 너무 무덤덤해졌다고 삐지기도 하고... &lt;br /&gt;&lt;br /&gt;그리고 아내는 결혼전 데이트할때 다니던 회사의 누가 와이셔츠가 이쁘니 넥타이가 이쁘니 어느 대리가 멋지니 부장은 매너없니 이런 이야기 하곤 했다.&lt;br /&gt;&lt;br /&gt;모르는 소리다. &lt;br /&gt;&lt;br /&gt;멋진 그 대리조차 직장은 힘든 곳이다. &lt;br /&gt;&lt;br /&gt;매너없는 부장도 이제 모가지가 달랑달랑한 시기다.&lt;br /&gt;&lt;br /&gt;미혼일때는 남자들의 멋진 모습을 찾았겠지만 그 멋진 모습조차 사회에서 살아남기 위한 위장이다. &lt;br /&gt;&lt;br /&gt;누구나 지치고 힘이 든 곳이 직장이지, 직장이 편하고 행복하면 샐러리맨들이 포장마차에서 소주잔을 빨며 내놓은 안주앞에 한숨을 쉬지는 않을 것이다. &lt;br /&gt;  &lt;br /&gt;집에서 쉬면서 스트레스 풀고 싶다. 집이 내 힘들고 지친 몸과 영혼을 쉬게 해주는 곳이였으면 좋겠다.&lt;br /&gt;&lt;br /&gt;아내가 내 몸과 영혼을 어루만져줬으면 좋겠다.  &lt;br /&gt;&lt;br /&gt;모든 남편이 일탈을 생각하지않고 직장을 마치고 다른 곳으로 가지 않고도 집이라는 포근하고 따스한 곳으로 발길을 돌릴수 있도록...&lt;br /&gt;&lt;br /&gt;아내를 사랑하기에 아내에게 싫은 소리 하기 싫어 나 혼자 삭인다고 아내는 또 투정을 부린다. &lt;br /&gt;&lt;br /&gt;당신한테 밖에서 들고온 이 무거운 짐을 넘기기 싫어 아무것도 아니라 말하면 자기는 함께 살아가자면서 왜 혼자 낑낑대냐고 또 뭐라 한다.&lt;br /&gt;&lt;br /&gt;문득 아버지가 생각난다. &lt;br /&gt;&lt;br /&gt;일 마치고 퇴근하신 아버지가 문을 열고 들어오실때 건성으로 대답한 "다녀오셨어요" 라는 말..&lt;br /&gt;&lt;br /&gt;아버지 죄송해요.. &lt;br /&gt;&lt;br /&gt;... 삶이 힘들땐... 아버지를 생각하자. &lt;br /&gt;&lt;br /&gt;사회에 나와 결혼을 하고 가정을 꾸리고 아기를 키우면서.. &lt;br /&gt;&lt;br /&gt;이 세상에서 나의 아버지는 정말 대단한 분이시다. &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;okjsp.pe.kr 은 나같이 SI에 일하는 많은 사람들이 오가는 곳이다.&lt;br /&gt;그래서인가, 동감가는 얘기들이 많다.&lt;br /&gt;오늘은 퇴근하면 무슨 일이 일어날까..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-4195499189893282564?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/4195499189893282564/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/blog-post_27.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/4195499189893282564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/4195499189893282564'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/blog-post_27.html' title='퇴근에 대한 소고'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-5688015739128341662</id><published>2007-08-17T13:28:00.000+09:00</published><updated>2007-08-17T13:29:37.091+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>카라잔 황천의 원령 공략법</title><content type='html'>&lt;a href="http://blog.love-02.com/95"&gt;카라잔 황천의 원령 공략법&lt;/a&gt; 괜찮은 게 있어서 링크.&lt;br /&gt;후후..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-5688015739128341662?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/5688015739128341662/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/blog-post_17.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5688015739128341662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5688015739128341662'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/blog-post_17.html' title='카라잔 황천의 원령 공략법'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-5282565028164671792</id><published>2007-08-16T17:47:00.000+09:00</published><updated>2007-08-16T17:51:45.981+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='머리속 그림들'/><title type='text'>고민+고민 = "하늘은 푸르다."</title><content type='html'>고민에 일 할 의욕이 바닦까지 내려가서 하늘보고 한숨쉬고 있었다.&lt;br /&gt;덥디더운 무더운 날씨에 땀이 배여 나온다.&lt;br /&gt;하늘은 여전히 파랗고..&lt;br /&gt;날씨가 정말 환하다.&lt;br /&gt;그러고보면 아직 할만한 세상이 맞는 듯 하다.&lt;br /&gt;&lt;br /&gt;저절로 기운이 돈다. 감사함이 기운을 북돋는다.&lt;br /&gt;꼭 해야할 것&lt;br /&gt;&lt;br /&gt;공부 계획 세우기&lt;br /&gt;공부할 웹페이지 만들기 -&gt; 커뮤니티 만들기&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-5282565028164671792?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/5282565028164671792/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/blog-post_2112.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5282565028164671792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5282565028164671792'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/blog-post_2112.html' title='고민+고민 = &quot;하늘은 푸르다.&quot;'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-9209238802506398832</id><published>2007-08-16T10:03:00.000+09:00</published><updated>2007-08-16T10:16:57.874+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='머리속 그림들'/><title type='text'>직장에 대한 고민</title><content type='html'>SI 만 2년이 되어간다.&lt;br /&gt;제대로된 패키지를 만들겠다고 한 의욕이 꺾여가고 있다.&lt;br /&gt;소프트웨어 기술에 대해 이해가 부족한 사업부장이나 인력파견에서 벗어나지 못하는 사업구조가 바뀌질 않고 어려워지는 사업을 타개할 방법을 제대로 찾지 못하고 있다.&lt;br /&gt;말아먹고 있는 대한민국 IT 업계의 현실(&lt;a href="http://www.zdnet.co.kr/itbiz/column/anchor/hsryu/0,39030308,39160320,00.htm"&gt;IT 업계 빅3의 빛과 그림자&lt;/a&gt;)에서 벗어나지 못하는 한 능력이 부족한 작은 이 회사에서 과연 미래가 있을까 하는 의문이 게속 솟구친다.&lt;br /&gt;&lt;br /&gt;더 나은 기술이 있어도 사용되지 못하고, 더 나은 능력이 있어도 사용되지 못하는 것 만큼 답답한 것도 없을 것이다.&lt;br /&gt;다음 프로젝트는 안성에 있는 농협에 쇼핑몰에 몇가지 더 첨가하는 일을 하게 될 것 같다. 4개월.&lt;br /&gt;건설업계같이 사람 머리수 만을 돈으로 계산하고, 더욱 싼 인력만 찾는 이곳에 정이 들 수가 없다.&lt;br /&gt;대기업은 기술발전이란는 건 안중에도 없고, 대기업 아니어도 기술선도라는 걸 기대할 수도 없다.&lt;br /&gt;내 손끝에서 나오는 것을 인정받지 못하고 서류상에 적혀있는 머리수의 단가만을 인정받을 수 있다는 게 정말 질린다.&lt;br /&gt;&lt;br /&gt;내 아내를 보며 참고, 시간이 흘러 더욱 많은 무기과 능력을 갖추기까지 참고 또 참는 것을 잘 할 수 있으런지 모르겠다.&lt;br /&gt;지금 업무에 활용되지 않을 좋은 기술들을 갈고 닦는 게 쉬운 일이 아니라는 걸. 또 아무리 싫다고 해도 맞겨진 일을 술렁술렁 넘겨버리는 것도 성격상 하지 못하고, 쓰린 맘을 추스리는데 보내는 시간이 아깝다.&lt;br /&gt;&lt;br /&gt;방책을 구해야겠다. 여러가지로, 여러면으로.&lt;br /&gt;고민하고 실천하기를 시간 앞에서 당당하게.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-9209238802506398832?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/9209238802506398832/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/blog-post_16.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/9209238802506398832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/9209238802506398832'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/blog-post_16.html' title='직장에 대한 고민'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2975169772010379460</id><published>2007-08-10T12:56:00.000+09:00</published><updated>2007-08-10T12:59:43.913+09:00</updated><title type='text'>iBatis in Action</title><content type='html'>&lt;a href="http://www.lsl.com.au/images/images-ref/ibatis-in-action.jpg"&gt;&lt;img style="float:center; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px;" src="http://www.lsl.com.au/images/images-ref/ibatis-in-action.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;요전에 주문한 책이 어제 도착했다.&lt;br /&gt;짐 옆에 끼고 있긴한데 볼 시간이 있으려나..&lt;br /&gt;&lt;br /&gt;P.S 물론 한글판. 이미지만 영문으로.. ~_~&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2975169772010379460?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2975169772010379460/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/ibatis-in-action.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2975169772010379460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2975169772010379460'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/ibatis-in-action.html' title='iBatis in Action'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2299405923329703536</id><published>2007-08-08T17:31:00.000+09:00</published><updated>2007-08-08T17:54:32.211+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for DBMS'/><title type='text'>Oracle - Create sequance</title><content type='html'>-----------------------------------------------&lt;br /&gt;-- Export file for user SAMPLEUSER           --&lt;br /&gt;-----------------------------------------------&lt;br /&gt;&lt;br /&gt;spool s070614.log&lt;br /&gt;&lt;br /&gt;prompt&lt;br /&gt;prompt Creating sequence IEBKNIFE_SEQ&lt;br /&gt;prompt ==============================&lt;br /&gt;prompt&lt;br /&gt;create sequence SAMPLEUSER.IEBKNIFE_SEQ&lt;br /&gt;minvalue 1&lt;br /&gt;maxvalue 9999999&lt;br /&gt;start with 2541&lt;br /&gt;increment by 1&lt;br /&gt;cache 20&lt;br /&gt;cycle;&lt;br /&gt;&lt;br /&gt;prompt&lt;br /&gt;prompt Creating sequence IEBPS_SEQ&lt;br /&gt;prompt ===========================&lt;br /&gt;prompt&lt;br /&gt;create sequence SAMPLEUSER.IEBPS_SEQ&lt;br /&gt;minvalue 1&lt;br /&gt;maxvalue 9999999&lt;br /&gt;start with 240753&lt;br /&gt;increment by 1&lt;br /&gt;cache 20&lt;br /&gt;cycle;&lt;br /&gt;&lt;br /&gt;prompt&lt;br /&gt;prompt Creating sequence SAMPLEUSER_SEQ&lt;br /&gt;prompt ===========================&lt;br /&gt;prompt&lt;br /&gt;create sequence SAMPLEUSER.SAMPLEUSER_SEQ&lt;br /&gt;minvalue 1&lt;br /&gt;maxvalue 9999&lt;br /&gt;start with 2021&lt;br /&gt;increment by 1&lt;br /&gt;cache 20&lt;br /&gt;cycle;&lt;br /&gt;&lt;br /&gt;prompt&lt;br /&gt;prompt Creating sequence SAMPLEUSER_UNITPACK&lt;br /&gt;prompt ================================&lt;br /&gt;prompt&lt;br /&gt;create sequence SAMPLEUSER.SAMPLEUSER_UNITPACK&lt;br /&gt;minvalue 1&lt;br /&gt;maxvalue 1295&lt;br /&gt;start with 61&lt;br /&gt;increment by 1&lt;br /&gt;cache 20&lt;br /&gt;cycle;&lt;br /&gt;&lt;br /&gt;prompt&lt;br /&gt;prompt Creating sequence SCHEDULE_SEQ&lt;br /&gt;prompt ==============================&lt;br /&gt;prompt&lt;br /&gt;create sequence SAMPLEUSER.SCHEDULE_SEQ&lt;br /&gt;minvalue 1&lt;br /&gt;maxvalue 9999999&lt;br /&gt;start with 1&lt;br /&gt;increment by 1&lt;br /&gt;nocache;&lt;br /&gt;&lt;br /&gt;prompt&lt;br /&gt;prompt Creating sequence TBL_SEQ&lt;br /&gt;prompt =========================&lt;br /&gt;prompt&lt;br /&gt;create sequence SAMPLEUSER.TBL_SEQ&lt;br /&gt;minvalue 1&lt;br /&gt;maxvalue 999999999999999999&lt;br /&gt;start with 239472&lt;br /&gt;increment by 1&lt;br /&gt;cache 20&lt;br /&gt;cycle;&lt;br /&gt;&lt;br /&gt;prompt&lt;br /&gt;prompt Creating sequence TOL_SEQ&lt;br /&gt;prompt =========================&lt;br /&gt;prompt&lt;br /&gt;create sequence SAMPLEUSER.TOL_SEQ&lt;br /&gt;minvalue 1&lt;br /&gt;maxvalue 9999999&lt;br /&gt;start with 2874463&lt;br /&gt;increment by 1&lt;br /&gt;cache 20&lt;br /&gt;cycle;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;spool off&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2299405923329703536?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2299405923329703536/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle-create-sequance.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2299405923329703536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2299405923329703536'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle-create-sequance.html' title='Oracle - Create sequance'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2789648076031685888</id><published>2007-08-08T17:20:00.000+09:00</published><updated>2007-08-08T17:55:27.785+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for DBMS'/><title type='text'>Oracle - Create table and index</title><content type='html'>spool DB_Table.log&lt;br /&gt;&lt;br /&gt;create table SAMPLEUSER.MY_DUAL&lt;br /&gt;(&lt;br /&gt;  X NUMBER not null,&lt;br /&gt;  primary key (X)&lt;br /&gt;)&lt;br /&gt;organization index;&lt;br /&gt;&lt;br /&gt;create table SAMPLEUSER.TB_IEM902&lt;br /&gt;(&lt;br /&gt;  PLANT_CD     VARCHAR2(4) not null,&lt;br /&gt;  MANA_NO      VARCHAR2(18) not null,&lt;br /&gt;  MANA_NM      VARCHAR2(50),&lt;br /&gt;  USE_YN       VARCHAR2(1) default 'N',&lt;br /&gt;  MANA_NM_ENG  VARCHAR2(50),&lt;br /&gt;  INSERT_DATE  DATE default SYSDATE,&lt;br /&gt;  INSERT_USER  VARCHAR2(20),&lt;br /&gt;  UPDATE_DATE  DATE default SYSDATE,&lt;br /&gt;  UPDATE_USER  VARCHAR2(20),&lt;br /&gt;  DEL_FLAG     VARCHAR2(1) default 'A' not null,&lt;br /&gt;  LEVEL_CD     VARCHAR2(30),&lt;br /&gt;  UPDATE_DATE1 VARCHAR2(14),&lt;br /&gt;  TYPE         VARCHAR2(4)&lt;br /&gt;)&lt;br /&gt;tablespace SAMPLEUSER_TABLE&lt;br /&gt;  pctfree 20&lt;br /&gt;  initrans 1&lt;br /&gt;  maxtrans 255&lt;br /&gt;  storage&lt;br /&gt;  (&lt;br /&gt;    initial 1M&lt;br /&gt;    minextents 1&lt;br /&gt;    maxextents unlimited&lt;br /&gt;  );&lt;br /&gt;comment on table SAMPLEUSER.TB_IEM902&lt;br /&gt;  is '관리코드정보';&lt;br /&gt;alter table SAMPLEUSER.TB_IEM902&lt;br /&gt;  add constraint TB_IEM902_PK primary key (PLANT_CD, MANA_NO)&lt;br /&gt;  using index &lt;br /&gt;  tablespace SAMPLEUSER_TABLE&lt;br /&gt;  pctfree 10&lt;br /&gt;  initrans 2&lt;br /&gt;  maxtrans 255&lt;br /&gt;  storage&lt;br /&gt;  (&lt;br /&gt;    initial 64K&lt;br /&gt;    minextents 1&lt;br /&gt;    maxextents unlimited&lt;br /&gt;  );&lt;br /&gt;create index SAMPLEUSER.TB_IEM902_X1 on SAMPLEUSER.TB_IEM902 (PLANT_CD)&lt;br /&gt;  tablespace SAMPLEUSER_INDEX&lt;br /&gt;  pctfree 10&lt;br /&gt;  initrans 2&lt;br /&gt;  maxtrans 255&lt;br /&gt;  storage&lt;br /&gt;  (&lt;br /&gt;    initial 4M&lt;br /&gt;    next 16K&lt;br /&gt;    minextents 1&lt;br /&gt;    maxextents unlimited&lt;br /&gt;    pctincrease 0&lt;br /&gt;  );&lt;br /&gt;create index SAMPLEUSER.TB_IEM902_X2 on SAMPLEUSER.TB_IEM902 (PLANT_CD, LEVEL_CD)&lt;br /&gt;  tablespace SAMPLEUSER_TABLE&lt;br /&gt;  pctfree 10&lt;br /&gt;  initrans 2&lt;br /&gt;  maxtrans 255&lt;br /&gt;  storage&lt;br /&gt;  (&lt;br /&gt;    initial 64K&lt;br /&gt;    minextents 1&lt;br /&gt;    maxextents unlimited&lt;br /&gt;  );&lt;br /&gt;grant select, insert, update, delete, references, index on SAMPLEUSER.TB_IEM902 to IEOPT;&lt;br /&gt;grant select, insert, update, delete, references, index on SAMPLEUSER.TB_IEM902 to SAMPLEUSEROC;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;spool off&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2789648076031685888?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2789648076031685888/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle-create-table-and-index.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2789648076031685888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2789648076031685888'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle-create-table-and-index.html' title='Oracle - Create table and index'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-7951056976067744898</id><published>2007-08-08T17:17:00.000+09:00</published><updated>2007-08-08T17:18:41.669+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for DBMS'/><title type='text'>Oracle - create table space user 테이블스페이스 유저 생성</title><content type='html'>CREATE TABLESPACE "SAMPLE_TABLE" LOGGING DATAFILE &lt;br /&gt;    '/oradata/iepcs/SAMPLE_TABLE1.dbf' SIZE 100M REUSE, &lt;br /&gt;    '/oradata/iepcs/SAMPLE_TABLE2.dbf' SIZE 100M REUSE, &lt;br /&gt;    '/oradata/iepcs/SAMPLE_TABLE3.dbf' SIZE 100M REUSE, &lt;br /&gt;    '/oradata/iepcs/SAMPLE_TABLE4.dbf' SIZE 100M REUSE, &lt;br /&gt;    '/oradata/iepcs/SAMPLE_TABLE5.dbf' SIZE 100M REUSE EXTENT MANAGEMENT LOCAL &lt;br /&gt;    SEGMENT SPACE MANAGEMENT  AUTO;&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;CREATE TABLESPACE "SAMPLE_INDEX" LOGGING DATAFILE &lt;br /&gt;    '/oraindex/iepcs/SAMPLE_INDEX01.dbf' SIZE 100M REUSE, &lt;br /&gt;    '/oraindex/iepcs/SAMPLE_INDEX02.dbf' SIZE 100M REUSE, &lt;br /&gt;    '/oraindex/iepcs/SAMPLE_INDEX03.dbf' SIZE 100M REUSE, &lt;br /&gt;    '/oraindex/iepcs/SAMPLE_INDEX04.dbf' SIZE 100M REUSE, &lt;br /&gt;    '/oraindex/iepcs/SAMPLE_INDEX05.dbf' SIZE 100M REUSE EXTENT MANAGEMENT LOCAL &lt;br /&gt;    SEGMENT SPACE MANAGEMENT  AUTO;&lt;br /&gt;    &lt;br /&gt;CREATE TEMPORARY TABLESPACE "SAMPLE_TEMP" TEMPFILE &lt;br /&gt;   '/oradata/iepcs/SAMPLE_TEMP01.dbf' SIZE 100M REUSE, &lt;br /&gt;   '/oradata/iepcs/SAMPLE_TEMP02.dbf' SIZE 100M REUSE, &lt;br /&gt;   '/oradata/iepcs/SAMPLE_TEMP03.dbf' SIZE 100M REUSE EXTENT MANAGEMENT LOCAL &lt;br /&gt;    UNIFORM SIZE 1024K;&lt;br /&gt;ALTER DATABASE DEFAULT TEMPORARY TABLESPACE "SAMPLE_TEMP";       &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;CREATE USER "SAMPLEUSER"  PROFILE "DEFAULT" &lt;br /&gt;    IDENTIFIED BY "SAMPLEUSER" DEFAULT TABLESPACE "SAMPLE_TABLE" &lt;br /&gt;    TEMPORARY TABLESPACE "SAMPLE_TEMP" &lt;br /&gt;    ACCOUNT UNLOCK;&lt;br /&gt;GRANT "CONNECT" TO "SAMPLEUSER";&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;GRANT "CONNECT" TO "SAMPLEUSER";&lt;br /&gt;GRANT "RESOURCE" TO "SAMPLEUSER";&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;사실 위에 내용은 Oracle Enterprise Manager Console에서 GUI로 작업할 수도 있다. -_-&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-7951056976067744898?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/7951056976067744898/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle-create-table-space-user.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7951056976067744898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7951056976067744898'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle-create-table-space-user.html' title='Oracle - create table space user 테이블스페이스 유저 생성'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-8556877407362148832</id><published>2007-08-08T17:06:00.000+09:00</published><updated>2007-08-08T17:12:28.982+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for DBMS'/><title type='text'>Oracle - Index rebuild</title><content type='html'>SELECT&lt;br /&gt; 'ALTER INDEX '|| INDEX_NAME ||' REBUILD UNRECOVERABLE;'&lt;br /&gt;&lt;br /&gt; FROM USER_INDEXES&lt;br /&gt;WHERE INDEX_NAME NOT LIKE '%[SOME_TABLE_NAME]%'&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-8556877407362148832?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/8556877407362148832/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle-index-rebuild.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8556877407362148832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8556877407362148832'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle-index-rebuild.html' title='Oracle - Index rebuild'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-6179660266484841733</id><published>2007-08-08T17:05:00.002+09:00</published><updated>2007-08-08T17:06:46.444+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for DBMS'/><title type='text'>Oracle - 파티션 추가 쿼리</title><content type='html'>ALTER TABLE TB_IEM124 ADD PARTITION TB_IEM124_P1_L_200712&lt;br /&gt;            VALUES ('0L0712') TABLESPACE IEPCS_TABLE&lt;br /&gt;            PCTFREE 20 INITRANS 1 MAXTRANS 255&lt;br /&gt;            STORAGE&lt;br /&gt;    (&lt;br /&gt;      INITIAL 1M&lt;br /&gt;      MINEXTENTS 1&lt;br /&gt;      MAXEXTENTS UNLIMITED&lt;br /&gt;    )&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;ALTER TABLE TB_IEM124 ADD PARTITION TB_IEM124_P1_C_200712&lt;br /&gt;            VALUES ('0C0712') TABLESPACE IEPCS_TABLE&lt;br /&gt;            PCTFREE 20 INITRANS 1 MAXTRANS 255&lt;br /&gt;            STORAGE&lt;br /&gt;    (&lt;br /&gt;      INITIAL 1M&lt;br /&gt;      MINEXTENTS 1&lt;br /&gt;      MAXEXTENTS UNLIMITED&lt;br /&gt;    )&lt;br /&gt;;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-6179660266484841733?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/6179660266484841733/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle_2186.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/6179660266484841733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/6179660266484841733'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle_2186.html' title='Oracle - 파티션 추가 쿼리'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-5875308895726536292</id><published>2007-08-08T17:05:00.001+09:00</published><updated>2007-08-08T17:05:31.707+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for DBMS'/><title type='text'>Oracle - 과도한 디스크 사용 검색</title><content type='html'>select A.disk_reads, A.sql_text,&lt;br /&gt;    B.sid, B.serial#&lt;br /&gt;from v$sqlarea A,&lt;br /&gt;     v$session B&lt;br /&gt;where A.disk_reads &gt; 10000&lt;br /&gt; and  A.ADDRESS = B.SQL_ADDRESS(+)&lt;br /&gt; AND  A.HASH_VALUE = B. SQL_HASH_VALUE(+)&lt;br /&gt;order by A.disk_reads desc;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-5875308895726536292?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/5875308895726536292/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle_08.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5875308895726536292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5875308895726536292'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle_08.html' title='Oracle - 과도한 디스크 사용 검색'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2557549087996677342</id><published>2007-08-08T17:04:00.000+09:00</published><updated>2007-08-08T17:05:03.058+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for DBMS'/><title type='text'>Oracle - 과도한 메모리 사용 검색</title><content type='html'>Select&lt;br /&gt;       D.sid "SID" ,&lt;br /&gt;       --s.serial# "Serial#",&lt;br /&gt;       D.username "Oracle User",&lt;br /&gt;       D.program "Program",&lt;br /&gt;&lt;br /&gt;       D.module "Module",&lt;br /&gt;       D.status "Status",&lt;br /&gt;       D.type "Type",&lt;br /&gt;       D.server "Connection",&lt;br /&gt;       to_char(D.logon_time,'YYYY-MM-DD HH24:MI:SS') "Logon Time",&lt;br /&gt;       D.osuser "OS User"  ,&lt;br /&gt;       decode(D.lockwait,null,'','Blocking') "Lock",&lt;br /&gt;       decode(D.taddr,null,'','TX') "Transaction",&lt;br /&gt;       SYSDATE - (D.last_call_et/86400) "Last Call",&lt;br /&gt;       A.User_Name,       &lt;br /&gt;       D.machine "Machine", &lt;br /&gt;       B.Disk_Reads, &lt;br /&gt;       B.Buffer_Gets, &lt;br /&gt;       B.Rows_Processed, &lt;br /&gt;       C.SQL_Text,&lt;br /&gt;       A.Address&lt;br /&gt;From   V$Open_Cursor A,&lt;br /&gt;       V$SQLArea     B,&lt;br /&gt;       V$SQLText     C,&lt;br /&gt;       sys.v_$session    D&lt;br /&gt;Where    A.User_Name  = Upper('IEPCS')&lt;br /&gt;  AND    B.ADDRESS    = D.SQL_ADDRESS&lt;br /&gt;  AND    B.HASH_VALUE = D.SQL_HASH_VALUE&lt;br /&gt;  And    A.Address    = C.Address&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2557549087996677342?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2557549087996677342/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2557549087996677342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2557549087996677342'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/oracle.html' title='Oracle - 과도한 메모리 사용 검색'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-8562012580286410911</id><published>2007-08-08T17:00:00.000+09:00</published><updated>2007-08-08T17:02:00.272+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for Servers'/><title type='text'>How to install Application Server (Tomcat 4, Apache 2, JK2 1.2) on Redhat linux 9</title><content type='html'>[준비]&lt;br /&gt;  1. Apache&lt;br /&gt;    file(source) : httpd-2.0.50.tar.tar&lt;br /&gt;    url : http://archive.apache.org/dist/httpd/httpd-2.0.50.tar.gz&lt;br /&gt;    다른 버전은 http://archive.apache.org/dist/httpd/ 에서 찾을 수 있다.&lt;br /&gt;  2. J2SDK&lt;br /&gt;    file(binary) : j2sdk-1_4_2_14-linux-i586.bin&lt;br /&gt;    url : http://java.sun.com/j2se/1.4.2/download.html&lt;br /&gt;  3. Tomcat connecter (mod_jk)&lt;br /&gt;    file(source) : tomcat-connectors-1.2.22-src.tar.gz&lt;br /&gt;    url : http://archive.apache.org/dist/tomcat/tomcat-connectors/jk/source/jk-1.2.22/tomcat-connectors-1.2.22-src.tar.gz&lt;br /&gt;    다른 버전은 http://archive.apache.org/dist/tomcat/tomcat-connectors/ 에서 찾을 수 있다.&lt;br /&gt;  4. Tomcat &lt;br /&gt;    file(binary) : jakarta-tomcat-4.1.31.tar.tar&lt;br /&gt;    url : http://archive.apache.org/dist/jakarta/tomcat-4/v4.1.31/bin/jakarta-tomcat-4.1.31.tar.gz&lt;br /&gt;    다른 버전은 http://archive.apache.org/dist/jakarta/ 에서 찾을 수 있다.&lt;br /&gt;  5. 준비된 파일을 /work에 복사한다.&lt;br /&gt;  6. root로 로그인한다.&lt;br /&gt;&lt;br /&gt;[installation]&lt;br /&gt;  1. Apache&lt;br /&gt;    [prompt]# cd /work&lt;br /&gt;    [prompt]# tar xvf httpd-2.0.50.tar.tar&lt;br /&gt;    [prompt]# cd httpd-2.0.50&lt;br /&gt;    [prompt]# ./configure --enable-rule=SHARED_CORE --enable-modules=so --enable-module=rewrite --prefix=/usr/local/apache-2.0.50&lt;br /&gt;    [prompt]# make&lt;br /&gt;    [prompt]# make install&lt;br /&gt;    [prompt]# rm -rf /etc/apache&lt;br /&gt;    [prompt]# rm -rf /etc/httpd&lt;br /&gt;    [prompt]# ln -s /usr/local/apache-2.0.50/conf /etc/apache&lt;br /&gt;    [prompt]# ln -s /usr/local/apache-2.0.50 /usr/local/httpd&lt;br /&gt;    [prompt]# chmod -R 755 /usr/local/apache-2.0.50&lt;br /&gt;    [prompt]# chmod 755 /usr/local/httpd&lt;br /&gt;    [prompt]# export APACHE_HOME=/usr/local/apache-2.0.50&lt;br /&gt;    &lt;br /&gt;  2. J2SDK&lt;br /&gt;    [prompt]# cd /work&lt;br /&gt;    [prompt]# ./j2sdk-1_4_2_14-linux-i586.bin&lt;br /&gt;    [prompt]# ln -s /usr/local/j2sdk1.4.2_14 /usr/local/java&lt;br /&gt;    [prompt]# export CLASSPATH=.:/usr/local/java/lib:usr/local/java/jre/lib:/oracle/product/9.2.0/jdbc/lib/classes12.jar:/oracle/product/9.2.0/jdbc/lib/&lt;br /&gt;    [prompt]# export JAVA_HOME=/usr/local/java&lt;br /&gt;    [prompt]# PATH=$PATH:$JAVA_HOME/bin&lt;br /&gt;    ** PATH로 걸려있는 경로 중 java 의 다른 실행파일이 있다면 다른 이름으로 변경한다.&lt;br /&gt;    ** CLASSPATH의 JDBC 경로 또한 맞는 위치로 바꾼다.&lt;br /&gt;&lt;br /&gt;  3. Tomcat&lt;br /&gt;    [prompt]# tar xvf jakarta-tomcat-4.1.31.tar.tar&lt;br /&gt;    [prompt]# mv jakarta-tomcat-4.1.31 /usr/local&lt;br /&gt;    [prompt]# ln -s /usr/local/jakarta-tomcat-4.1.31 /usr/local/tomcat4&lt;br /&gt;    [prompt]# export TOMCAT_HOME=/usr/local/tomcat4&lt;br /&gt;    [prompt]# export BASEDIR=/usr/local/tomcat4&lt;br /&gt;    [prompt]# export CATALINA_BASE=/usr/local/tomcat4/&lt;br /&gt;    [prompt]# export CATALINA_HOME=/usr/local/tomcat4/&lt;br /&gt;    [prompt]# export CATALINA_TMPDIR=/usr/local/tomcat4/temp&lt;br /&gt;    ** export한 내용은 /etc/profile 에 추가한다&lt;br /&gt;    [prompt]# groupadd tomcat&lt;br /&gt;    [prompt]# useradd tomcat&lt;br /&gt;    [prompt]# passwd&lt;br /&gt;    [prompt]# chown -R tomcat:tomcat /usr/local/jakarta-tomcat-4.1.31&lt;br /&gt;    [prompt]# chmod -R 755 /usr/local/jakarta-tomcat-4.1.31&lt;br /&gt;&lt;br /&gt;  4. mod_jk&lt;br /&gt;    [prompt]# tar xvfz tomcat-connectors-1.2.22-src.tar.gz&lt;br /&gt;    [prompt]# cd tomcat-connectors-1.2.22-src&lt;br /&gt;    [prompt]# ./buildconf.sh&lt;br /&gt;    [prompt]# ./configure --with-apxs=/usr/local/apache-2.0.50/bin/apxs --with-tomcat4=/usr/local/tomcat4&lt;br /&gt;    [prompt]# cd apache-2.0&lt;br /&gt;    [prompt]# make -f Makefile.apxs&lt;br /&gt;    [prompt]# make install&lt;br /&gt;  &lt;br /&gt;[Configuration]&lt;br /&gt;  1.workers.properties&lt;br /&gt;    file : workers.properties&lt;br /&gt;    path : /usr/local/httpd/conf&lt;br /&gt;    context :&lt;br /&gt;      workers.tomcat_home=/usr/local/tomcat&lt;br /&gt;      workers.java_home=/usr/local/java&lt;br /&gt;      ps=/&lt;br /&gt;      worker.list=worker1&lt;br /&gt;      worker.default.port=8009&lt;br /&gt;      worker.default.host=localhost&lt;br /&gt;      worker.default.type=ajp13&lt;br /&gt;      worker.default.lbfactor=1&lt;br /&gt;&lt;br /&gt;  2. httpd.conf&lt;br /&gt;    file : httpd.conf&lt;br /&gt;    path : /usr/local/httpd/conf&lt;br /&gt;    context :&lt;br /&gt;      LoadModule jk_module modules/mod_jk.so&lt;br /&gt;      JkWorkersFile /usr/local/httpd/conf/workers.properties&lt;br /&gt;      JkLogFile /usr/local/httpd/logs/mod_jk.log&lt;br /&gt;      JkLogLevel info&lt;br /&gt;      JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "&lt;br /&gt;      JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories&lt;br /&gt;      JkRequestLogFormat "%w %V %T"&lt;br /&gt;      JkMount /jsp-examples worker1&lt;br /&gt;      JkMount /jsp-examples/* worker1&lt;br /&gt;      JkMount /*.jsp worker1&lt;br /&gt;      JkMount /* worker1&lt;br /&gt;      JkMount /examples worker1&lt;br /&gt;      JkMount /examples/* worker1&lt;br /&gt;      &lt;br /&gt;      DocumentRoot /usr/local/tomcat/webapps/ROOT&lt;br /&gt;      &lt;Directory "/usr/local/tomcat4/webapps/ROOT"&gt;&lt;br /&gt;      ServerName, &lt;br /&gt;      &lt;br /&gt;  3. server.xml&lt;br /&gt;    file : server.xml&lt;br /&gt;    path : /usr/local/tomcat4/conf&lt;br /&gt;    context :&lt;br /&gt;      &lt;Server port="8005" shutdown="SHUTDOWN" debug="0"&gt;&lt;br /&gt;       &lt;Listener className="org.apache.ajp.tomcat4.config.ApacheConfig" /&gt;&lt;br /&gt;        &lt;Listener className="org.apache.catalina.mbeans.ServerLifecycleListener"&lt;br /&gt;                  debug="0"/&gt;&lt;br /&gt;        &lt;Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"&lt;br /&gt;                  debug="0"/&gt;&lt;br /&gt;        &lt;!-- Global JNDI resources --&gt;&lt;br /&gt;        &lt;GlobalNamingResources&gt;&lt;br /&gt;          &lt;!-- Test entry for demonstration purposes --&gt;&lt;br /&gt;          &lt;Environment name="simpleValue" type="java.lang.Integer" value="30"/&gt;&lt;br /&gt;          &lt;!-- Editable user database that can also be used by&lt;br /&gt;               UserDatabaseRealm to authenticate users --&gt;&lt;br /&gt;          &lt;Resource name="UserDatabase" auth="Container"&lt;br /&gt;                    type="org.apache.catalina.UserDatabase"&lt;br /&gt;             description="User database that can be updated and saved"&gt;&lt;br /&gt;          &lt;/Resource&gt;&lt;br /&gt;          &lt;ResourceParams name="UserDatabase"&gt;&lt;br /&gt;            &lt;parameter&gt;&lt;br /&gt;              &lt;name&gt;factory&lt;/name&gt;&lt;br /&gt;              &lt;value&gt;org.apache.catalina.users.MemoryUserDatabaseFactory&lt;/value&gt;&lt;br /&gt;            &lt;/parameter&gt;&lt;br /&gt;            &lt;parameter&gt;&lt;br /&gt;              &lt;name&gt;pathname&lt;/name&gt;&lt;br /&gt;              &lt;value&gt;conf/tomcat-users.xml&lt;/value&gt;&lt;br /&gt;            &lt;/parameter&gt;&lt;br /&gt;          &lt;/ResourceParams&gt;&lt;br /&gt;        &lt;/GlobalNamingResources&gt;&lt;br /&gt;        &lt;!-- Define the Tomcat Stand-Alone Service --&gt;&lt;br /&gt;        &lt;Service name="Tomcat-Standalone"&gt;&lt;br /&gt;          &lt;Connector className="org.apache.coyote.tomcat4.CoyoteConnector"&lt;br /&gt;                     port="8009" minProcessors="5" maxProcessors="75"&lt;br /&gt;                     enableLookups="true" redirectPort="8443"&lt;br /&gt;                     acceptCount="10" debug="0" connectionTimeout="0"&lt;br /&gt;                     useURIValidationHack="false"&lt;br /&gt;                     protocolHandlerClassName="org.apache.jk.server.JkCoyoteHandler"/&gt;&lt;br /&gt;          &lt;!-- Define the top level container in our container hierarchy --&gt;&lt;br /&gt;          &lt;Engine name="Standalone" defaultHost="localhost" debug="0"&gt;&lt;br /&gt;            &lt;Logger className="org.apache.catalina.logger.FileLogger"&lt;br /&gt;                    prefix="catalina_log." suffix=".txt"&lt;br /&gt;                    timestamp="true"/&gt;&lt;br /&gt;            &lt;Realm className="org.apache.catalina.realm.UserDatabaseRealm"&lt;br /&gt;                       debug="0" resourceName="UserDatabase"/&gt;&lt;br /&gt;            &lt;!-- Define the default virtual host --&gt;&lt;br /&gt;            &lt;Host name="localhost" debug="0" appBase="webapps"&gt;&lt;br /&gt;              &lt;Listener className="org.apache.ajp.tomcat4.config.ApacheConfig" append="true" /&gt;&lt;br /&gt;              &lt;Context path="" docBase="ROOT" debug="0"&lt;br /&gt;                       reloadable="true" crossContext="true"&gt;&lt;br /&gt;                &lt;Logger className="org.apache.catalina.logger.FileLogger"&lt;br /&gt;                           prefix="localhost_log." suffix=".txt"&lt;br /&gt;                    timestamp="true"/&gt;&lt;br /&gt;              &lt;/Context&gt;&lt;br /&gt;            &lt;/Host&gt;&lt;br /&gt;          &lt;/Engine&gt;&lt;br /&gt;        &lt;/Service&gt;&lt;br /&gt;      &lt;/Server&gt;&lt;br /&gt;&lt;br /&gt;  4. Program copy&lt;br /&gt;    [prompt]# cp /work/ROOT /usr/local/tomcat4/webapps/ROOT&lt;br /&gt;&lt;br /&gt;  3. server.xml&lt;br /&gt;    file : web.xml&lt;br /&gt;    path : /work/ROOT /usr/local/tomcat4/webapps/ROOT/WEB-INF&lt;br /&gt;    context :&lt;br /&gt;      &lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;&lt;br /&gt;      &lt;!DOCTYPE web-app&lt;br /&gt;          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"&lt;br /&gt;          "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;&lt;br /&gt;      &lt;web-app&gt;&lt;br /&gt;        &lt;display-name&gt;Welcome to Tomcat&lt;/display-name&gt;&lt;br /&gt;        &lt;description&gt;&lt;br /&gt;           Welcome to Tomcat&lt;br /&gt;        &lt;/description&gt;&lt;br /&gt;        &lt;servlet-mapping&gt;&lt;br /&gt;           &lt;servlet-name&gt;invoker&lt;/servlet-name&gt;&lt;br /&gt;           &lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;&lt;br /&gt;        &lt;/servlet-mapping&gt;&lt;br /&gt;        &lt;resource-ref&gt;&lt;br /&gt;           &lt;description&gt;Oracle Datasource&lt;/description&gt;&lt;br /&gt;           &lt;res-ref-name&gt;jdbc/classDS&lt;/res-ref-name&gt;&lt;br /&gt;           &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;&lt;br /&gt;           &lt;res-auth&gt;Container&lt;/res-auth&gt;&lt;br /&gt;        &lt;/resource-ref&gt;&lt;br /&gt;      &lt;/web-app&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[Startup]&lt;br /&gt;  1. Apache&lt;br /&gt;    [prompt]# /usr/local/httpd/bin/apachectl start&lt;br /&gt;  2. Tomcat&lt;br /&gt;    [prompt]# su - tomcat&lt;br /&gt;    [prompt]# /usr/locat/tomcat4/bin/catalina.sh start&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;[FAQ]&lt;br /&gt;  1. 시작페이지를 요청하면 페이지를 찾을 수 없다.&lt;br /&gt;    - configuration 파일들을 확인한다. &lt;br /&gt;      httpd.conf 의 DocumentRoot, ServerRoot, ServerName 을 확인한다.&lt;br /&gt;      server.xml에서 &lt;Host&gt;의 appBase 는 $CATALINA_HOME을 루트로 한다.&lt;br /&gt;      &lt;Host&gt;의 child element인 &lt;Context&gt;에서 docBase는 &lt;Host&gt;의 appBase를 루트로 한다.&lt;br /&gt;    - httpd 설정파일이 /etc/apache 또는 /etc/httpd 에 따로 저장되었을 수도 있다.&lt;br /&gt;      해당 설정을 모두 지우고 설치한 apache의 conf 경로를 심볼릭링크로 지정해둔다.&lt;br /&gt;      &lt;br /&gt;  2. .html은 잘 보이나, servlet을 요청하면 페이지를 찾을 수 없다.&lt;br /&gt;    - 환경변수가 올바르게 되어 있는지 확인한다. 특히 톰켓은 tomcat계정으로 실행하므로 tomcat 계정에서도 올바른 환경변수가 지정되어 있는지 확인한다.&lt;br /&gt;      [prompt]# echo $JAVA_HOME&lt;br /&gt;      [prompt]# echo $TOMCAT_HOME&lt;br /&gt;      [prompt]# echo $CATALINA_HOME&lt;br /&gt;      [prompt]# echo $CLASSPATH&lt;br /&gt;    - configuration 파일들을 확인한다. &lt;br /&gt;      server.xml에서 &lt;Host&gt;의 appBase 는 $CATALINA_HOME을 루트로 한다.&lt;br /&gt;      &lt;Host&gt;의 child element인 &lt;Context&gt;에서 docBase는 &lt;Host&gt;의 appBase를 루트로 한다.&lt;br /&gt;      WEB-INF 내의 web.xml 의 내용을 확인한다.&lt;br /&gt;      *tomcat5에서는 servlet mapping을 invoker와 같이 일괄지정할 수 없다.(보안위배된다하여 변경되었다.)&lt;br /&gt;      *http 요청 실패(error:401, error:404)는 apache 요청실패와 tomcat 요청실패가 다르다.&lt;br /&gt;       요청실패 메세지로 확인할 수 있다.&lt;br /&gt;      &lt;br /&gt;  3. DB Connecter 관련 java exception이 발생한다.&lt;br /&gt;    - 만약 NoClass Exception이라면 JDBC를 로드할 수 없는 것이다.&lt;br /&gt;      JDBC의 classes12.jar이 CLASSPATH에 맞게 지정되어있는지 확인한다.&lt;br /&gt;    - DB 연결정보가 맞지 않을 수 있다. iecom_rdb.java의 소스를 확인하여 DB 연결정보(ip, SID, port 등)를 확인한다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-8562012580286410911?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/8562012580286410911/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/how-to-install-application-server.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8562012580286410911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8562012580286410911'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/how-to-install-application-server.html' title='How to install Application Server (Tomcat 4, Apache 2, JK2 1.2) on Redhat linux 9'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-3762724737297638356</id><published>2007-08-08T16:59:00.002+09:00</published><updated>2007-08-08T17:02:30.301+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for Servers'/><title type='text'>How to install OC4J 9 on Redhat linux 9</title><content type='html'>How to Install OC4J 10g (9.0.4)&lt;br /&gt;&lt;br /&gt;준비물 : &lt;br /&gt;    OC4J Oracle homepage에서 다운로드한다.&lt;br /&gt;    JDK(v1.4 이상) 설치되어 있어야 한다.&lt;br /&gt;&lt;br /&gt;1. Download OC4J&lt;br /&gt;&lt;br /&gt;2. Copy package&lt;br /&gt;  # su - root&lt;br /&gt;  # cp /work/oc4j_extended_904 /usr/local&lt;br /&gt;  # ln -s /usr/local/oc4j_extended_904 oc4j&lt;br /&gt;  # chmod 755 -R /work/oc4j_extended_904&lt;br /&gt;&lt;br /&gt;3. Setting Environment&lt;br /&gt;  JAVA_HOME=/usr/local/java&lt;br /&gt;  ORACLE_HOME=/usr/local/oc4j  (OC4J의 HOME이다. Oracle의 home이 아니다)&lt;br /&gt;  J2EE_HOME=$ORACLE_HOME/j2ee/home&lt;br /&gt;&lt;br /&gt;4. Deploy POP source&lt;br /&gt;  # cd /usr/local/oc4j/j2ee/home&lt;br /&gt;  # cp -r /work/ROOT ./  (TOMCAT 등에서 사용된 ROOT 모두를 복사한다.)&lt;br /&gt;  # mv ROOT iepcs        (복사한 소스를 iepcs로 명명한다.)&lt;br /&gt;  # chmod -R 777 iepcs&lt;br /&gt;&lt;br /&gt;5. Configuration&lt;br /&gt;  # cd /usr/local/oc4j/j2ee/home/config&lt;br /&gt;  # vi application.xml&lt;br /&gt;&lt;orion-application autocreate-tables="true" default-data-source="jdbc/OracleDS"&gt;&lt;br /&gt;    &lt;web-module id="defaultWebApp" path="../../home/default-web-app"/&gt;&lt;br /&gt;위의 내용중&lt;br /&gt;&lt;web-module id="defaultWebApp" path="../../home/default-web-app"/&gt; 부분인 default deployee이며 이를&lt;br /&gt;&lt;web-module id="defaultWebApp" path="../../home/iepcs"/&gt; 와 같이 수정한다.&lt;br /&gt;&lt;br /&gt;  # vi http-web-site.xml&lt;br /&gt;&lt;web-site port="8888" display-name="Oracle9iAS Containers for J2EE HTTP Web Site"&gt;&lt;br /&gt;위의 port를 80으로 바꾼다.&lt;br /&gt;&lt;web-site port="80" display-name="Oracle9iAS Containers for J2EE HTTP Web Site"&gt;&lt;br /&gt;&lt;br /&gt;  # vi server.xml&lt;br /&gt;&lt;application-server application-directory="../applications" deployment-directory="../application-deployments" connector-directory="../connectors"&gt;&lt;br /&gt;위 내용 중 check-for-update property가 있다면 true로 고치고, 없으면 추가한다.&lt;br /&gt;&lt;application-server check-for-update property="true" application-directory="../applications" deployment-directory="../application-deployments" connector-directory="../connectors"&gt;&lt;br /&gt;check-for-update가 true일 때 web application의 변화가 있으면 즉시 반영된다. 그러나 성능은 저하된다.&lt;br /&gt;&lt;br /&gt;6. Review Directories&lt;br /&gt;&lt;ORACLE_HOME&gt;&lt;br /&gt;  /bin&lt;br /&gt;  /j2ee&lt;br /&gt;    + /home (WEB Application HOME)&lt;br /&gt;      + /config (설정파일)&lt;br /&gt;      + /iepcs (POP Source)&lt;br /&gt;  /javacache&lt;br /&gt;  /javavm&lt;br /&gt;  /jdbc&lt;br /&gt;  /jdk&lt;br /&gt;  /jlib&lt;br /&gt;  /lib&lt;br /&gt;  /rdbms&lt;br /&gt;  /soap&lt;br /&gt;  /sqlj&lt;br /&gt;  /toplink&lt;br /&gt;  /webservices&lt;br /&gt;&lt;br /&gt;7. Startup&lt;br /&gt;  # cd /usr/local/oc4j/j2ee/home/&lt;br /&gt;  # java -jar oc4j.jar&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-3762724737297638356?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/3762724737297638356/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/how-to-install-oc4j-9-on-redhat-linux-9.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3762724737297638356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3762724737297638356'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/how-to-install-oc4j-9-on-redhat-linux-9.html' title='How to install OC4J 9 on Redhat linux 9'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2392802247667097730</id><published>2007-08-08T16:59:00.001+09:00</published><updated>2007-08-08T17:02:30.301+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for Servers'/><title type='text'>How to install Oracle 9.2.0.4 on AIX</title><content type='html'>Creating Oracle User Accounts&lt;br /&gt;&lt;br /&gt;1 smitty user -&gt; oracle계정 생성&lt;br /&gt;  smitty fs -&gt; oracle home directory&lt;br /&gt;  smitty group -&gt;dba그룹 생성&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Creating Oracle Directorieser&lt;br /&gt;&lt;br /&gt;2. su - root&lt;br /&gt;    mkdir -p /u01/app/oracle/product/9.2.0&lt;br /&gt;   (mkdir -p /oracle/product/9.2.0)&lt;br /&gt;    chown -R oracle.oinstall /u01&lt;br /&gt;   (chown -R oracle.oinstall /oracle)&lt;br /&gt;   (chown -R oracle.oinstall /ora-data)&lt;br /&gt;                                          &lt;br /&gt;    mkdir /var/opt/oracle&lt;br /&gt;    chown oracle.dba /var/opt/oracle&lt;br /&gt;    chmod 755 /var/opt/oracle&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Setting Oracle Environments&lt;br /&gt;&lt;br /&gt;3.&lt;br /&gt;# vi /home/oracle/.profile&lt;br /&gt;export ORACLE_HOME=/home/oracle&lt;br /&gt;export ORACLE_TERM=vt100&lt;br /&gt;export ORACLE_BASE=/home/oracle&lt;br /&gt;export NLS_LANG=AMERICAN_AMERICA.KO16KSC5601&lt;br /&gt;export PATH=$PATH:$ORACLE_HOME/bin/oracle&lt;br /&gt;export PATH=$PATH:/bin:/usr/bin&lt;br /&gt;export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib&lt;br /&gt;export ORACLE_SID=ANAMDB&lt;br /&gt;export DISPLAY=127.0.0.1:0.0&lt;br /&gt;umask 022&lt;br /&gt;CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib&lt;br /&gt;CLASSPATH=$CLASSPATH:$ORACLE_HOME/network/jlib&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Uncompress and unpack downloaded files: For Oracle9i (9.2.0): &lt;br /&gt;&lt;br /&gt;4.  # cd /home/oracle&lt;br /&gt;    # zcat ship_9204_linux_disk1.cpio.gz | cpio -idmv&lt;br /&gt;    # zcat ship_9204_linux_disk2.cpio.gz | cpio -idmv&lt;br /&gt;    # zcat ship_9204_linux_disk3.cpio.gz | cpio -idmv&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Run preinstall script&lt;br /&gt;&lt;br /&gt;5.  # cd /home/oracle/Disk1 &lt;br /&gt;    # ./rootpre.sh &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Run Installer&lt;br /&gt;1. # su - oracle &lt;br /&gt;   $ cd /DISK1 &lt;br /&gt;   $ runInstaller : ./runInstaller &lt;br /&gt;&lt;br /&gt;13. sys/sysadmin&lt;br /&gt;14. system/sysadmin&lt;br /&gt;&lt;br /&gt;15. #sqlplus /nolog&lt;br /&gt;    sql&gt;connect sys/sysadmin as sysdba&lt;br /&gt;    sql&gt;quit&lt;br /&gt;    #lsnrctl&lt;br /&gt;    lsnrctl&gt;start&lt;br /&gt;    lsnrctl&gt;quit&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2392802247667097730?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2392802247667097730/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/how-to-install-oracle-9204-on-aix.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2392802247667097730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2392802247667097730'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/how-to-install-oracle-9204-on-aix.html' title='How to install Oracle 9.2.0.4 on AIX'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-1009537116887936660</id><published>2007-08-08T16:58:00.001+09:00</published><updated>2007-08-08T17:02:30.302+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for Servers'/><title type='text'>How to install Oracle 9.2.0.4 on Redhat linux 9</title><content type='html'>Setting Shared Memory&lt;br /&gt;&lt;br /&gt;(root 계정으로 진행)&lt;br /&gt;1. # cat /proc/sys/kernel/shmmax&lt;br /&gt;    2147483648&lt;br /&gt;    # echo 2147483648 &gt; /proc/sys/kernel/shmmax&lt;br /&gt;    # sysctl -w kernel.shmmax=2147483648&lt;br /&gt;    # echo "kernel.shmmax=2147483648" &gt;&gt; /etc/sysctl.conf&lt;br /&gt;2. # cat /proc/sys/kernel/shmmni&lt;br /&gt;    4096&lt;br /&gt;    # echo 4096 &gt; /proc/sys/kernel/shmmni&lt;br /&gt;    # sysctl -w kernel.shmmni=4096&lt;br /&gt;    # echo "kernel.shmmni=4096" &gt;&gt; /etc/sysctl.conf&lt;br /&gt;3  $ getconf PAGE_SIZE&lt;br /&gt;    4096&lt;br /&gt;    # cat /proc/sys/kernel/shmall&lt;br /&gt;    2097152&lt;br /&gt;    # echo 2097152 &gt; /proc/sys/kernel/shmall&lt;br /&gt;    # sysctl -w kernel.shmall=2097152&lt;br /&gt;    # echo "kernel.shmall=2097152" &gt;&gt; /etc/sysctl.conf&lt;br /&gt;&lt;br /&gt;Creating Oracle User Accounts&lt;br /&gt;&lt;br /&gt;4. su - root&lt;br /&gt;    groupadd dba          # group of users to be granted with SYSDBA system privilege&lt;br /&gt;    groupadd oinstall     # group owner of Oracle files&lt;br /&gt;    useradd -c "Oracle software owner" -g oinstall -G dba oracle&lt;br /&gt;    passwd oracle&lt;br /&gt;&lt;br /&gt;Creating Oracle Directorieser&lt;br /&gt;&lt;br /&gt;5. su - root&lt;br /&gt;    mkdir -p /u01/app/oracle/product/9.2.0&lt;br /&gt;   (mkdir -p /oracle/product/9.2.0)&lt;br /&gt;    chown -R oracle.oinstall /u01&lt;br /&gt;   (chown -R oracle.oinstall /oracle)&lt;br /&gt;   (chown -R oracle.oinstall /ora-data)&lt;br /&gt;                                          &lt;br /&gt;    mkdir /var/opt/oracle&lt;br /&gt;    chown oracle.dba /var/opt/oracle&lt;br /&gt;    chmod 755 /var/opt/oracle&lt;br /&gt;&lt;br /&gt;Setting Oracle Environments&lt;br /&gt;&lt;br /&gt;6.&lt;br /&gt;(oracle 계정으로 진행 # su - oracle)&lt;br /&gt;# Set the LD_ASSUME_KERNEL environment variable only for Red Hat 9, &lt;br /&gt;# RHEL AS 3, and RHEL AS 4 !!&lt;br /&gt;# Use the "Linuxthreads with floating stacks" implementation instead of NPTL:&lt;br /&gt;export LD_ASSUME_KERNEL=2.4.1    # for RH 9 and RHEL AS 3&lt;br /&gt;export LD_ASSUME_KERNEL=2.4.19   # for RHEL AS 4&lt;br /&gt;&lt;br /&gt;# Oracle Environment&lt;br /&gt;export ORACLE_BASE=/u01/app/oracle&lt;br /&gt;export ORACLE_HOME=$ORACLE_BASE/product/9.2.0&lt;br /&gt;export ORACLE_SID=test&lt;br /&gt;export ORACLE_TERM=xterm&lt;br /&gt;# export TNS_ADMIN= Set if sqlnet.ora, tnsnames.ora, etc. are not in $ORACLE_HOME/network/admin&lt;br /&gt;export NLS_LANG=AMERICAN;&lt;br /&gt;export ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data&lt;br /&gt;LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib&lt;br /&gt;LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib&lt;br /&gt;export LD_LIBRARY_PATH&lt;br /&gt;export DISPLAY=127.0.0.1:0.0&lt;br /&gt;&lt;br /&gt;# Set shell search paths&lt;br /&gt;export PATH=$PATH:$ORACLE_HOME/bin&lt;br /&gt;&lt;br /&gt;JDK&lt;br /&gt;According to the JDK documentation, install JDK under /usr/local. Then create a symbolic link to the JDK under /usr/local/java: &lt;br /&gt;7. su - root&lt;br /&gt;    bzip2 -dc jdk118_v3-glibc-2.1.3.tar.bz2 | tar xf - -C  /usr/local&lt;br /&gt;    ln -s /usr/local/jdk118_v3 /usr/local/java&lt;br /&gt;&lt;br /&gt;8. radhat 9에 /usr/bin/gcc296을 gcc로 링크한다.&lt;br /&gt;    # su - root&lt;br /&gt;    # mv /usr/bin/gcc /usr/bin/gcc323&lt;br /&gt;    # ln -s /usr/bin/gcc296 /usr/bin/gcc&lt;br /&gt;    # mv /usr/bin/g++ /usr/bin/g++323      # if g++ doesn't exist, then gcc-c++ was not installed&lt;br /&gt;    # ln -s /usr/bin/g++296 /usr/bin/g++&lt;br /&gt;&lt;br /&gt;Uncompress and unpack downloaded files: For Oracle9i (9.2.0): &lt;br /&gt;&lt;br /&gt;8.  # cd /work&lt;br /&gt;    # zcat ship_9204_linux_disk1.cpio.gz | cpio -idmv&lt;br /&gt;9.  # zcat ship_9204_linux_disk2.cpio.gz | cpio -idmv&lt;br /&gt;10. # zcat ship_9204_linux_disk3.cpio.gz | cpio -idmv&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;11. # startx &lt;- x윈도우 실행하고&lt;br /&gt;    # cd /oracle/Disk1&lt;br /&gt;    # ./runoraInstaller&lt;br /&gt;  11.1 오라클 인스톨러 실행중 한글이 깨져서 보일때&lt;br /&gt;    11.1.1 Disk1/stage/Components/oracle.swd.jre/1.3.1.0.0/1/DataFiles/Expanded/jre/linux/lib/fonts&lt;br /&gt;           위의 경로에 batang.ttc gulim.ttc mingliu.ttc (windows font) 세 파일을 복사해넣는다.&lt;br /&gt;    11.1.2 Disk1/stage/Components/oracle.swd.jre/1.3.1.0.0/1/DataFiles/Expanded/jre/linux/lib/fonts/fonts.dir&lt;br /&gt;           의 내용을 edit하여 다음 3라인을 추가한다. &lt;br /&gt;           batang.ttc -ms-batang-medium-r-normal--0-0-0-0-c-0-ksc5601.1987-0 &lt;br /&gt;           gulim.ttc -ms-gulim-medium-r-normal--0-0-0-0-c-0-ksc5601.1987-0 &lt;br /&gt;           mingliu.ttc -ms-mingliu-medium-r-normal--0-0-0-0-c-0-ksc5601.1987-0&lt;br /&gt;    11.1.3 Disk1/stage/Components/oracle.swd.jre/1.3.1.0.0/1/DataFiles/Expanded/jre/linux/lib&lt;br /&gt;           위의 경로에 font.properties.ko 파일을 추가한다&lt;br /&gt;&lt;br /&gt;12. 오라클 인스톨러 실행중에 &lt;br /&gt;    '/tmp/orainstRoot.sh'를 root 계정으로 실행하고 continue하란다.. 시키는데로 하자&lt;br /&gt;  12.1 인스톨 중, 끝부분에서 Linking 을 할때(84%) 쯤에, Error in invoking target install of makefile /Oracle/product/9.2.0/ctx/lib/ins_ctx.mk 에러메세지가 발생한다면&lt;br /&gt;    12.1.1 $vi $ORACLE_HOME/ctx/lib/env_ctx.mk 를 에디트&lt;br /&gt;           "INSO_LINK =" 이 부분에  "$(LDLIBFLAG)dl" 추가&lt;br /&gt;           예)&lt;br /&gt;            INSO_LINK = &lt;br /&gt;            -L$(CTXLIB) $(LDLIBFLAG)m $(LDLIBFLAG)dl $(LDLIBFLAG)sc_ca $(LDLIBFLAG)sc_fa &lt;br /&gt;            $(LDLIBFLAG)sc_ex $(LDLIBFLAG)sc_da $(LDLIBFLAG)sc_ut $(LDLIBFLAG)sc_ch $(LDLIBFLAG)sc_fi &lt;br /&gt;            $(LLIBCTXHX) $(LDLIBFLAG)c -Wl,-rpath,$(CTXHOME)lib $(CORELIBS) $(COMPEOBJS)&lt;br /&gt;&lt;br /&gt;13. sys/sysadmin&lt;br /&gt;14. system/sysadmin&lt;br /&gt;&lt;br /&gt;15. #sqlplus /nolog&lt;br /&gt;    sql&gt;connect sys/sysadmin as sysdba&lt;br /&gt;    sql&gt;quit&lt;br /&gt;    #lsnrctl&lt;br /&gt;    lsnrctl&gt;start&lt;br /&gt;    lsnrctl&gt;quit&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-1009537116887936660?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/1009537116887936660/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/how-to-install-oracle-9204-on-redhat_08.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1009537116887936660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1009537116887936660'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/how-to-install-oracle-9204-on-redhat_08.html' title='How to install Oracle 9.2.0.4 on Redhat linux 9'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-283268673256356538</id><published>2007-08-08T15:40:00.000+09:00</published><updated>2007-08-08T16:55:35.067+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for DBMS'/><title type='text'>Auto backup - Oracle cold backup on linux</title><content type='html'>&lt;blockquote&gt;[auto_db_backup.sh]-------------------------------------------------------------&lt;br /&gt;#! /bin/bash&lt;br /&gt;WEEKAGO=`date -d "-7 days" +%Y%m%d`&lt;br /&gt;NOW=`date +%Y%m%d`&lt;br /&gt;/oracle/product/9.2.0/bin/sqlplus /nolog &lt;&lt;EOF&lt;br /&gt;connect / as sysdba&lt;br /&gt;shutdown&lt;br /&gt;exit&lt;br /&gt;EOF&lt;br /&gt;tar -cvf /work/db_backup/oradata_$NOW.tar /oradata&lt;br /&gt;tar -cvf /work/app_backup/iepcs_tw_$NOW.tar /usr/local/tomcat4/webapps/ROOT&lt;br /&gt;rm -f /work/db_backup/*_$WEEKAGO.tar&lt;br /&gt;rm -f /work/app_backup/*_$WEEKAGO.tar&lt;br /&gt;/oracle/product/9.2.0/bin/sqlplus /nolog  &lt;&lt;EOF&lt;br /&gt;connect / as sysdba&lt;br /&gt;startup&lt;br /&gt;exit&lt;br /&gt;EOF&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;[auto_ftp_send_data.sh]-------------------------------------------------------------&lt;br /&gt;#! /bin/bash&lt;br /&gt;NOW=`date +%Y%m%d`&lt;br /&gt;ftp -vn &lt;&lt;EOF&lt;br /&gt;open 165.244.124.134&lt;br /&gt;user pop "popadmin"&lt;br /&gt;prompt&lt;br /&gt;put /work/db_backup/oradata_$NOW.tar /oradata_$NOW.tar&lt;br /&gt;bye&lt;br /&gt;EOF&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;[auto_ftp_send_apps.sh]-------------------------------------------------------------&lt;br /&gt;#! /bin/bash&lt;br /&gt;NOW=`date +%Y%m%d`&lt;br /&gt;ftp -vn &lt;&lt;EOF&lt;br /&gt;open 165.244.124.134&lt;br /&gt;user pop "popadmin"&lt;br /&gt;prompt&lt;br /&gt;put /usr/local/httpd/conf/httpd.conf /$NOW_httpd.conf&lt;br /&gt;put /usr/local/httpd/workers.properties /$NOW_workers.properties&lt;br /&gt;put /usr/local/tomcat4/conf/server.xml /$NOW_server.xml&lt;br /&gt;put /usr/local/tomcat4/webapps/ROOT/WEB-INF/web.xml /$NOW_web.xml&lt;br /&gt;put /home/oracle/.bash_profile /$NOW_oracle_bash_profile&lt;br /&gt;put /work/app_backup/iepcs_tw_$NOW.tar /$NOW_iepcs_tw.tar&lt;br /&gt;bye&lt;br /&gt;EOF&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;[crontab]-----------------------------------------------------------------------&lt;br /&gt;0 23 * * * /home/oracle/auto_db_backup.sh&lt;br /&gt;10 23 * * 0 /home/oracle/auto_ftp_send_data.sh&lt;br /&gt;50 23 * * * /home/oracle/auto_ftp_send_apps.sh&lt;br /&gt;분 시 일 월 요일 명령&lt;br /&gt;--------------------------------------------------------------------------------&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-283268673256356538?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/283268673256356538/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/auto-backup.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/283268673256356538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/283268673256356538'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/auto-backup.html' title='Auto backup - Oracle cold backup on linux'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-7938709608089655371</id><published>2007-08-08T14:42:00.000+09:00</published><updated>2007-08-08T14:53:32.241+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>어느덧 8월</title><content type='html'>어젠 고심고심한 끝에 책을 두권 구입했다.&lt;br /&gt;&lt;span id="LB_CENTER_IMG"&gt;&lt;img style="CURSOR: hand" onclick="javascript:window.close(); return false;" src="http://image.yes24.com/momo/TopCate50/MidCate02/4918602.jpg" /&gt;&lt;span id="LB_CENTER_IMG"&gt;&lt;img style="CURSOR: hand" onclick="javascript:window.close(); return false;" src="http://image.yes24.com/momo/TopCate56/MidCate06/5559032.jpg" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;이것들 말고도 Spring 책 한권 더 있는데 포인트 좀 쌓고 사려고 며칠 미뤘다.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;통장 잔고와 결재될 카드값을 보면 자꾸 책 사는 것이 꺼려지게 된다.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;그럼 꽤 우울해진다.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;아내에게도 이 우울함을 전달해 주기는 싫고...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;알고 싶은 것이 있으면 구글신에게 물어보는 것으로 때우곤 했는데&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;어제는 코딩하다가 막혀버려서 스스로에게 화가 났었다.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;그러고보면 어젠 참 우울한 날이었다.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;아침에 늦게 일어나 머리도 엉망이고, 벨트가 어디 있는지 보이질 않아서 바지는 흘러내리고, 간만에 노트북을 정리하려고 들고 출근했는데 고장나고, 퇴근하고 났더니 처남은 본 체도 안하고, 아내가 퇴근해서 첫마디가 왜 화냤나고 쏘고..&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;아내가 내 우울한 얼굴을 바꿔보려고 술한잔하자고 했는데 술집이 비싸서 갈 생각이 들었다 접고, 친구라고 하나 있는게 학원에 있다고 해서&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;결국 마트에서 까뮤 V.S.O.P 하나 샀다.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;img src="http://www.kaja21.co.kr/bbs/table/winegoods/upload/camus.jpg" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;오늘은 좀 낫군. 이런저런 생각을 정리 중이다.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;개인프로젝트 &lt;a href="http://sam-jv.blogspot.com/2007/04/concept-note.html"&gt;MyRoom&lt;/a&gt;의 컨셉을 바꿔서 다시 하려고 한다.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;오늘도 차근차근.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-7938709608089655371?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/7938709608089655371/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/8.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7938709608089655371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7938709608089655371'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/8.html' title='어느덧 8월'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-1603912020912360877</id><published>2007-08-08T14:37:00.000+09:00</published><updated>2007-08-08T14:40:14.738+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Project::My Room'/><title type='text'>링크들</title><content type='html'>Online whiteboard &lt;a href="http://vyew.com/"&gt;Vyew.com - FREE Anytime Collaboration and Live Conferencing™&lt;/a&gt;- &lt;br /&gt;&lt;a href="http://tunelinux.pe.kr/tune/tunning-pse/tunning.html"&gt;리눅스 시스템 모니터링 시스템 최적화&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ihelpers.co.kr/programming/tipntech.php?CMD=view&amp;TYPE=6&amp;amp;KEY=&amp;SC=S&amp;amp;&amp;CC=&amp;amp;PAGE=1&amp;IDX=408"&gt;Oracle LOCK 문제를 일으키는 SQL 명령 찾기&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.brl.pe.kr/"&gt;B.R.Lee's Homepage (FA,PLC관련자료)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://openframework.or.kr/JSPWiki/Wiki.jsp"&gt;Open web framework Wiki&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.puschitz.com/InstallingOracle9i.shtml"&gt;Oracle Installation on Redhat Linux &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://tdd.or.kr/pf/book/render_page?pagename=JumpToPython&amp;keyword=&amp;amp;filename=&amp;curpage=&amp;amp;historyname=&amp;content=&amp;amp;newname="&gt;파이썬 강좌&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ibm.com/developerworks/kr/series/web/index.html"&gt;IBM Ajax 마스터하기&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://php.chol.com/~vision82/tt/38"&gt;[HowTo] Apache 2 + Tomcat 5 + mod_jk 통합 설치 설명서&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;a href="http://okjsp.pe.kr/lecture/index.xml"&gt;Java WAS 팁 모음(tomcat, resin, apache 등등)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://wiki.javajigi.net/display/WEB20/19-Week+Free+AJAX+Programming+Online+Course"&gt;19-Week Free AJAX Programming Online Course &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://wiki.blender.org/index.php/Manual.kr/Manual"&gt;블렌더 한글 튜토리얼(Blender Tutorial Korean)&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-1603912020912360877?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/1603912020912360877/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/blog-post_08.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1603912020912360877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1603912020912360877'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/blog-post_08.html' title='링크들'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-3786724622572889146</id><published>2007-08-08T14:24:00.000+09:00</published><updated>2007-08-08T14:33:50.300+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='머리속 그림들'/><title type='text'>우린 돈 때문에 일한 게 아니다. 세상을 바꾸기 위해 일했다. -호킨스 @ 애플</title><content type='html'>우린 돈 때문에 일한 게 아니다. 세상을 바꾸기 위해 일했다. -호킨스 @ 애플&lt;br /&gt;&lt;a href="http://www.oksjp.co.kr/"&gt;okjsp&lt;/a&gt; 에서 본 말이다.&lt;br /&gt;&lt;br /&gt;요샌 왠지 맘속에 항상 불안감이 있다.&lt;br /&gt;미래에 대한 불안감이다.&lt;br /&gt;개발자(대개의 엔지니어들도)에 대한 경시풍조도 그렇고, 박봉도 그렇고, 내 기술의 활용이 잘 되지 않는 것도 그렇고, 하루하루 불안함이 마음 바닦 어딘가에 있다.&lt;br /&gt;이것저것 아이디어가 생각나지만 구체적으로 구현하지는 못하고 있다.&lt;br /&gt;자꾸 다른 것들과 연결시키고 혼자서 실망하곤 한다.&lt;br /&gt;이 블로그도 그렇다.&lt;br /&gt;글을 쓴다는 것이 꼭 다른사람에게 보이기 위함이 조금이라도 들어가야 하는 것인지.&lt;br /&gt;내 마음이 깨끗하게 원하는대로 그리고 행동도 원하는대로 하질 못하고 있는 거다.&lt;br /&gt;&lt;br /&gt;내가 하고 싶은 건 개발이다. 프로그램 개발.&lt;br /&gt;지금 하고 있는 일이 개발인지 자꾸 햇갈린다.&lt;br /&gt;그리고 그냥 개발이 아닌 사람들을 평등하게 만들 수 있는 그런 개발을 원한다.&lt;br /&gt;당연히 사람은 원래 평등하지 않지만 힘의 평형을 만들고 싶다.&lt;br /&gt;힘없는 사람도 힘있는 사람과 평등해 질 수 있는 그런 것들을 만들고 싶다.&lt;br /&gt;물론 재미있어야 하고.&lt;br /&gt;&lt;br /&gt;제일 위에 있는 말을 보고 머릿속이 멈칫 했다.&lt;br /&gt;세상을 바꾸기 위해 일한다라.....&lt;br /&gt;나도 물론 밥그릇 걱정을 하고 있다. 박봉에 마음아픈건 여전하니까.&lt;br /&gt;하지만 정말 원하는 것은 그게 아닌가. 세상이 좀 더 행복해지게 하는 것.&lt;br /&gt;방법을 하나씩 실천하자.&lt;br /&gt;그리고 계속 리팩토링하고 유지보수하면 열매가 보이지 않을까?&lt;br /&gt;&lt;br /&gt;지금은 2007년 8월 8일 오후 2시 23분.&lt;br /&gt;&lt;br /&gt;또 시작하자.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-3786724622572889146?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/3786724622572889146/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/08/blog-post.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3786724622572889146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3786724622572889146'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/08/blog-post.html' title='우린 돈 때문에 일한 게 아니다. 세상을 바꾸기 위해 일했다. -호킨스 @ 애플'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-199614700466697352</id><published>2007-04-17T11:48:00.000+09:00</published><updated>2007-04-17T14:25:23.298+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='좋은 책 이야기'/><title type='text'>초의  : 차, 사상, 예술을 선으로 승화시킨 풀옷의 선승</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Fvbj4JTJPhI/RiQ2zLepmHI/AAAAAAAAACA/nRtIB_K5AkQ/s1600-h/803075.jpg"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_Fvbj4JTJPhI/RiQ2zLepmHI/AAAAAAAAACA/nRtIB_K5AkQ/s400/803075.jpg" alt="" id="BLOGGER_PHOTO_ID_5054224934699112562" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;조선 후기 초의라는 선사에 대한 소설이다. 작가는 할 수 있는 한 고증을 모아서 집필했다고 한다. 이 책을 읽은 건 한 2,3년 전이었던 것 같은데, 아직까지도 은은한 향기를 내고 있는 책이다. 일단 yes24에서 검색한 초의선사의 내용을 보면 &lt;blockquote&gt;&lt;br /&gt;초의 선사(1786-1866)는 조선 후기의 대선사이자 다도를 정립한 사람이다.&lt;br /&gt;성은 장씨(張氏)이며, 자는 중부(中孚), 법명은 의순(意恂)으로, 초의는 호이다.&lt;br /&gt;16세에 출가하여 불학 이외에도 유학, 도교 등 여러 교학에 통달하였고, 범서(梵書)에도 능통하였다.&lt;br /&gt;다산 정약용, 추사 김정희, 소치 허련, 자하 신위 등과 폭 넓게 교류를 가져 시부(詩賦)를 익히기도 하고, 〈동다송(東茶頌)〉과 &lt;다신전(茶神傳)&gt;을 지어 차 생활의 멋을 설명하기도 하였다. 불교 사상 또한 다선일미사상(茶禪一味思想)으로, 차를 통하여 법희선열(法喜禪悅)을 맛본다고 하였으며, 좌선을 통해서 뿐만이 아니라 평범한 일상 생활 속에서 멋을 찾고 불법을 구하고자 노력하였다. 명성이 널리 알려지자 대둔사의 동쪽 계곡에 일지암을 짓고 40여 년을 홀로 정진하다 1866년 나이 80세, 법랍 65세로 입적하였다.&lt;/blockquote&gt;&lt;br /&gt;이렇다. 책도 냈고, 김정희와 정약용의 친구이며 평생동안 좋은 친구로 지낸 분이다. 조선후기라면 신분이동도 가능했고 여러 사회적 이유가 많았던 사회이다. 또 정약용이라면 조선후기 최고의 이슈메이커 아닌가. 초의는 이런 시대에 민초들의 생활에 깊이 관여하여 사람들이 좀 더 행복하게 살게 하기 위해 고민하고 행동한다. 시, 노래, 그림 등(법가에도 판소리 비슷한 노래나 춤이 있다고 한다) 예술에 출중한 엘리트인 초의가 깨닭음을 얻어 민초들에게 옳바른 삶, 행복한 생활로 이끌었다는 내용이다. 게다가 중요한 것은 사회에 큰 영향력을 끼치던 인물들(고위관리던 정약용 같은 친구이던)을 직접 찾아가 민생을 위한 것이 어떤 것이라는 것을 의논했다는 거다. 초의라는 법명은 그의 생전의 업적을 그린 것이다.&lt;br /&gt;차에 대하여서는 그는 최고의 전문가였다. 남은 문헌이 차에 대한 것이 많아서 그런지 대게 차와 초의에 대한 이야기가 큰 줄기처럼 보인다. 그러나 책에서 전해지는 내용의 핵심은 차 하나만이 아니다. 차와 같이 은은하게 풍기는 향기처럼, 또 한가지 향기만을 풍기는 것이 아닌 여러 향이 조화로운 차향같은 그의 인생을 보여주는 것이다.&lt;br /&gt;그 시대, 조선후기나 현시대나 많은 사람들이 성공을 위해 달린다. 자신이나 주변을 희생하면서 성공을 원한다. 어느 시대나 마찬가지가 아닐까 싶다. 다만 변혁이 많은 시기에는 힘없는 민초들에게는 그리 좋은 시절이 아니라는 것이다. 초의는 그러한 시대를 힘있게 살며 힘없는 사람을 위해 살았다. 지금도 초의같은 분이 아직 세상에 있다. 그래서 세상이 모두 망가지지 않고 아름답게 그려지는 것이 아닐까 한다.&lt;br /&gt;향기는 시간이 지나면 사라지지만 또 다른 어느곳에서 또 다른 향기가 불어올 것이다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-199614700466697352?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/199614700466697352/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/blog-post_17.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/199614700466697352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/199614700466697352'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/blog-post_17.html' title='초의  : 차, 사상, 예술을 선으로 승화시킨 풀옷의 선승'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Fvbj4JTJPhI/RiQ2zLepmHI/AAAAAAAAACA/nRtIB_K5AkQ/s72-c/803075.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-7932645247995926596</id><published>2007-04-17T11:37:00.000+09:00</published><updated>2007-04-17T11:42:46.487+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for Win32'/><title type='text'>WinCE 4.x 설치 패키지(.exe) 만들기</title><content type='html'>이 이야기는 WinCE 4.x에서 동작할 App 제작시 배포를 위한 이야기입니다.&lt;br /&gt;&lt;br /&gt;준비물&lt;br /&gt;Cabwiz.exe (PocketPC Builder인가 거기에 포함되어 있음. eVC엔 없었다는.. =_=)&lt;br /&gt;Cabwiz.ddf&lt;br /&gt;Makecab.exe (Windows 어딘가에 포함되어 있었는지 이미 갖고 있었음. Cabwiz에 필요한 파일)&lt;br /&gt;ezsetup.exe (오픈소스. 구글에서 ezsetup만 치면.. -_-)&lt;br /&gt;&lt;br /&gt;Cabwiz.exe와 cabwiz.ddf, Makecab.exe는 같은 경로에 있어야 한다. 쉽게 하려면 네 파일을 모두 설치 패키지 만들 파일이 있는 경로에 같이 두고 진행하는게 좋다.&lt;br /&gt;(.ini든 .inf든 뭔든 한자리에~~ -_-v)&lt;br /&gt;&lt;br /&gt;예제를 보면서 따라하기.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;example.inf&lt;br /&gt;;------------------------------------------------------------------------------------------------------------&lt;br /&gt;[Version]&lt;br /&gt;Signature = "$Windows NT$"     ; 그대로&lt;br /&gt;Provider = "Me"         ; 소스 배포하는 사람이나 회사&lt;br /&gt;CESignature = "$Windows CE$"     ; 그대로&lt;br /&gt;&lt;br /&gt;[CEStrings]&lt;br /&gt;AppName="ExProgram"        ; 프로그램 이름(이나 브렌드 등등)&lt;br /&gt;InstallDir="\PocketStore\Sample"    ; 설치될 위치&lt;br /&gt;Desktop="\Windows\바탕 화면"    ; 단축아이콘을 넣기 위해&lt;br /&gt;&lt;br /&gt;[Strings]&lt;br /&gt;Company_name = "Comppp"        ; 회사이름이라는데 별 영향없는 듯.(틀림없이 변수이고 필요 없을 것임)&lt;br /&gt;reg_path = "\PocketStore\Sample"    ; Registry 경로&lt;br /&gt;&lt;br /&gt;[CEDevice]            ; 여기 부분을 잘 활용하면 각 CPU에 맞는 버전을 패키징 할 수 있음(현재는 패스. 단일 플랫폼)&lt;br /&gt;UnsupportedPlatforms = Pltfrm1   &lt;br /&gt;VersionMin = 2.0&lt;br /&gt;VersionMax = 5.0&lt;br /&gt;&lt;br /&gt;[DefaultInstall]        ; 설치될 파일들의 목록을 지정하는 부분&lt;br /&gt;CopyFiles = Files.Common    ; 기본적으로 파일 리스트&lt;br /&gt;AddReg = RegSettings        ; 설치할 때 추가할 레지스트리의 리스트 이름&lt;br /&gt;CEShortcuts = Startmenu, Desktop    ; 말 그대로 단축아이콘. 여기서는 변수 이름만 지정하고 [DestinationDirs] 부분에 실제 경로를 기술할 것임&lt;br /&gt;&lt;br /&gt;[Files.Common]            ; 설치될 파일 리스트. [DestinationDirs] 부분에 실제 경로를 기술할 것임&lt;br /&gt;DataMgrCore.dll,,,0&lt;br /&gt;LOGO.BMP,,,0&lt;br /&gt;THANK.bmp,,,0&lt;br /&gt;Sample.exe,,,0&lt;br /&gt;&lt;br /&gt;[CEShortcuts]            ; 단축아이콘 부분&lt;br /&gt;CEShortcuts = Startmenu, Desktop&lt;br /&gt;[Startmenu]            ; 위에선 변수 선언, 여기에서 세부내용 기술함.&lt;br /&gt;SampleProgram,0,Sample.exe        ; Taskbar의 시작프로그램 부분과 바탕화면에 단축아이콘을 넣을 것임&lt;br /&gt;[Desktop]&lt;br /&gt;SampleProgram,0,Sample.exe&lt;br /&gt;&lt;br /&gt;[RegSettings]            ; HKLM은 레지스트리의 LocalMachine.&lt;br /&gt;HKLM,%reg_path%,Port,0x00000000,80    ; %reg_path% 하위로 %reg_path%\path2 와 같이 경로를 더 둘 수 있음&lt;br /&gt;HKLM,%reg_path%,Server,0x00000000,123.456.789.001&lt;br /&gt;HKLM,%reg_path%,Option1,0x00000000,1&lt;br /&gt;HKLM,%reg_path%,Option2,0x00000000,1&lt;br /&gt;HKLM,%reg_path%,Option3,0x00000000,1&lt;br /&gt;HKLM,%reg_path%,Option4,0x00000000,1&lt;br /&gt;HKLM,%reg_path%,Option5,0x00000000,1&lt;br /&gt;&lt;br /&gt;[SourceDisksNames]&lt;br /&gt;1 = ,"Common files",,D:\Installation    ; cab으로 패키징될 Disk 이름&lt;br /&gt;&lt;br /&gt;[SourceDisksFiles]            ; 위의 [Files.Common]의 내용과 같게 해 주면 간단함.&lt;br /&gt;DataMgrCore.dll = 1&lt;br /&gt;LOGO.BMP = 1&lt;br /&gt;THANK.bmp = 1&lt;br /&gt;Sample.exe = 1&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[DestinationDirs]            ; 설치될 경로&lt;br /&gt;Files.Common = 0,%InstallDir%        ; 위에서 설정한 경로&lt;br /&gt;Startmenu = 0,%CE11%            ; 시작프로그램\프로그램&lt;br /&gt;Desktop = 0,%CE3%            ; \Windows\바탕화면&lt;br /&gt;&lt;br /&gt;;------------------------------------------------------------------------------------------------------------&lt;/blockquote&gt;&lt;br /&gt;위와같이 해 주면 되겠다. *.inf는 실제로 cabwiz.exe가 .cab으로 패키징할 내용을 담고 있다. 심사숙고해서 만들길 바란다.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;cabwiz.ddf&lt;br /&gt;;------------------------------------------------------------------------------------------------------------&lt;br /&gt;;&lt;br /&gt;; cabwiz.ddf&lt;br /&gt;;&lt;br /&gt;; Template directive file to create the CAB file&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;.Set Cabinet=ON&lt;br /&gt;.Set Compress=OFF&lt;br /&gt;.Set CabinetFileCountThreshold=0    ; no files per cabinet threshold&lt;br /&gt;.Set FolderFileCountThreshold=0     ; no files per folder threshold&lt;br /&gt;.Set FolderSizeThreshold=0          ; no folder size threshold&lt;br /&gt;.Set MaxCabinetSize=0               ; no max size for the cabinet&lt;br /&gt;.Set MaxDiskFileCount=0&lt;br /&gt;.Set MaxDiskSize=0&lt;br /&gt;.Set ReservePerCabinetSize=0        ; for web signing&lt;br /&gt;.Set ReservePerDataBlockSize=0&lt;br /&gt;.Set ReservePerFolderSize=0&lt;br /&gt;.Set UniqueFiles=OFF&lt;br /&gt;&lt;br /&gt;.Set DiskDirectory1=.&lt;br /&gt;.Set DiskLabel1=Setup&lt;br /&gt;&lt;br /&gt;;&lt;br /&gt;; to be filled out by the CABWIZ.exe program&lt;br /&gt;;.Set InfFileName=&lt;br /&gt;;.Set RptFileName=&lt;br /&gt;;.Set CabinetName1=&lt;br /&gt;;&lt;br /&gt;; followed by the list of files&lt;br /&gt;;------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;/blockquote&gt;이건 이대로 바꿀 것 없이 그대로 쓰면 된다. 세부적인 내용은 구글신이 알려줄거다.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;setup.ini&lt;br /&gt;;------------------------------------------------------------------------------------------------------------&lt;br /&gt;[CEAppManager]&lt;br /&gt;Version      = 1.0&lt;br /&gt;Component    = Sample_program    ; 요게 [Sample_program] 요리에서 설명한다.&lt;br /&gt;&lt;br /&gt;[Sample_program]&lt;br /&gt;Description  = 주절주절     ; 그냥 이런저런 설명&lt;br /&gt;Uninstall    = Sample Program    ; 프로그램 추가/제거에 나타나는 이름&lt;br /&gt;CabFiles     = sample.cab&lt;br /&gt;;------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;/blockquote&gt;*.ini는 ezsetup.exe가 cab을 exe로 만들어줄 내용을 담고 있다. 그리고 프로그램추가/제거의 목록에도 나타나게 된다.&lt;br /&gt;&lt;br /&gt;.cab 만들기&lt;br /&gt;&gt;&gt; cabwiz sample.inf /err error.txt&lt;br /&gt;이렇게 하면 sample.cab이 만들어진다. 에러나면 error.txt를 보도록&lt;br /&gt;사실 이 .cab만 WinCE PDA에 복사해서 실행하면 설치한다. 그래도 좀 더 폼나는 설치 패키지(PC에서 실행하는)를 만드려면 ezsetup.exe를 사용한다.&lt;br /&gt;&lt;br /&gt;.exe 만들기 (설치용 패키지!!)&lt;br /&gt;&gt;&gt; ezsetup -l english -i setup.ini -r ReadMe.txt -e eula.txt -o Setup_Sample.exe&lt;br /&gt;ReadMe.txt는 설치 시작할 때 나오는 글이고, eula.txt는 사용자 약관(동의하나 하는)에 대한 내용이다.&lt;br /&gt;&lt;br /&gt;모두 정상작동한다면 Setup_Sample.exe가 멋지게 나올 것이다.&lt;br /&gt;(실제 이 방법으로 한국의 대기업 K사에서 업무용 PDA 프로그램이 배포된다. -_-v)&lt;br /&gt;혹시라도 위의 방법에 대해서 질문이 있는 분은 서슴없이 제게 메일을 주시길. ( icksishu At gmail Dot com )&lt;br /&gt;&lt;br /&gt;P.S 사실 위의 내용은 본인이 잊지 않기 위해서 적어둔 것임. -_-;;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-7932645247995926596?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/7932645247995926596/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/wince-4x-exe.html#comment-form' title='1개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7932645247995926596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7932645247995926596'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/wince-4x-exe.html' title='WinCE 4.x 설치 패키지(.exe) 만들기'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2745870429268384300</id><published>2007-04-17T09:25:00.000+09:00</published><updated>2007-04-17T11:47:26.623+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><category scheme='http://www.blogger.com/atom/ns#' term='좋은 책 이야기'/><title type='text'>Joel on Software</title><content type='html'>지난주에 갑자기 인터넷 서점에서 책을 질렀다.&lt;br /&gt;그 중에 꼭 보고 싶었던 조엘 온 소프트웨어를 한참 보고 있다. 볼 시간이라곤 출근, 화장실 정도지만 벌써 2/3정도는 읽었다.&lt;br /&gt;소문대로 재미있는 내용이 많다. 주로 소프트웨어 관리에 집중되어 있는데 원본이 개인 블로그이다 보니 이야기를 정말 스스로 원하는 대로 풀어나간다.(양키 센스나 유머는 아직 100% 이해하기 어렵지만 말이다.)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://images.amazon.com/images/P/1590593898.01._SCLZZZZZZZ_.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;특히 인상에 남는 부분이 Eric Raymond의 Art of Unix Programming에서의 내용과 자신의 생각을 말하는 부분이었는데, 뭐, 둘의 출발이나 현재 하고 있는거나 이것저것 완전히 다른 환경에 있는 사람이니 생각이 같기는 어렵겠지.&lt;br /&gt;&lt;img src="http://images.pearsoned-ema.com/jpeg/large/9780131429017.jpg" border="0" /&gt;&lt;br /&gt;난 Raymond의 책에서 정말 감명받았다. 유닉스의 철학인 '작은 것이 아름답다'나 대학 때 배웠던 'Divide &amp;amp; Conquer', '한가지 목적에만 충실하라', 그리고 '데이터에 집중하라' 등등의 멋진 통찰들이 내가 평소 하던 프로그래밍의 사고나 방법을 더욱 튼튼하고 유연하게 했다.&lt;br /&gt;물론 joel도 그러한 것들에는 충분히 동의하고 raymond의 통찰에 찬사를 보냈지만 이미 그 둘은 말했듯이 너무 다른 상황에 있었던지라 유닉스의 간결함이 독선이나 특정 사용자층(특히 프로그래머)에게만 있다는 joel의 생각이 조금은 씁쓸했다.&lt;br /&gt;옆집 할머니가 사용할 수 있는 프로그램이 필요하다는 joel의 생각도 맞다. 물론 나 또한 그런 프로그램이 더더욱 많아야 한다고 생각한다. 그렇다고 raymond의 글을 문장 그대로 해석해야 하나 싶다. 예를 들면 '침묵은 금이다'라는 unix에서의 신조는 아무 메세지를 내보내지 않고 결과가 나오기까지 기다리는(cp *.tar ~/ 와 같이) 방법을 꼭 아니다라고 할 것은 아니고, 해당 사용자가 납득할만한 간결한 메세지만을 보여주는 것으로 이해할 수 있지 않나 싶다. Windows환경에서 돌아가는 프로그램 중에서 정말 승질나게 메세지를 자꾸 내보내는 프로그램들을 심심치 않게 찾을 수 있다. 요새 내가 하고 있는 일(거의 끝났지만)중에 한국 K모 사에서 쓰는 WinCE Application이 있는데 프로그램 동작 도중 서버에 업데이트할 새 프로그램이 발견되면 메세지를 내보낸다. 종전 방법은 "새 프로그램이 발견되었습니다. 업데이트하시겠습니까?"라는 메세지와 yes, no를 선택할 수 있는 Dialog를 내보내고 yes면 또 "종료합니다. 다시 시작하세요"라고 메세지를 보내며 창이 닫힌다. 사용자는 프로그램을 끝내고 다시 시작해야 한다. 그렇다고 종료 안하고 다른 부분을 사용할 수 있는 것도 아니다. 그래서 바꾼 내용은 업데이트할 것이 발견되면 "업데이트 할 내용이 있어 프로그램을 다시 시작합니다." 라는 메세지와 함께 프로그램을 종료하고 업데이트를 진행한다. 다른 것은 도대체가 필요한 것을 모르겠다. 결국 가는 길을 하나이고 별다른 선택을 주지 않는다면 사용자는 실수 하고 싶어도 할 수도 없으니까. 간단한 예지만 사용자의 실수를(No를 선택해서 업데이트를 하지 않고 이후를 진행하고 업데이트는 잊어버리는) 시스템(프로그램 동작)으로 막는 것을 바란다.&lt;br /&gt;뭐, Raymond의 책에선 Windows를 비아냥대는 부분이 여럿있으나 누구나 그렇지 않나 싶다. Raymond가 무슨 성인군자도 아니고. ㅎㅎ (그렇지만 Unix freak들 사이에선 unix가 불교의 선과 같은 깨닭음의 경지가 있다는 식의 유머들이 있다. 재미있는 문화다.)&lt;br /&gt;joel이야 처음부터 지금까지 Packaging programming이어서 특정 회사만을 위한 프로그래밍이 정말 궁금하다고 하면서도 나름대로 정리, 언급하는데, 딱 그 분야인 SI에서 일하고 있는 나로서는 우울함이 울컥울컥.. OTL..&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;P.S 블로그를 다시 시작한지 얼마 되지 않아 글쓰는 것이 예전같지 않고 매끄럽지 않은게 자꾸 끊기고 하는데, 요새 글을 쓸 때 좀 더 쉽고 편한 표현을 사용하려고 하다보니 더더욱 그렇다. 음... 쉬운 표현이 꼭 좋지는 않다는 생각이 방금 이 글을 다시 읽어보면서 느꼈다. 그냥 예전 감각을 살려서 써야지.. =_=&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2745870429268384300?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2745870429268384300/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/joel-on-software.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2745870429268384300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2745870429268384300'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/joel-on-software.html' title='Joel on Software'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2554008644360774869</id><published>2007-04-16T19:13:00.000+09:00</published><updated>2007-04-16T19:19:05.677+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>My character 이야기 - 샬랄라추기경</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Fvbj4JTJPhI/RiNMwrepmGI/AAAAAAAAAB4/s-lSfOF9v2k/s1600-h/shallala1.JPG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_Fvbj4JTJPhI/RiNMwrepmGI/AAAAAAAAAB4/s-lSfOF9v2k/s400/shallala1.JPG" alt="" id="BLOGGER_PHOTO_ID_5053967606028540002" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;그림이 더 크게 안된다. -_-&lt;br /&gt;메디브 서버에서의 첫 캐릭이다. 원래 이름은 예비군오년차. 캐릭 만들 때가 예비군훈련 끝나고 군복입은 상태에서 겜방에 가서 만든거라 아무생각없이 만들어진 이름이다. 이후에 알렉스트라자 서버로 옮기면서 샬랄라추기경으로 바꿨다.&lt;br /&gt;확팩이후 3달이 다되도록 간신히 만렙만 찍어놓고 별로 달리지 않는 비운의 캐릭이다. 사제는 영 졸려서.. -_-&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2554008644360774869?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2554008644360774869/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/my-character.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2554008644360774869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2554008644360774869'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/my-character.html' title='My character 이야기 - 샬랄라추기경'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Fvbj4JTJPhI/RiNMwrepmGI/AAAAAAAAAB4/s-lSfOF9v2k/s72-c/shallala1.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-6871748029477948471</id><published>2007-04-16T14:29:00.000+09:00</published><updated>2007-04-16T15:24:15.427+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='머리속 그림들'/><title type='text'>아직도 정리되지 않은 수많은 요즘 시대 이야기들.</title><content type='html'>일하는 시간 중에서 그냥 보내는 시간이 생기기 시작했다. 이제야 프로젝트가 막판으로 달리는 뜻이다.&lt;br /&gt;멍한 시간엔 여러 기사들을 읽는다, 물론 관심가는 것들만. zdnet, 블로그 등등.&lt;br /&gt;UCC가 난리인건 조금 시간이 되었고 아직도 시끌시끌할 게 많을 UCC이다. WEB2.0이라는 것도 시끌시끌하고, 글을 쓰던 이미지를 올리던 동영상을 뿌리던 유저 입장에서도 해당 컨텐츠의 공간을 만들 제공자나 개발자 입장에서도 할 말도 할 것도 많다.&lt;br /&gt;깊게 생각해 본적은 없지만 나에겐 그냥 아직도 한 때 지나가는 유행같다. 한가지 공감하는 것은 주체의 확산이라는 것 밖에.&lt;br /&gt;내가 바라는 세상엔 분명 모든 사람이 아니 정말 모두는 아니고 사용하는 사람들이 제공하는 사람과 거의 같아지는 그런 세상이다. 누구나 제공하고 누구나 사용할 수 있는 그런 세상말이다. 뭐, 현재의 UCC가(UCC든 UCG든) 비슷하긴 하지만 아직도 공간을 제공하는 업체측은 사용자가 많이많이 만들어주길 바라는 포스가 꽤 있다. 유투브에 동영상 안올리면 유투브도 망하는 거니까.&lt;br /&gt;&lt;br /&gt;무언가 부족하다.&lt;br /&gt;만들어서 공유하고 보고 즐긴다 라는 현재 트렌드가 내게는 그리 열광할 만한 것이 못된다. 지금 느낌은 뭐랄까.... 시내 한복판에 높은 스테이지가 생겨서 올라가는 사람을 환호하고 올라간 본인은 무언가 특별한 사람이 된 것 같은 집단최면같이 느껴진다.&lt;br /&gt;부족하다는 건 그냥 '보고 이야기한다'라는 것의 단순함이다. 좀 더 감각적이길 원한다. 그렇지만 아직 만진다던가(촉감) 맛본다던가(미감) 하는 건 멀고 먼 훗날 이야기일까.&lt;br /&gt;&lt;a href="http://i-guacu.com/1593"&gt;UCC는 컨텐츠와 커뮤티케이션의 결합이 빚어낸 현상이라고 한다.&lt;/a&gt; 하지만 그냥 그런 것 같지만은 않다. 거기엔 흥미를 당기는 맛과 보고자하는 사람들의 욕구가 있어 UCC가 열광되는 것이 아닌가 한다. 게다가 지식의 확산이라는 현상이 일어나면서(사람들 입에, 웹 링크에 전해지는) 정보의 공유와 해당 내용의 공감이 커뮤니티라는 말많은 얘기꺼리를 만들어낸다. 결국 해당 컨텐츠는 높은 스테이지 위에 있게 되는 것이고 더더욱 많은 사람들이 보고 말하게 되는 루프가 점점 더 커지고 더이상의 욕구를 불러 일으키지 않게 되면 루프는 끝난다.&lt;br /&gt;루프는 좋다. 나 또한 정보나 지식의 확산이 좀 더 투명한 사회를 만들 수 있다고 생각하니까.(물론 피해를 줄 수 있는 부작용도 있겠지만 말이다.) 문제는 사람은 시간에 갇혀있는 존재라는 것이고 감각적인 욕구에 끌릴때가 꽤나 많다는 것이다. UCC에 부시 사생활이라도 올라오면 입소문은 금방일테니. 후후.. -_-&lt;br /&gt;&lt;br /&gt;음.. 정리 안된다. 역시.&lt;br /&gt;그냥 전에 간단히 생각해 본 것은 원시시대의 가상환경에 사람이 놓인다면 어떤 일들이 일어날까 하는 것이었는데 생각하다보니 그것보다는 더 서로 행복을 줄 수 있는 환경을 만드는 것이 어떨까 했다. &lt;br /&gt;목소리가 더 멀리 전해지면 세상은 더 시끄러워 질 것이다. 발걸음이 더 빠르다면 사람들은 더 많이 부딛힐 것이다. 음.. 또 뭐가 있을까? 생각의 속도는 비슷하고 사람들의 욕구도 비슷하다. 아, 가만.. 욕구를 실현해 줄 만한 건 더 만들 수 있을지도. 결국 그건가.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-6871748029477948471?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/6871748029477948471/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/blog-post_16.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/6871748029477948471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/6871748029477948471'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/blog-post_16.html' title='아직도 정리되지 않은 수많은 요즘 시대 이야기들.'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-3061312499473914900</id><published>2007-04-05T13:47:00.000+09:00</published><updated>2007-08-08T15:04:52.164+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announce'/><title type='text'>이곳을 방문하신 분들께.</title><content type='html'>제 블로그를 찾아주셔서 감사합니다.&lt;br /&gt;무언가 멋진 인사말을 넣으려고 며칠이나 광고성 글만 올려놓다가 아무리 생각해도 많은 사람들이 공감하는 글은 없겠다 싶어서 인사말이라는 걸 접었습니다. -_-a&lt;br /&gt;그저 이런저런 넋두리와 가끔하는 메모 등등을 넣는 단순한 개인 포스트의 모임입니다.&lt;br /&gt;이래저래해도 모든 분들이 행복하길 기원할 뿐이예요 ㅎㅎ&lt;br /&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: right"&gt;icksishu At gmail Dot com &lt;/div&gt;&lt;div style="TEXT-ALIGN: right" align="left"&gt; &lt;/div&gt;&lt;div style="TEXT-ALIGN: right" align="left"&gt;P.S 프로그램 개발에 목말라 있는 분들은 같이 조용히 담소를 나누었으면 좋겠습니다~ ^^&lt;/div&gt;&lt;div style="TEXT-ALIGN: right" align="left"&gt; &lt;/div&gt;&lt;div style="TEXT-ALIGN: right" align="left"&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-3061312499473914900?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/3061312499473914900/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/blog-post_05.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3061312499473914900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3061312499473914900'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/blog-post_05.html' title='이곳을 방문하신 분들께.'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-6830180883823846226</id><published>2007-04-05T13:41:00.000+09:00</published><updated>2007-04-05T13:47:30.315+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Project::SecretMessanger'/><title type='text'>Project::SecretMessanger</title><content type='html'>오늘 잡담하던 중에 회사의 최모씨의 바람이 있었다.&lt;br /&gt;왠간한 대기업은 방화벽을 사용하여 메신저를 막는다. 그래서 그 회사의 메신저만 사용해야 한다. LG의 i-Messanger와 같은. -_-&lt;br /&gt;그래서 생각해본 게 거의 모든 방화벽은 몇개의 port만을 열어놓는데 그 중에 HTTP를 이용한 메신저가 어떨까 싶었다.&lt;br /&gt;독하게 패킷 내부를 검사해서 막아버리는 것을 우회하기위한 로직도 넣고 해서... 일단 freeware로 뿌리는 것이 어떨까 싶다.&lt;br /&gt;그래서 지금 HTTP 명세와 활용방법을 구상중이다. ㅎㅎ&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-6830180883823846226?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/6830180883823846226/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/projectsecretmessanger.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/6830180883823846226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/6830180883823846226'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/projectsecretmessanger.html' title='Project::SecretMessanger'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-7986859818552233559</id><published>2007-04-04T17:14:00.000+09:00</published><updated>2007-04-04T19:21:29.338+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announce'/><title type='text'>for non-korean friends visited my blog</title><content type='html'>Hi, I'm Baek Semin. you can call me Samuel Baek or Sam.&lt;br /&gt;I am sorry most my posts are written only korean.&lt;br /&gt;I love all kind of programming. yes, I love them.&lt;br /&gt;and I am working in some SI company.&lt;br /&gt;However, jobs of SI almost are boring to me. I want more extrime projects&lt;br /&gt;I've developed about Win32 apps, web apps with java servlet, web pages of php and mobile apps in WinCE.&lt;br /&gt;I don't like MS tools (kind of Visual series) even if I have to use visual studio, eVC in my company.&lt;br /&gt;I wanna make something special like the Second Life.&lt;br /&gt;If you wanna know some foreign developer or tell about programming, you can send email to me.&lt;br /&gt;I'm sure to be happy for somebody.&lt;br /&gt;&lt;div style="text-align: right;"&gt;icksishu At gmail dot com&lt;/div&gt;God Bless you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-7986859818552233559?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/7986859818552233559/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/for-non-korean-friends-visited-my-blog.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7986859818552233559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7986859818552233559'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/for-non-korean-friends-visited-my-blog.html' title='for non-korean friends visited my blog'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-8679897614514666674</id><published>2007-04-04T11:38:00.000+09:00</published><updated>2007-04-04T11:50:42.872+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>Elephants Dream - Orange Team</title><content type='html'>Blender에 대한 문서들을 모으던 중 Elephants Dream이라는 걸 발견했다.&lt;br /&gt;&lt;center&gt;&lt;img src="http://orange.blender.org/wp-content/themes/orange/images/media/ed-thumb-1920.jpg" /&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;무려 Blender로 제작된 에니메이션 영화라는 것이다. DVD로도 판매한다. 대박!&lt;br /&gt;&lt;center&gt;&lt;img src="http://www.blender3d.org/e-shop/images/640/orangedvd.jpg" name="pop" alt="Blender Images" border="0" /&gt;&lt;/center&gt;&lt;br /&gt;가격은 35$ 란다.&lt;br /&gt;&lt;a href='http://www.blender3d.org/e-shop/product_info.php?products_id=84'&gt;&lt;b&gt;&lt;span style="font-family:Verdana, Arial;font-size:130%;color:#000000;"&gt;Elephants Dream, Open Movie DVD  &lt;s&gt;� 39.00&lt;/s&gt;  &lt;span style="color:#ff0000;"&gt;� 35.00&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;그냥 보는 것은 &lt;a href='http://orange.blender.org/download'&gt;다운로드&lt;/a&gt; 할 수 있다.&lt;br /&gt;한글 자막이 지원되지 않는 것이 아쉽지만 멋지다고 할 수 밖에 없다. ㅜ_ㅜ 감동이다.&lt;br /&gt;아직 보지는 못했다.&lt;br /&gt;&lt;br /&gt;더군다나 또 대박이.... Elephants Dream을 제작한 &lt;a href='http://video.blendertestbuilds.de/download.blender.org/ED/DVD1/blog/'&gt;Orange Team&lt;/a&gt;이 웹서버 설정을 잘못한건지 디렉토리를 그대로 볼 수 있어서 Elephants Dream의 소스를 볼 수 있었다. -_- 일단 다운.. ;;&lt;br /&gt;그들의 소스를 잠깐동안 살펴봤는데, Blender를 나름대로 뜯어고친 듯 하다. 소스도 있다. -_- 그리고 제작에 쓰인 스크립트가 &lt;a href='http://www.python.org/'&gt;Python&lt;/a&gt;이라는 것. 정말 python은 다양한 용도로 쓰이는 것 같다.&lt;br /&gt;나도 하고 싶다!!&lt;br /&gt;&lt;br /&gt;보고나면 또 할 말이 많겠지.. 아움..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-8679897614514666674?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/8679897614514666674/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/elephants-dream-orange-team.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8679897614514666674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8679897614514666674'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/elephants-dream-orange-team.html' title='Elephants Dream - Orange Team'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-591044828098538834</id><published>2007-04-03T17:35:00.000+09:00</published><updated>2007-08-08T17:59:00.020+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>Blender 한글 튜토리얼</title><content type='html'>3D 툴을 찾아보다가 결국 Blender에 대해 이리저리 찾는 중 HWP로 된 문서 발견.&lt;br /&gt;dambee 라는 분이 손수 작성해서 공개한 거다. 여기에 올리려고 했는데 파일 올리기 같은 건 안되고..&lt;br /&gt;음... 일단 로컬로 갖고 있지만, 제작자가 맘껏 공개해달라고 적어놨으니 HTML로 바꿔서 적어봐야겠다.&lt;br /&gt;&lt;br /&gt;마지막 인용글을 포함해 넣겠다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;당연한 얘기지만 이 글은 다른 누구에게라도 배포하실 수 있습니다. 지식은 독식보다는 공유를 통해 더 발전한다고 저 자신은 믿고 있으니까요. 다만 지식의 공유라는 목적을 벗어나 경제적인 목적이나 개인적인 명예욕 때문에 저의 졸문을 도용하는 행위를 해서는 안됩니다. 언제가 될지는 모르겠지만 다음 번 매뉴얼을 통해 더 깊이 있는 내용으로 만날 수 있도록 노력하겠습니다. 그럼 그때까지 안녕히...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Happy Blending...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;dambee E-mail : dambee@kebi.com&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;추가 :&lt;br /&gt;세상에나... blender에 대한 책이 나왔나 찾아보는 중에... blender 위키에 한글 튜토리얼이 있는 걸 발견.. -_-       -&gt; http://wiki.blender.org/index.php/Manual.kr/Manual&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="http://wiki.blender.org/index.php/Manual.kr/Manual"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-591044828098538834?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/591044828098538834/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/blender.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/591044828098538834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/591044828098538834'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/blender.html' title='Blender 한글 튜토리얼'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-1900119037124048689</id><published>2007-04-03T16:22:00.001+09:00</published><updated>2007-04-05T13:39:57.946+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Project::My Room'/><title type='text'>Concept Note</title><content type='html'>보통 사람이 사는 듯한 방을 구성한다.&lt;br /&gt;방에는 애완동물(개, 고양이 등등)이 있다.&lt;br /&gt;애완동물은 독립적으로 활동한다.&lt;br /&gt;특정조건(주기적? 특정 이벤트?)에 의해 스크린샷을 남기고 바탕화면 이미지를 이것으로 교체한다.&lt;br /&gt;각 host는 peer-to-peer로 다른 호스트에 방문할 수 있다.&lt;br /&gt;&lt;br /&gt;지원 플랫폼 : Mac OS X, Linux, Windows&lt;br /&gt;사용될 엔진 : ODE, Irrlicht&lt;br /&gt;언어 : C++&lt;br /&gt;개발툴 : Code:Blocks(gcc), Xcode(gcc), 3DMax&lt;br /&gt;&lt;br /&gt;- comment&lt;br /&gt;되도록 open source로 진행하고 싶은데 modeling tool을 잘 모르니 이게 또 만만치 않다.&lt;br /&gt;일단 찾아본 것은 &lt;a href="http://www.moonlight3d.eu/cms/"&gt;Moonlight3D&lt;/a&gt;, &lt;a href="http://www.blender.org/"&gt;Blender&lt;/a&gt;, &lt;a href="http://openfx.org/"&gt;OpenFX&lt;/a&gt;, &lt;a href="http://innovation3d.sourceforge.net/"&gt;Innovation3D&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Blender - Linux, Mac OS X, Windows, Solaris, FreeBSD등등.. 무작 지원.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;2D 포멧 : TGA, JPG, PNG, OpenEXR, DPX, Cineon, Radiance HDR, Iris, SGI Movie, IFF, AVI and Quicktime GIF, TIFF, PSD, MOV&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;  3D 포멧 : 3D Studio, AC3D, COLLADA, DEC Object File Format, DirectX, Lightwave, MD2, Motion Capture, Nendo, OpenFlight, PLY, Pro Engineer, Radiosity,Raw Triangle, Softimage, STL, TrueSpace, VideoScape, VRML, VRML97, Wavefront, X3D Extensible 3D, xfig export&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;    최강이다.. &gt;_&lt;&lt;br /&gt;Moonlight3d - Linux, Windows 지원, 문서가 빈약해서 포기. -_-&lt;br /&gt;OpenFX - Windows만 지원. -_-a  Windows만... Windows만...&lt;br /&gt;Innovation3D - Linux만 지원... 우움..&lt;br /&gt;결국 Blender 낙찰...? 그러나 쓸 사람이 쓴다고 해야 낙찰이겠다.(게다가 3D Max나 Maya등이 문서나 튜토리얼 구하기 더 좋지 않겠나.. -_-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-1900119037124048689?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/1900119037124048689/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/concept-note.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1900119037124048689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1900119037124048689'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/concept-note.html' title='Concept Note'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-8818380550898444255</id><published>2007-04-03T13:37:00.000+09:00</published><updated>2007-04-03T13:44:10.269+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>ipaq 후후..</title><content type='html'>&lt;img src="http://h50201.www5.hp.com/product/finished_goods/h5550/images/h5550_pop_img.gif" /&gt;&lt;br /&gt;결혼직전에 집에 있던 15인치 LCD패널하고 요놈하고 회사에 황모과장님이랑 바꿨다.&lt;br /&gt;한동안 묻어놨다가 이제 꺼내서 좀 써보려고 하는 중이다.&lt;br /&gt;생각보다 성능이 좋다. 일단 빠르고, 용량 크고. 거기에 Sandisk 2GB miniSD도 하나 샀다. 21000원이였던가.. 번들로 제공된 디오펜인가 하는 펜인식IME도 잘 되더라. 정말 잘되더라. -_-;&lt;br /&gt;일단은 포켓알맵공개용을 깔아서 봤는데 꽤 쏠쏠하다. 동영상 재생이나 MP3같은 것도 잘 되지만 동영상 볼일은 별루 없을 것 같고.. MP3야 ipod이 있으니까. 후후.. -_-+&lt;br /&gt;슈패애뮬이라던가 마메라던가 각종 에뮬도 PPC로 나와있으니 잘 쓸 수는 있겠지만, 역시나 시간이 없어서.. 요샌 버스타고 다니는 것도 아니라 할 시간이 없다. -_-&lt;br /&gt;그래도 와이프랑 놀러다닐때 알맵이 한 몫 할 것 같다. pdf 파일 보고 있다거나 할 때도 좋을 듯 하고.. 어쨋든 알맵 대만족. 후후후..&lt;br /&gt;&lt;br /&gt;P.S 지문인식 기능이 있는데 하지 말라나.. 잘못되면 하드리셋해도 안된다나 어쩌나.. -_-&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-8818380550898444255?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/8818380550898444255/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/ipaq.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8818380550898444255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8818380550898444255'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/ipaq.html' title='ipaq 후후..'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-8001440252135163389</id><published>2007-04-02T18:37:00.000+09:00</published><updated>2007-04-02T18:58:16.299+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>요새 근황</title><content type='html'>블로그를 한동안 안쓰다 쓰려니 음.. 아무생각 안난다.&lt;br /&gt;3월부터 KT&amp;G에서 프로젝트를 진행중이다.&lt;br /&gt;Mobilian이라는 회사에서 나온 PDA인데&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.bluebird.co.kr/products/bip_1200/img/product_front.gif" height="380" width="236" /&gt;&lt;br /&gt;이렇게 생겼다. 여기에 들어가는 영업/판매용 어플리케이션이 있다.&lt;br /&gt;XDB라는 dBase 후손의 로컬DB가 쓰였는데 그걸 Sybase의  UltraLite로 갈아치우는 작업이다.&lt;br /&gt;덤으로 Afaria라는 모바일 업데이트 프로그램도 import시킨다.&lt;br /&gt;eVC(embeded Visual C++)로 작업하고 MFC기반이다. 물론 첨 하는 거. -_-&lt;br /&gt;이런건 사실 큰 문제가 되지 않지만(eVC는 버그가 많다. -_-) 문제는 KT&amp;amp;G.&lt;br /&gt;출근이 8시 30분까지인데... 여긴 신탄진이니까.. 가는데 4~50분 걸리구 그러려면 7시 30분에 나가는데... 또 그러려면 6시 반에 기상. -_-&lt;br /&gt;게다가 정시 퇴근시간이 저녁 7시. 집에가서 밥먹고 하면 순식간에 9시다. -_-&lt;br /&gt;정말 하루가 빠르다. ㅜ_ㅜ&lt;br /&gt;&lt;br /&gt;다행이도 지금은 거의 끝나가고 프로그램 테스트 중인데... 잘하면 이번주에 끝낼 수 있으려나..&lt;br /&gt;와이프랑 보낼 시간도, WOW할 시간도, 내 개인 프로젝트 할 시간도, 잡생각할 시간도.. 적기만하다. 하루가 36시간이었으면 얼마나 좋을까..&lt;br /&gt;&lt;br /&gt;벗꽃이 만개하기 시작했다. (신탄진이 벗꽃으로 유명했다니.. orz...)&lt;br /&gt;언능 끝내자. -_-+&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-8001440252135163389?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/8001440252135163389/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/blog-post.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8001440252135163389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8001440252135163389'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/blog-post.html' title='요새 근황'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-1263113406046190592</id><published>2007-04-02T18:22:00.001+09:00</published><updated>2007-04-05T13:39:57.947+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Project::My Room'/><title type='text'>irrlicht 확정!</title><content type='html'>이런 저런 구상을 하다가 결국 3D 환경으로 해야 하지 않겠나 싶은게..&lt;br /&gt;취미로 밀어붙일 프로젝트가 떠올랐다.&lt;br /&gt;차차 정리하고..&lt;br /&gt;&lt;br /&gt;일단 3D로 만들어지려면 DirectX나 OpenGL로 노가다하기는 싫으니까 적당히 엔진을 물색했다.&lt;br /&gt;결정 조건은&lt;br /&gt;1. Cross-Platform 이어야 할 것. (Mac, X-Window, Windows)&lt;br /&gt;2. DirectX, OpenGL 둘다 지원할 것.&lt;br /&gt;3. Open Source일 것. (되도록 GPL 말구..)&lt;br /&gt;4. Borland Tool을 지원할 것.&lt;br /&gt;5. 자세한 문서가 있을 것.&lt;br /&gt;6. 다양한 예제들이 있을 것.&lt;br /&gt;&lt;br /&gt;물망대에 오른 것이 Genesis3D, Ogre, Irrlicht, yake 등.&lt;br /&gt;Genesis3D는 맥을 지원하기 어려워서 빠짐.&lt;br /&gt;Ogre도 좋긴 한데 Borland 것들로는 너무 어려워서 제거.&lt;br /&gt;Irrlicht 요게 업데이트도 좋고, 사운드 엔진에 XML 엔진 등등 서드파티가 많고 좋긴 한데 역시 borland tool을 사용하기 빡시다. 그치만 가능함.&lt;br /&gt;yake 이거야 말도 가장 방대하지 않을까 싶었지만서도.. borland에서 역시 막힘.&lt;br /&gt;사실 결정된 이유는 구조가 좋은 irrlicht 랄까..&lt;br /&gt;&lt;br /&gt;&lt;img alt="Irrlicht Engine logo" src="http://irrlicht.sourceforge.net/images/general/irrlichtlogo.gif" height="60" width="233" /&gt;&lt;br /&gt;&lt;br /&gt;멋진 놈이다. 후후..&lt;br /&gt;업무중에 일은 안하고 몇가지 메쉬 찍는 테스트를 해봤다. Code::Block이라는 툴을 사용.&lt;br /&gt;사용하기 젤 편한 듯 해서 결국 irrlicht 결정!&lt;br /&gt;&lt;br /&gt;import할 포멧들도 다양하게 지원한다.&lt;br /&gt;한국에서야 3d max가 가장 많이 쓰인다고 하니 음... 누굴 꼬드겨서 해보라고할까 생각중.&lt;br /&gt;&lt;br /&gt;으쌰~ 출발할 수 있겠구나~&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-1263113406046190592?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/1263113406046190592/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/04/irrlicht.html#comment-form' title='1개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1263113406046190592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1263113406046190592'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/04/irrlicht.html' title='irrlicht 확정!'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-1315536746604817784</id><published>2007-03-31T20:32:00.002+09:00</published><updated>2007-04-17T11:42:20.581+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for Win32'/><title type='text'>[Naver Blog 2004/11/18 16:15] Borland C++에서 Windows API 사용할 때..</title><content type='html'>&lt;p&gt;// 컴퓨터 이름을 알아내서 저장하는 것.&lt;/p&gt; &lt;p&gt;// DataMod는 VCL의 DataModule을 상속받은 것.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;    char szBuffer[MAX_COMPUTERNAME_LENGTH+1];&lt;br /&gt;// 컴퓨터 이름을 저장할 버퍼&lt;/p&gt; &lt;p&gt;    DWORD dwcNameSize = MAX_COMPUTERNAME_LENGTH + 1;&lt;/p&gt; &lt;p&gt;// Windows만의 데이터타입인 DWORD&lt;/p&gt; &lt;p&gt;// unsigned long을 typedef 한 것&lt;br /&gt;    GetComputerName(szBuffer, &amp;dwcNameSize);&lt;/p&gt; &lt;p&gt;// 이 함수(WinAPI)가 이름을 알아냄. 인자값 둘 다 address reference&lt;br /&gt;    DataMod-&gt;IssueUnit = StrPas(szBuffer);&lt;/p&gt; &lt;p&gt;//&lt;span style="font-size:85%;"&gt; StrPas()는 PChar형의 데이터를 String형으로 변환&lt;/span&gt;&lt;br /&gt;    DataMod-&gt;IssueUnit = DataMod-&gt;IssueUnit.SubString(DataMod-&gt;IssueUnit.Length(),1);&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;뭐.. 그렇게~&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-1315536746604817784?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/1315536746604817784/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041118-1615-borland-c.html#comment-form' title='2개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1315536746604817784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1315536746604817784'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041118-1615-borland-c.html' title='[Naver Blog 2004/11/18 16:15] Borland C++에서 Windows API 사용할 때..'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-8723788268185522220</id><published>2007-03-31T20:32:00.001+09:00</published><updated>2007-03-31T20:34:58.837+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for EJB'/><title type='text'>[Naver Blog 2004/05/22 14:11] EJB 작성 - Enterprise Bean 작성하기 (2)</title><content type='html'>&lt;p&gt;엔터프라이즈 빈 클래스&lt;/p&gt; &lt;p&gt; - 원격 인터페이스의 비지니스 메소드를 실제로 구현하는 클래스이다.&lt;/p&gt; &lt;p&gt; - javax.ejb.EnterpriseBean를 상속한 javax.ejbSessionBean 인터페이스 또는 javax.ejb.EntityBean 인터페이스 또는 javax.ejb.MessageDrivenBean 인터페이스를 implements 한다.&lt;/p&gt; &lt;p&gt; - 엔터프라이즈 빈은 홈 인터페이스에서 정의된 메소드에 상응하는 콜백 메소드를 구현한다.&lt;/p&gt; &lt;p&gt;   (홈 인터페이스에서 정의한 메소드를 직접 엔터프라이즈 빈에서 구현하지는 않고 홈 인터페이스에서 정의된 원격 메소드를 엔터프라이즈 빈 클라이언트가 호출하게 되면 EJB 컨테이너가 콜백으로 실제 엔터프라이즈 빈 인스턴스의 메소드를 호출하게 되는데, 콜백 메소드란 홈 인터페이스의 원격 메소드에 상응하는 콜백 메소드가 EJB 컨테이너가 홈 인터페이스에서 정의한 원격 메소드 호출에 대한 결과로 호출하게 되는 엔터프라이즈 빈의 메소드를 말하는 것이다.)&lt;/p&gt; &lt;p&gt;   (엔터프라이즈 빈 클라이언트 -&gt; 메소드 호출 -&gt; EJB 컨테이너의 엔터프라이즈 빈 인스턴스 메소드 호출 -&gt; 클라이언트에 전달)&lt;/p&gt; &lt;p&gt; - 원격 인터페이스에서 정의한 메소드의 시그너쳐와 리턴 타입이 동일하여야 하며 동일한 Exception을 throws한다.&lt;/p&gt; &lt;p&gt; - 디폴트 생성자를 반드시 가져야 한다.&lt;/p&gt; &lt;p&gt;    (개발자가 직접 생성하지 않는다.)&lt;/p&gt; &lt;p&gt;    (ex)&lt;/p&gt; &lt;p&gt;    Class ejb = Class.forName("com.scourge.ejb.MyBean");&lt;/p&gt; &lt;p&gt;       // 현재의 ClassLoader를 사용하여 메모리에 로드&lt;/p&gt; &lt;p&gt;    MyBean bean = (ejb.scourge.ejb.MyBean)ejb.newInstance();&lt;/p&gt; &lt;p&gt;       // 디폴트 생성자 호출&lt;/p&gt; &lt;p&gt; - 예)&lt;/p&gt; &lt;p&gt;  import java.rmi.Remote;&lt;/p&gt; &lt;p&gt;  import javax.ejb.SessionBean;&lt;/p&gt; &lt;p&gt;  import javax.ejb.EJBException;&lt;/p&gt; &lt;p&gt;  import javax.ejb.CreateException;&lt;/p&gt; &lt;p&gt;  import javax.ejb.SessionContext;&lt;/p&gt; &lt;p&gt;  public class HelloBean implements SessionBean {&lt;/p&gt; &lt;p&gt;       public HelloBean() {&lt;/p&gt; &lt;p&gt;              System.out.println("constructor..");&lt;/p&gt; &lt;p&gt;       }&lt;/p&gt; &lt;p&gt;       public void ejbCreate() throws RemoteException, CreateException {&lt;/p&gt; &lt;p&gt;              System.out.println("ejbCreate() Called");&lt;/p&gt; &lt;p&gt;       }&lt;/p&gt; &lt;p&gt;       public String sayHello(String name) throws RemoteException {&lt;/p&gt; &lt;p&gt;              return "Hello " + name + "!!";&lt;/p&gt; &lt;p&gt;       }&lt;/p&gt; &lt;p&gt;       public void ejbActivate() throws RemoteException, EJBException {&lt;/p&gt; &lt;p&gt;       }&lt;/p&gt; &lt;p&gt;       public void ejbPassivate() throws RemoteException, EJBException {&lt;/p&gt; &lt;p&gt;       }&lt;/p&gt; &lt;p&gt;       public void setSessionContext(SessionContext ctx) throws RemoteException,&lt;/p&gt; &lt;p&gt;              EJBException {&lt;/p&gt; &lt;p&gt;              System.out.prinln("HelloEJB instance create..");&lt;/p&gt; &lt;p&gt;       }&lt;/p&gt; &lt;p&gt;       public void ejbRemove() throws RemoteException, EJBException {&lt;/p&gt; &lt;p&gt;       }&lt;/p&gt; &lt;p&gt;}&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-8723788268185522220?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/8723788268185522220/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/ejb-enterprise-bean-2.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8723788268185522220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8723788268185522220'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/ejb-enterprise-bean-2.html' title='[Naver Blog 2004/05/22 14:11] EJB 작성 - Enterprise Bean 작성하기 (2)'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-5686944120444836572</id><published>2007-03-31T20:31:00.001+09:00</published><updated>2007-03-31T20:34:58.837+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for EJB'/><title type='text'>[Naver Blog 2004/05/22 12:37] EJB 작성 - Enterprise Bean 작성하기 (1)</title><content type='html'>&lt;p&gt;하나의 엔터프라이즈 빈을 작성하기 위해 필요한 파일&lt;/p&gt; &lt;p&gt; - 원격 인터페이스, 홈 인터페이스, 엔터프라이즈 빈 클래스, 프라이머리 키 클래스&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;원격 인터페이스 파일&lt;/p&gt; &lt;p&gt; - 원격 인터페이스는 엔터프라이즈 빈이 제공하는 비지니스 메소드(서비스)를 정의하는 &lt;/p&gt; &lt;p&gt;    인터페이스이며 javax.ejb.EJBObject를 상혹하여 정의한다.&lt;/p&gt; &lt;p&gt; - 모든 메소드는 java.rmi.RemoteException을 throws 하도록 정의한다.&lt;/p&gt; &lt;p&gt;    (javax.ejb.EJBObject가 java.rmi.Remote 인터페이스를 상속하기 때문이다.)&lt;/p&gt; &lt;p&gt; - 리턴타입이나 파라미터 형은 RMI 타입이어여한다.&lt;/p&gt; &lt;p&gt; - 예)&lt;/p&gt; &lt;p&gt;  import java.rmi.Remote;&lt;/p&gt; &lt;p&gt;  import javax.ejb.EJBObject;&lt;/p&gt; &lt;p&gt;  public interface Hello extends EJBObject {&lt;/p&gt; &lt;p&gt;       public String sayHello(String name) throws RemoteException;&lt;/p&gt; &lt;p&gt;  }&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;홈 인터페이스 파일&lt;/p&gt; &lt;p&gt; - 홈 인터페이스는 엔터프라이즈 빈의 라이프 사이클과 관련된 메소드를 정의하는 인터페이스.&lt;/p&gt; &lt;p&gt; - javax.ejb.EJBHome 인터페이스를 상혹한다.&lt;/p&gt; &lt;p&gt; - create 메소드나 엔티티 빈을 위한 Finder 메소드만을 정의한다.&lt;/p&gt; &lt;p&gt; - 모든 메소드는 기본적으로 java.rmi.RemoteException을 throws한다.&lt;/p&gt; &lt;p&gt;    (이것도 java.rmi.Remote 인터페이스를 상속한 인터페이스이기 때문이다.)&lt;/p&gt; &lt;p&gt; - create 메소드를 정의할 때&lt;/p&gt; &lt;p&gt;    -- 리턴형은 원격 인터페이스 타입이어야 한다.&lt;/p&gt; &lt;p&gt;    -- create 메소드는 오버로딩을 할 수 있다.&lt;/p&gt; &lt;p&gt; - 예)&lt;/p&gt; &lt;p&gt;  import java.rmi.RemoteException;&lt;/p&gt; &lt;p&gt;  import javax.ejb.EJBHome;&lt;/p&gt; &lt;p&gt;  import javax.ejb.CreateException;&lt;/p&gt; &lt;p&gt;  public interface HelloHome extends EJBHome {&lt;/p&gt; &lt;p&gt;       public Hello create() throws CreateException, RemoteException;&lt;/p&gt; &lt;p&gt;  }&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-5686944120444836572?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/5686944120444836572/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040522-1237-ejb-enterprise.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5686944120444836572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5686944120444836572'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040522-1237-ejb-enterprise.html' title='[Naver Blog 2004/05/22 12:37] EJB 작성 - Enterprise Bean 작성하기 (1)'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-4688316182581314699</id><published>2007-03-31T20:29:00.001+09:00</published><updated>2007-03-31T20:31:04.792+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for PHP'/><title type='text'>[Naver Blog 2004/07/07 14:28] 입력 폼에서 추출하여 업데이트 하는 함수</title><content type='html'>&lt;p&gt;// POST로 넘어온 것 중 걸러서 update하는 함수&lt;br /&gt;function updateSiteInfo($uid, $tableName) {&lt;br /&gt; global $HTTP_POST_VARS;   // POST 연관배열을 전역변수로 선언하고&lt;br /&gt; $attribute[] = array_values($HTTP_POST_VARS); // 연관배열의 인덱스 인자를 배열로 넣고 -&gt; DB attribute가 됨&lt;br /&gt; $query = "update $tableName set ";  // 업데이트 쿼리문 준비&lt;br /&gt; for($i=0; $i&lt;count($HTTP_POST_VARS); $i++) { // 연관배열의 인덱스 만큼 쿼리를 한다&lt;br /&gt;  if($attribute[i] != "send") { // hidden text를 제외하고&lt;br /&gt;   $query .= $attribute[i]." = ";&lt;br /&gt;   $query .= "'".$HTTP_POST_VARS[$i]."' where = '".$uid."'";&lt;br /&gt;   $queryResult = mysql_query($query);&lt;br /&gt;   if (!$queryResult) { // 예외처리&lt;br /&gt;    error("QUERY_ERROR");&lt;br /&gt;    return "no";&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;// $query = substr($query,(strlen($query)-1)); // 맨 뒤의 한 글자 제거 -&gt; ","&lt;br /&gt; return "yes";&lt;br /&gt;}&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;지난번에 만들었던 함수를 update에 맞게 고치다가 array_values()를 발견했다. 생각해보니까 딱 맞는데.. 더 세련되게 만들 수 있었을텐데..&lt;/p&gt; &lt;p&gt;그래서 다시 만들었다. 세련된 코드.. ㅡㅡv&lt;/p&gt; &lt;p&gt;error()는 에러를 출력하는 함수로 회사 사장님이 만든거다. 혹시 이거 보고 하실분들은 에러처리에서 알아서 고치시길. ㅡㅡ;;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-4688316182581314699?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/4688316182581314699/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040707-1428.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/4688316182581314699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/4688316182581314699'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040707-1428.html' title='[Naver Blog 2004/07/07 14:28] 입력 폼에서 추출하여 업데이트 하는 함수'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-4733176205531036217</id><published>2007-03-31T20:28:00.000+09:00</published><updated>2007-03-31T20:31:04.792+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for PHP'/><title type='text'>[Naver Blog 2004/06/12 03:41] 자유롭게 검색할 수 있도록 폼에서 쿼리문 추출하기</title><content type='html'>&lt;p&gt; // 검색을 위해 입력된 폼에서 쿼리문을 만들어내는 함수&lt;br /&gt; function combiQuery($tablename, $attributes, $order) {  // table name으로 인자를 받는다.&lt;br /&gt;  global $HTTP_POST_VARS;   // POST 연관배열을 전역변수로 선언하고&lt;br /&gt;  for($i = 0; $i &lt; count($HTTP_POST_VARS); $i++) { // count를 계산&lt;br /&gt;   if(current($HTTP_POST_VARS)) $formcount++;&lt;br /&gt;   next($HTTP_POST_VARS);&lt;br /&gt;  }&lt;br /&gt;  reset($HTTP_POST_VARS); // 배열 포인터를 처음으로 돌림&lt;/p&gt; &lt;p&gt;  if($formcount != 0) {   // 입력된 폼이 하나 이상일 때&lt;br /&gt;   $query = "select ".$attributes." from ".$tablename." where";  // 쿼리문에 where 절 삽입&lt;/p&gt; &lt;p&gt;   for($i = 0; $i &lt; count($HTTP_POST_VARS); $i++) {   // 폼의 최대값만큼 루프를 돌며&lt;br /&gt;    if(current($HTTP_POST_VARS)) {   // POST 연관배열에 값이 있을 때&lt;br /&gt;     $query .= " ".key($HTTP_POST_VARS)." like '%".current($HTTP_POST_VARS)."%'";  // 쿼리문에 like 조건 절 삽입&lt;br /&gt;     $formcount--;   // n개의 조건이면 n-1만큼 and 절 삽입&lt;br /&gt;     if($formcount != 0) $query .= " and";   // n개의 조건이면 n-1만큼 and 절 삽입&lt;br /&gt;     next($HTTP_POST_VARS);  // POST 연관배열의 다음 값.. 계속해서 연관배열의 값을 조사하여 루프&lt;br /&gt;    }&lt;br /&gt;    else next($HTTP_POST_VARS);  // 연관배열의 현재 참조시 값이 없으면 다시 루프&lt;br /&gt;   }&lt;br /&gt;   $query .= " order by  ".$order;&lt;br /&gt;  }&lt;br /&gt;  else  $query = "select ".$attributes." from ".$tablename." order by ".$order;  // 폼에 값이 없을 때 기본 쿼리문&lt;/p&gt; &lt;p&gt;  return $query;  // 계산된 쿼리문 리턴&lt;br /&gt; }&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;-----------------------------------------------&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;그러니까 method가 post로 넘어온 폼은 $HTTP_POST_VARS에 저장된는데 이것을 처리해서 쿼리를 만들어내는 함수이다.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;폼에 여러 개의 textbox가 있을 때 or로 검색 가능하게 하는 것이지.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;문제는 textbox에 아무것도 들어있지 않아도 완전한 null이 아니라는 것이다.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;(그래서 count()를 해 보면 textbox나 기타 폼의 숫자만큼 count된다. 따라서 그만큼 루프.)&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;따라서 새로운 배열에 복사하는데 값이 ""(just like null ^^)가 아닐 때 current()를 사용하여 값을 복사.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;복사한 배열의 index가 0일 때는 where절이 붙지 않고&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;index가 n 일 때 n-1 만큼의 and 절이 붙는다.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;그래서 formcount를 계산하여 formcount가 n-1만큼 and절을 삽입한다.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;이것이 이 함수의 비법이다.&lt;/span&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;^^v&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-4733176205531036217?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/4733176205531036217/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040612-0341.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/4733176205531036217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/4733176205531036217'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040612-0341.html' title='[Naver Blog 2004/06/12 03:41] 자유롭게 검색할 수 있도록 폼에서 쿼리문 추출하기'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2064037480582937362</id><published>2007-03-31T20:27:00.000+09:00</published><updated>2007-03-31T20:31:04.792+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for PHP'/><title type='text'>[Naver Blog 2004/06/05 00:40] 아파치(apache) 사용자 인증창 안뜨기</title><content type='html'>&lt;p&gt;httpd.conf에&lt;/p&gt; &lt;p&gt;&lt;directory&gt;&lt;br /&gt;    Options FollowSymLinks&lt;br /&gt;    AllowOverride None&lt;br /&gt;    Allow from all  ##이 부분을 추가&lt;br /&gt;&lt;/directory&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;이것땜에 한참 고생했음..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2064037480582937362?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2064037480582937362/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040605-0040-apache.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2064037480582937362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2064037480582937362'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040605-0040-apache.html' title='[Naver Blog 2004/06/05 00:40] 아파치(apache) 사용자 인증창 안뜨기'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-5873655325565734001</id><published>2007-03-31T20:26:00.000+09:00</published><updated>2007-03-31T20:31:04.793+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for PHP'/><title type='text'>[Naver Blog 2004/05/25 06:05] Oracle과 여러가지 프로그래밍 연동(VB, VC, PHP, JSP, ASP 등등)</title><content type='html'>&lt;center&gt;&lt;img id="userImg6589195" style="" onclick="'popview(" src="http://blogfiles11.naver.net/data2/2004/5/25/74/%C1%A4%C0%BA%C0%CC.jpg" onload="'setTimeout(" /&gt;&lt;/center&gt; &lt;p align="center"&gt;정은아~ 낼 생일 축하~ ^^/&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;발표자료 땜시로 밤새 만들었네..&lt;/p&gt; &lt;p&gt;5시간 걸렸다.&lt;/p&gt; &lt;p&gt;개략적인 내용만 적혀있기 때문에 맛보기용으로 참조할 수 밖에 없고.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;그래도 기분이 썩 좋은 게 여러가지가 머릿속에서 한꺼번에 정리된다는 느낌이&lt;/p&gt; &lt;p&gt;밤샘 아침 기분과 어우러져서 흐뭇하네.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;오늘은 할 일이 많구먼..&lt;/p&gt; &lt;p&gt;오전엔 생일 선물 사야되구, 학교 갔다가 한시간동안 발표(강의야 이건.. 칫. ㅡㅡ+)하고&lt;/p&gt; &lt;p&gt;저녁엔 파티를... &lt;/p&gt; &lt;p&gt;녹초가 될 듯 싶다.&lt;/p&gt; &lt;p&gt;그래도.. 오늘 즐거운 흥분이 일어나길 바란다. ^^&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-5873655325565734001?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/5873655325565734001/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040525-0605-oracle-vb-vc.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5873655325565734001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5873655325565734001'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040525-0605-oracle-vb-vc.html' title='[Naver Blog 2004/05/25 06:05] Oracle과 여러가지 프로그래밍 연동(VB, VC, PHP, JSP, ASP 등등)'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2392095425884097539</id><published>2007-03-31T20:25:00.000+09:00</published><updated>2007-03-31T20:31:04.793+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for PHP'/><title type='text'>[Naver Blog 2004/05/15 01:35] PHP + Oracle 연동시 데이터 처리</title><content type='html'>&lt;p&gt;&lt;span style="color:#ff0000;"&gt;// 쿼리문을 받아서 출력하는 함수&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;// $query는 넘어온 쿼리문, $num_cols는 아직 안씀.. ㅡㅡ;;&lt;/span&gt;&lt;/p&gt; &lt;p&gt; function searchCustomer($query, $num_cols) {&lt;br /&gt;  global $conn;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;// $conn는 OCILogon()의 리턴된 접속인자&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt; &lt;/span&gt;&lt;span style="color:#003366;"&gt; $stmt = OCIParse($conn, $query);&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;// 쿼리를 파싱해서&lt;/span&gt;&lt;br /&gt;  OCIExecute($stmt);&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;//실행함..&lt;/span&gt;&lt;br /&gt;  echo "&lt;br /&gt;                        &lt;table border="\" cellspacing="\" bordercolordark="\" bordercolorlight="\" width="\" cellpadding="\"&gt;&lt;br /&gt;                            &lt;tr&gt;&lt;br /&gt;                                &lt;td width="\" bgcolor="\"&gt;&lt;br /&gt;                                    &lt;p align="\"&gt;&lt;span style="\"&gt;고객&lt;br /&gt;                                    번호&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;                                &lt;/td&gt;&lt;br /&gt;                                &lt;td width="\" bgcolor="\"&gt;&lt;br /&gt;                                    &lt;p align="\"&gt;&lt;span style="\"&gt;이름&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;                                &lt;/td&gt;&lt;br /&gt;                                &lt;td width="\" bgcolor="\"&gt;&lt;br /&gt;                                    &lt;p align="\"&gt;&lt;span style="\"&gt;전화번호&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;                                &lt;/td&gt;&lt;br /&gt;                                &lt;td width="\" bgcolor="\"&gt;&lt;br /&gt;                                    &lt;p align="\"&gt;&lt;span style="\"&gt;주소&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;                                &lt;/td&gt;&lt;br /&gt;                            &lt;/tr&gt;&lt;br /&gt;  ";&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;//여기까지는 그냥 테이블 헤더부분&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;//OCIFetchinto()는 파싱한 쿼리문을 배열로 넣어주는 함수&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;//더이상 넘길 것이 없을 때 0리턴&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;//$column 배열에 넘기므로 포인터인 &amp;$column으로 지정&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;//사실 처음 $num_cols를 받아서 컬럼수가 있는 만큼 하고 싶었지만&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;//일단 while로도 충분히 진행되므로 다음에 수정. ㅡㅡa&lt;/span&gt;&lt;/p&gt; &lt;p&gt;  while(OCIFetchInto($stmt, &amp;$column)) {&lt;br /&gt;   echo "                            &lt;tr&gt;";&lt;br /&gt;   echo "                                &lt;td width="\"&gt;";&lt;br /&gt;   echo "                                    &lt;p align="\"&gt;&lt;span style="\"&gt;".$column[0]."&lt;/span&gt;&lt;/p&gt;";&lt;br /&gt;   echo "                                &lt;/td&gt;";&lt;br /&gt;   echo "                                &lt;td width="\"&gt;";&lt;br /&gt;   echo "                                    &lt;p align="\"&gt;&lt;span style="\"&gt;".$column[1]."&lt;/span&gt;&lt;/p&gt;";&lt;br /&gt;   echo "                                &lt;/td&gt;";&lt;br /&gt;   echo "                                &lt;td width="\"&gt;";&lt;br /&gt;   echo "                                    &lt;p align="\"&gt;&lt;span style="\"&gt;".$column[2]."&lt;/span&gt;&lt;/p&gt;";&lt;br /&gt;   echo "                                &lt;/td&gt;";&lt;br /&gt;   echo "                                &lt;td width="\"&gt;";&lt;br /&gt;   echo "                                    &lt;p align="\"&gt;&lt;span style="\"&gt;".$column[3]."&lt;/span&gt;&lt;/p&gt;";&lt;br /&gt;   echo "                                &lt;/td&gt;";&lt;br /&gt;   echo "                            &lt;/tr&gt;";&lt;br /&gt;  }&lt;br /&gt;  echo "                     &lt;/table&gt;";&lt;br /&gt; }&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;span style="color:#ff0000;"&gt;//나머지는 그냥 이해될 거라 생각됨. ㅡㅡv&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2392095425884097539?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2392095425884097539/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040515-0135-php-oracle.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2392095425884097539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2392095425884097539'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040515-0135-php-oracle.html' title='[Naver Blog 2004/05/15 01:35] PHP + Oracle 연동시 데이터 처리'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-4589463191209786015</id><published>2007-03-31T20:23:00.000+09:00</published><updated>2007-03-31T20:31:04.794+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for PHP'/><title type='text'>[Naver Blog 2004/05/15 01:25] PHP + Oracle 연동시 초기 DB 접속 함수</title><content type='html'>&lt;p&gt;&lt;?php&lt;br /&gt;//DB 접속 함수&lt;br /&gt;function Oracleconnect($user="", $password="", $db="") {&lt;br /&gt; // Default 지정&lt;br /&gt; if (!$user) $user = "defaultUser";&lt;br /&gt; if (!$password) $password = "password";&lt;br /&gt; if (!$db) $db = "oracle9";&lt;/p&gt; &lt;p&gt; $conn = OCILogon($user, $password, $db);&lt;/p&gt; &lt;p&gt; // 접속인자 리턴, 접속 실패시 0 리턴&lt;br /&gt; if ($conn) return $conn;&lt;br /&gt; else return 0;&lt;br /&gt;}&lt;br /&gt;?&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;간단함.&lt;/p&gt; &lt;p&gt;OCI8 함수 중 OCILogon()를 사용.&lt;/p&gt; &lt;p&gt;OCILogon() 리턴값은 오라클 접속인자(현재 integer 인 듯 함. ㅡㅡ; 아직 정확히는..)&lt;/p&gt; &lt;p&gt;이후 그 리턴값인 conn은 계속 사용될 것임&lt;/p&gt; &lt;p&gt;OCIParse() 등등에서 사용됨.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-4589463191209786015?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/4589463191209786015/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040515-0125-php-oracle-db.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/4589463191209786015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/4589463191209786015'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040515-0125-php-oracle-db.html' title='[Naver Blog 2004/05/15 01:25] PHP + Oracle 연동시 초기 DB 접속 함수'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-3127787428398642955</id><published>2007-03-31T20:22:00.000+09:00</published><updated>2007-03-31T20:31:04.794+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P. Note for PHP'/><title type='text'>[Naver Blog 2004/05/11 22:53] WebLogic 8.1</title><content type='html'>&lt;p&gt;&lt;img id="userImg3743258" style="" onclick="'popview(" src="http://blogfiles11.naver.net/data2/2004/5/11/58/Untitled-1.jpg" onload="'setTimeout(" align="right" width="550" /&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt; &lt;p&gt;BEA의 WebLogic&lt;/p&gt; &lt;p&gt;EJB기반의 WebService Platform&lt;/p&gt; &lt;p&gt;게다가 IDE를 제공한다. 물론 자바기반이고.&lt;/p&gt; &lt;p&gt;지금까지는 EJB의 구조와 전반을 이해하는 것만으로 시간을 보내고 있음.&lt;/p&gt; &lt;p&gt;그나마 예전에 RMI 까지 했던 게 도움이 되는군.&lt;/p&gt; &lt;p&gt;EJB의 원격호출이 RMI를 확장해서 재편집한 것이어서..&lt;/p&gt; &lt;p&gt;정리가 되는 대로 하나 둘 올릴 예정.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;아싸~ 파이팅~&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;P.S 그나저나 네이버 블로그는 EJB기반일까나.. XML 구조를 봐서는 전혀 알 수가 없네.. ㅡㅡ&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-3127787428398642955?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/3127787428398642955/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040511-2253-weblogic-81.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3127787428398642955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3127787428398642955'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040511-2253-weblogic-81.html' title='[Naver Blog 2004/05/11 22:53] WebLogic 8.1'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2178662693461583636</id><published>2007-03-31T18:06:00.001+09:00</published><updated>2007-03-31T20:30:40.985+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2005/02/24 10:41] 내 블로그인데도 간만이네.. ㅡㅡa</title><content type='html'>&lt;p&gt;세월에 몸을 맞겨 그냥 흘러서 어느새 2월이 가고 있다.&lt;/p&gt; &lt;p&gt;서울 생활도, 직장 생활도 조금씩 적응되는 중이고.&lt;/p&gt; &lt;p&gt;스트레스가 제로인 나에게도 조금씩 스트레스라고 할 만한 것들이 생긴다.&lt;/p&gt; &lt;p&gt;뭐, 금방 녹아 사라지기도 하고 앙금처럼 남아 있기도 하다.&lt;/p&gt; &lt;p&gt;물살이 심하게 일어나지 않으면 앙금도 조금씩 뭍혀가겠지.&lt;/p&gt; &lt;p&gt;뿌옇게 보이지 않을 정도로 일어나기 전에 한번 갈아엎으면 사라질테고.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;조금씩 자신을 믿어나간다.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2178662693461583636?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2178662693461583636/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20050224-1041_31.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2178662693461583636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2178662693461583636'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20050224-1041_31.html' title='[Naver Blog 2005/02/24 10:41] 내 블로그인데도 간만이네.. ㅡㅡa'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2795101839182975958</id><published>2007-03-31T18:05:00.002+09:00</published><updated>2007-03-31T20:30:40.986+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2005/01/04 09:16] 2005년이 되긴 했는데..</title><content type='html'>&lt;p&gt;연말연초해서 무자게 바뻤다.&lt;/p&gt; &lt;p&gt;31일도 12시를 넘겨 1일 새벽 3시에 퇴근하구&lt;/p&gt; &lt;p&gt;다음날인 2일도 안산 LG백화점에 가구.. 번개 디버그 떔에 일하느라..&lt;/p&gt; &lt;p&gt;WOW도 별로 못해서 이제야 21렙임.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;새해엔 무언가 따듯한 마음과 뜨거운 열정으로 보내고 싶은데..&lt;/p&gt; &lt;p&gt;아직은 잘 모르겠다.&lt;/p&gt; 차차 알겠지&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2795101839182975958?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2795101839182975958/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20050104-0916-2005.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2795101839182975958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2795101839182975958'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20050104-0916-2005.html' title='[Naver Blog 2005/01/04 09:16] 2005년이 되긴 했는데..'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-7707750554028281491</id><published>2007-03-31T18:05:00.001+09:00</published><updated>2007-03-31T20:30:40.986+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/12/30 22:20] 진짜 연말이네..</title><content type='html'>&lt;p&gt;올 한해도 역시 빡세게 지나갔다.&lt;/p&gt; &lt;p&gt;그나마 다행인 건 연말이 되어서 조금씩 풀리기 시작했다는 것.&lt;/p&gt; &lt;p&gt;남는 것 보단 잃은 게 많은 한 해지만&lt;/p&gt; &lt;p&gt;하나님, 기도해주는 할머니, 좋은 친구들, 알게 모르게 도와주는 사람들 덕택에&lt;/p&gt; &lt;p&gt;어떻게, 어떻게 흐른 것 같다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;여전히 딱히 바라는 건 없지만&lt;/p&gt; &lt;p&gt;그냥 모두들 행복하길 빈다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;아직 죽지 않고 살아있으니..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-7707750554028281491?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/7707750554028281491/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041230-2220.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7707750554028281491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7707750554028281491'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041230-2220.html' title='[Naver Blog 2004/12/30 22:20] 진짜 연말이네..'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-8297439644592938015</id><published>2007-03-31T18:04:00.000+09:00</published><updated>2007-03-31T20:30:40.987+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/12/24 11:45] 크리스마스 전야파티 계획 불투명</title><content type='html'>&lt;p&gt;일단 나도 감기로 겔겔...&lt;/p&gt; &lt;p&gt;은숙이 어제 퍼져서 병원에 갔다 옴.&lt;/p&gt; &lt;p&gt;병수 오늘 약속 꺠졌다구 우울.. (것땜에 안된다구? 장냔햐? ㅡㅡ+)&lt;/p&gt; &lt;p&gt;민식이 근무.&lt;/p&gt; &lt;p&gt;수키도 기운 쇄진..&lt;/p&gt; &lt;p&gt;창우나 정은인 사태도 모르고 걍 지냄. ㅡㅡ;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;일단 심적 환자들 먼저 추스리고&lt;/p&gt; &lt;p&gt;정신적 환자는 치료 핑계 대구..&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;그냥 조촐함이 이렇게 힘들단 말이냐~&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;Oh, Santa~ Help us~~&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-8297439644592938015?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/8297439644592938015/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041224-1145.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8297439644592938015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8297439644592938015'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041224-1145.html' title='[Naver Blog 2004/12/24 11:45] 크리스마스 전야파티 계획 불투명'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-196436040597441811</id><published>2007-03-31T18:03:00.000+09:00</published><updated>2007-03-31T20:30:40.987+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/12/23 12:51] 아우.. 뒷골땡겨..</title><content type='html'>&lt;p&gt;그저께 밤 늦게 술먹구 퍼져 잔게 화근이었나..&lt;/p&gt; &lt;p&gt;어제 감기걸렸다.&lt;/p&gt; &lt;p&gt;기침, 두통, 오한, 몸살.. 종합선물세트.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;코딩은 계속 해야겠는데.. 글자가 자꾸 움직이는 것 처럼 보여서 진척이 늦다.&lt;/p&gt; &lt;p&gt;아프다기 보단... 헤롱헤롱..&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;낼 이븐데... 얼렁 나야지.. 츄~욱~&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;P.S 흐느적~&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-196436040597441811?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/196436040597441811/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041223-1251.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/196436040597441811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/196436040597441811'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041223-1251.html' title='[Naver Blog 2004/12/23 12:51] 아우.. 뒷골땡겨..'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-3512457863617237194</id><published>2007-03-31T18:02:00.000+09:00</published><updated>2007-03-31T20:30:40.987+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/12/22 11:40] 크억~ 랍스터~</title><content type='html'>&lt;p&gt;&lt;img id="userImg9834925" style="" onclick="popview(this.src)" src="http://blogfiles13.naver.net/data5/2004/12/22/300/lobster_1-icksishu.jpg" onload="'setTimeout(" align="left" width="550" /&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;어제 봄비(친구 이름이다. ㅡㅡ;) 만나서 좀 땡강부렸더니 랍스터를 사줬다.&lt;/p&gt; &lt;p&gt;코스로 먹었는데 랍스터 회랑 양념구이랑 전골이 차례로 등장.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;img id="userImg5051408" style="" onclick="popview(this.src)" src="http://blogfiles5.naver.net/data5/2004/12/22/212/lobster_2-icksishu.jpg" onload="'setTimeout(" width="550" /&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;젤 맛있는 부분은.. 양념구이에서 머리부분.. 뇌같은.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;담엔.. 돼지 양구이 먹음.&lt;/p&gt; &lt;p&gt;위다. ㅡㅡ&lt;/p&gt; &lt;p&gt;곱차이랑 맛은 비슷하나 좀 더 고기같다고 할까..&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;봄비네 집에 가서 맥주 한잔 더.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-3512457863617237194?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/3512457863617237194/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041222-1140.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3512457863617237194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3512457863617237194'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041222-1140.html' title='[Naver Blog 2004/12/22 11:40] 크억~ 랍스터~'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-1511005614527760792</id><published>2007-03-31T18:00:00.002+09:00</published><updated>2007-03-31T20:30:40.988+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/12/20 09:15] 와우 길드 가입했다..</title><content type='html'>&lt;p&gt;크...&lt;/p&gt; &lt;p&gt;태어나서 첨 길드라는 걸 가입. ㅡㅡ&lt;/p&gt; &lt;p&gt;30대 전후라는 게 눈에 띄어서 바로 가입..&lt;/p&gt; &lt;p&gt;잠깐 해 보다가 여러명 만나서 같이 해 보니까 더욱 재미가 쏠쏠~&lt;/p&gt; &lt;p&gt;이젠 진짜 빠져버리고 싶어~~&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-1511005614527760792?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/1511005614527760792/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041220-0915.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1511005614527760792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1511005614527760792'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041220-0915.html' title='[Naver Blog 2004/12/20 09:15] 와우 길드 가입했다..'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2162352783750871461</id><published>2007-03-31T18:00:00.001+09:00</published><updated>2007-03-31T20:30:40.988+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/12/18 06:40] 앞으로 10일... ㅡㅡ</title><content type='html'>&lt;p&gt;월급날까지 10일 남았다.&lt;/p&gt; &lt;p&gt;버티고 버텨서 그 때까지만..&lt;/p&gt; &lt;p&gt;연말에 성탄절도 꼈지만..&lt;/p&gt; &lt;p&gt;그렇지만..&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;만원 더... ㅡㅡ;;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2162352783750871461?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2162352783750871461/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041218-0640-10.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2162352783750871461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2162352783750871461'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041218-0640-10.html' title='[Naver Blog 2004/12/18 06:40] 앞으로 10일... ㅡㅡ'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-3976477092247732662</id><published>2007-03-31T17:58:00.000+09:00</published><updated>2007-03-31T20:30:40.989+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/12/14 20:15] 순식간이로구먼~</title><content type='html'>&lt;p&gt;어~ 하다 보니까 2주 가까이 지났다.&lt;/p&gt; &lt;p&gt;꼭 일땜에 바쁜 것 보다는 이것저것 사건들이 생기니까..&lt;/p&gt; &lt;p&gt;연말에 더 많은 일이 생길 지도 모르겠다.&lt;/p&gt; &lt;p&gt;돈은 없으니 뭐, 큰 일이 생기진 않겠지. ㅡㅡ&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;신제품 개발에 들어갔다.&lt;/p&gt; &lt;p&gt;문제는 이것들이 3가지나 되는데&lt;/p&gt; &lt;p&gt;어느 것 하나도 확실한 결정이 없다.&lt;/p&gt; &lt;p&gt;과장은 그냥 3개 다 가자고 해서 모두 개발할 거다.&lt;/p&gt; &lt;p&gt;다이렉트X를 사용한 화상 게임(아이토이같은..),&lt;/p&gt; &lt;p&gt;가위바위보(네트웍대전) 게임&lt;/p&gt; &lt;p&gt;바코드 센싱 마일리지 경품행사.&lt;/p&gt; &lt;p&gt;나한텐 뭐하나 만만한게 없다. Win32에 Borland C++이니..&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;모르겠다~&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;P.S WOW는 언제 상용화하나...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-3976477092247732662?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/3976477092247732662/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041214-2015.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3976477092247732662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3976477092247732662'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041214-2015.html' title='[Naver Blog 2004/12/14 20:15] 순식간이로구먼~'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-5406751439553238359</id><published>2007-03-31T17:50:00.000+09:00</published><updated>2007-03-31T20:30:40.989+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/12/04 11:07] 바람이 어디서 부는지 어디로 가는지..</title><content type='html'>&lt;span style="font-size: 12pt;"&gt; &lt;p&gt;사람은 바람이 어디서 부는지 어디로 가는지 알지 못한다.&lt;/p&gt; &lt;p&gt;다만 바람이 있다는 것만 알 수 있다.. 그리고 어느 방향인지만..&lt;/p&gt; &lt;p&gt;그러나 바람을 일으키는 이는 알고 있다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;때가 되면..&lt;/p&gt; &lt;p&gt;그 누구도 나를 잡지 못할 것 같다.&lt;/p&gt; &lt;p&gt;그 때가 아직은 아니지만, 언젠가 올 것을 안다.&lt;/p&gt; &lt;p&gt;그 기로에 섰을 때 누군가 나를 잡을 것인가, 그냥 흘러갈 것인가.. 알지 못한다.&lt;/p&gt; &lt;p&gt;다만 때가 되면 알 수 있을 걸..&lt;/p&gt;&lt;/span&gt;&lt;span style="font-size: 9pt;"&gt; &lt;p&gt; &lt;/p&gt;&lt;/span&gt;&lt;span style="font-size: 12pt;"&gt; &lt;p&gt;정한 때는 알 수 없으니 마냥 기다릴 뿐..&lt;/p&gt; &lt;p&gt;언제인지 알 수 없으니 계속 준비할 뿐..&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-5406751439553238359?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/5406751439553238359/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041204-1107_31.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5406751439553238359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5406751439553238359'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041204-1107_31.html' title='[Naver Blog 2004/12/04 11:07] 바람이 어디서 부는지 어디로 가는지..'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-8904578406680847248</id><published>2007-03-30T11:47:00.001+09:00</published><updated>2007-03-30T11:50:58.496+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/12/01 22:35] 퇴근후..</title><content type='html'>&lt;p&gt;어느새 겜방에 간다.&lt;/p&gt; &lt;p&gt;특히 늦게 퇴근해서 한 10시 반이면 그렇게 된다.&lt;/p&gt; &lt;p&gt;집에 가면 잘 일 밖에 없으니까.&lt;/p&gt; &lt;p&gt;(TV가 없어져서.. ㅡㅡ; 달랑 플스..)&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;WOW하려고 하는데 접속하는 데 대기자 440명...&lt;/p&gt; &lt;p&gt;섭에 접속할 때 대기자 150명..&lt;/p&gt; &lt;p&gt;ㅡㅡ&lt;/p&gt; &lt;p&gt;돈아깝지만 이거라도 해야 시간을 보낼 수 있는 듯..&lt;/p&gt; &lt;p&gt;돈도 떨어져가는데..&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;뭐, 어떻게 되겠지~&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-8904578406680847248?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/8904578406680847248/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041201-2235.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8904578406680847248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8904578406680847248'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041201-2235.html' title='[Naver Blog 2004/12/01 22:35] 퇴근후..'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-3592118362386281884</id><published>2007-03-30T11:46:00.000+09:00</published><updated>2007-03-30T11:50:58.504+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/11/30 13:25] 월급 명세서 나오다.. ㅡㅡ+</title><content type='html'>&lt;span style="font-family:verdana;"&gt; &lt;p&gt;2주 밖에 일을 안 했지만서도 무척이나 부족한 느낌이..&lt;/p&gt; &lt;p&gt;일단 지급 640003원.. (월급은 1200000)&lt;/p&gt; &lt;p&gt;이제 공제가..&lt;/p&gt; &lt;p&gt;연금 66150원, 의료보험 31570원, 고용보험 2880원&lt;/p&gt; &lt;p&gt;기타(아마 집세일 듯) 46000원..&lt;/p&gt; &lt;p&gt;공제합계액 146600원&lt;/p&gt; &lt;p&gt;결과적으로 493403원...&lt;/p&gt; &lt;p&gt; &lt;/p&gt;&lt;/span&gt;&lt;span style="font-size: 12pt;"&gt; &lt;/span&gt;&lt;p&gt;&lt;span style="font-size: 9pt;"&gt;벌써 36만원 썼다..&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size: 9pt;"&gt;이제 연말인데... 쪼들림이 보인다.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size: 9pt;"&gt;한달만 잘 버티면.... 1200000원 그대로~&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size: 9pt;"&gt;그럼 공제한다고 해도 1000000원은 남을테니..&lt;/span&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;&lt;span style="font-size: 9pt;"&gt;기운내라아~~&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-3592118362386281884?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/3592118362386281884/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041130-1325.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3592118362386281884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3592118362386281884'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041130-1325.html' title='[Naver Blog 2004/11/30 13:25] 월급 명세서 나오다.. ㅡㅡ+'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-8280144254660172747</id><published>2007-03-30T11:30:00.002+09:00</published><updated>2007-03-30T11:31:42.428+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/11/26 12:39] 바쁘다고 핑계는.. ㅡㅡ</title><content type='html'>&lt;p&gt;바쁘긴 바뻤다.&lt;/p&gt; &lt;p&gt;이번주 행사만 해도 3개나 있었고&lt;/p&gt; &lt;p&gt;대전 세이백화점은 요구사항이 까다로와서..&lt;/p&gt; &lt;p&gt;수욜 밤엔 밤새서 만들고.. 목요일까지 일하구.&lt;/p&gt; &lt;p&gt;그래도 빡씬 덕택에 빠르게 업무를 많이 이해했으니까..&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;어제는 태선이랑 압구정에서 좀 놀았는데..&lt;/p&gt; &lt;p&gt;역시 서울 술값은 비싸더라구.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;오늘은 금요일~&lt;/p&gt; &lt;p&gt;저녁부터는 휴일~&lt;/p&gt; &lt;p&gt;아싸~&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-8280144254660172747?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/8280144254660172747/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041126-1239.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8280144254660172747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8280144254660172747'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041126-1239.html' title='[Naver Blog 2004/11/26 12:39] 바쁘다고 핑계는.. ㅡㅡ'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-7665463815737302788</id><published>2007-03-30T11:30:00.001+09:00</published><updated>2007-03-30T11:31:42.429+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/11/22 19:00] 야근이라..</title><content type='html'>&lt;p&gt;다들 퇴근했다.&lt;/p&gt; &lt;p&gt;앞으로 계속 야근하기로 했다.&lt;/p&gt; &lt;p&gt;뭐, 별로 할 것도 없고.&lt;/p&gt; &lt;p&gt;뭔 약속 있는 거 아니면야.. ^^&lt;/p&gt; &lt;p&gt;지하철로 퇴근하는건 1850원,&lt;/p&gt; &lt;p&gt;집에가서 밥사먹는건 4-5000원.&lt;/p&gt; &lt;p&gt;훨씬 남는 장사다. ㅡㅡ&lt;/p&gt; &lt;p&gt;쿠훗~&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-7665463815737302788?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/7665463815737302788/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041122-1900.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7665463815737302788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7665463815737302788'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041122-1900.html' title='[Naver Blog 2004/11/22 19:00] 야근이라..'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-6599838422519486098</id><published>2007-03-30T11:29:00.001+09:00</published><updated>2007-03-30T11:31:42.429+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/11/20 00:48] 일주일 내내 별일 없다가.. 쿡...</title><content type='html'>&lt;p&gt;일찍 퇴근해서 청주가려는 금요일.&lt;/p&gt; &lt;p&gt;아무생각 없는 내게도 무언가 일이 터졌다.&lt;/p&gt; &lt;p&gt;롯데백화점 경품 이벤트를 갑자기 한다는 것.&lt;/p&gt; &lt;p&gt;족구 한판 하고 자리에 앉아있으니까 컴터 네 대가 도착했다.&lt;/p&gt; &lt;p&gt;참고로 내 사수는 말레이시아로 출장갔다.&lt;/p&gt; &lt;p&gt;1월달에나 온다나.. ㅡㅡ;&lt;/p&gt; &lt;p&gt;어제 인수인계해 준다고 한 두시간 동안 무언가 들었는데&lt;/p&gt; &lt;p&gt;사실 그걸 다 머리속에 집어넣지는 못했다.&lt;/p&gt; &lt;p&gt;어쨋든....&lt;/p&gt; &lt;p&gt;그냥 로또 경품행사겠거니 하고 DB서버, 클라이언트, 예비용 서버등 셋팅 완료.&lt;/p&gt; &lt;p&gt;6시에 가져간다고 해서 4시 반부터 소스코드 이해하기나 하고 있었다..&lt;/p&gt; &lt;p&gt;시스템부에서 6시가 넘도록 장비를 가지러 오지도 않고...&lt;/p&gt; &lt;p&gt;행사 스펙이라고 준 것도 ppt 한 페이지 짜리.. ㅡㅡ&lt;/p&gt; &lt;p&gt;그것도 6시에 왔다.&lt;/p&gt; &lt;p&gt;6시 반이 되어서 행사내용을 듣고..&lt;/p&gt; &lt;p&gt;결국 소스코드 수정에 들어갔다.&lt;/p&gt; &lt;p&gt;어찌어찌 바쁘게 하다보니 10시...&lt;/p&gt; &lt;p&gt;막판 수정까지 10시 반...&lt;/p&gt; &lt;p&gt;청주가는 건 무리.. ㅡㅡ&lt;/p&gt; &lt;p&gt;월욜부터 목욜까지 한 일보다 금욜 밤에 한 일의 양이 훨씬 많다니..&lt;/p&gt; &lt;p&gt;뭐, 첨엔 그런거지 하면서 넘어간다.. 쯧..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-6599838422519486098?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/6599838422519486098/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041120-0048.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/6599838422519486098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/6599838422519486098'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041120-0048.html' title='[Naver Blog 2004/11/20 00:48] 일주일 내내 별일 없다가.. 쿡...'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-8423758886070468713</id><published>2007-03-30T11:28:00.002+09:00</published><updated>2007-03-30T11:31:42.430+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/11/19 11:20] 드디어 금요일~~</title><content type='html'>&lt;p&gt;저녁엔 청주에 가야지.&lt;/p&gt; &lt;p&gt;은숙이가 뭔 영화를 보자고 하는데.. 가자마자 바로 보고.. 흐음..&lt;/p&gt; &lt;p&gt;그나저나 잠은 어디서 자나..&lt;/p&gt; &lt;p&gt;현재 있는 소스코드 이해하는 것만해도 며칠 걸릴 듯.&lt;/p&gt; &lt;p&gt;그거 수정하고 회사 행사 있을 때 셋팅하고 하는 게 내 일.&lt;/p&gt; &lt;p&gt;어여 몇 달 지나서 이것저것 생필품을 사야할텐데..&lt;/p&gt; &lt;p&gt;그동안 계속 궁색하겠네~&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-8423758886070468713?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/8423758886070468713/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041119-1120.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8423758886070468713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8423758886070468713'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041119-1120.html' title='[Naver Blog 2004/11/19 11:20] 드디어 금요일~~'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-1448405620834115646</id><published>2007-03-30T11:28:00.001+09:00</published><updated>2007-03-30T11:31:42.430+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/11/17 09:01] 아우우우... 안깨네..</title><content type='html'>&lt;p&gt;회식이라구 한잔한게... 무지 먹은 듯..&lt;/p&gt; &lt;p&gt;출근하는데 술이 안꺠서 어떻게 했는지 모름.&lt;/p&gt; &lt;p&gt;그래도 와보니 책상이군.&lt;/p&gt; &lt;p&gt;술깨면 수정.. ㅡㅡv&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;P.S 회식자리서 재떨이 한통 먹음.. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-1448405620834115646?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/1448405620834115646/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041117-0901.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1448405620834115646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/1448405620834115646'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041117-0901.html' title='[Naver Blog 2004/11/17 09:01] 아우우우... 안깨네..'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-7685808868103224142</id><published>2007-03-30T11:27:00.001+09:00</published><updated>2007-03-30T11:31:42.430+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/11/16 12:42] 신입사원 백세민~!</title><content type='html'>&lt;p&gt;취직했다.&lt;/p&gt; &lt;p&gt;오늘이 두번째 근무일.&lt;/p&gt; &lt;p&gt;회사 사이트는 &lt;a target="_blank" class="con_link" href="http://www.exnet.co.kr/"&gt;www.exnet.co.kr&lt;/a&gt;이고 난 소프트웨어 연구개발팀.&lt;/p&gt; &lt;p&gt;사원아파트라고 갔더만... 자취방이다. &lt;/p&gt; &lt;p&gt;룸메이트도 둘 더 있는데 집 안은 환상적인 환경을 제공한다.&lt;/p&gt; &lt;p&gt;뭐든지 다 밟힌다. ㅡㅡv&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;한번도 쓰지 않았던 borland C++ builder를 쓰고 하드웨어 레벨의 프로그래밍을 해야 할 듯.&lt;/p&gt; &lt;p&gt;일이야 어느 정도 되겠지만 이쁜 여직원이 있으려나.. ㅡㅡ;&lt;/p&gt; &lt;p&gt;아직 사람들도 잘 모른다.&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;시작은 언제나 작지만 끝은 알 수가 없으니.. ^^&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-7685808868103224142?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/7685808868103224142/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041116-1242.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7685808868103224142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/7685808868103224142'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20041116-1242.html' title='[Naver Blog 2004/11/16 12:42] 신입사원 백세민~!'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-8872423478451738958</id><published>2007-03-30T11:26:00.000+09:00</published><updated>2007-03-30T11:31:42.431+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/07/16 19:29] 인턴 끝~</title><content type='html'>&lt;p&gt;오늘부로 끝이다. ㅡㅡv&lt;/p&gt; &lt;p&gt;웹빌더도 다 마쳤다.&lt;/p&gt; &lt;p&gt;아쉬운 생각 전혀 없다.&lt;/p&gt; &lt;p&gt;좋지 않은 기억이 많지만 다 좋은 기억으로 바꿀거다.&lt;/p&gt; &lt;p&gt;(사장같은 인간은 역시 근처에 두면 안된다는 거 확실. ㅡㅡ+)&lt;/p&gt; &lt;p&gt;몸으로 때우면서 상승한 내공이 있고, 약간의 아이디어도 얻었다.&lt;/p&gt; &lt;p&gt;일하면서 피곤한 건 느껴지지 않았다. 결국 난 프로그래머인게 판명났다. T-T&lt;/p&gt; &lt;p&gt;쉬긴 그렇고 계속 일자리 찾아야지.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-8872423478451738958?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/8872423478451738958/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040716-1929.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8872423478451738958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8872423478451738958'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040716-1929.html' title='[Naver Blog 2004/07/16 19:29] 인턴 끝~'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-5364979472163849577</id><published>2007-03-30T11:25:00.000+09:00</published><updated>2007-03-30T11:31:42.432+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/07/15 13:18] 오늘은 울 형 생일..</title><content type='html'>&lt;p&gt;그러고보니까 형 사진이 파일로 없네.. ㅡㅡ;&lt;/p&gt; &lt;p&gt;생일 선물로 홈피 만들어줬다.&lt;/p&gt; &lt;p&gt;&lt;a target="_blank" class="con_link" href="http://gareon.ivyro.net/"&gt;http://gareon.ivyro.net&lt;/a&gt;&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;환경은 php4, mysql 3.xx, linux, apache, phpbb2.0.9&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;형 생일축하해~~ &lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;P.S 요새는 호스팅 이용료가 무척 싸더군.. ㅡㅡb&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-5364979472163849577?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/5364979472163849577/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040715-1318.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5364979472163849577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/5364979472163849577'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040715-1318.html' title='[Naver Blog 2004/07/15 13:18] 오늘은 울 형 생일..'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-8023766692910586869</id><published>2007-03-30T11:24:00.001+09:00</published><updated>2007-03-30T11:25:20.719+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/07/12 10:13] 종이로 시디케이스 접는 법..!!</title><content type='html'>&lt;center&gt;&lt;img id="userImg8956824" style="" onclick="'popview(" src="http://blogfiles16.naver.net/data2/2004/7/7/271/dooki56169.jpg" onload="'setTimeout(" width="550" /&gt;&lt;/center&gt; &lt;p align="center"&gt;더블 시디도 넣을 수 있다.&lt;/p&gt; &lt;p align="center"&gt; &lt;/p&gt; &lt;p align="center"&gt;실제로 접어 봤는데,&lt;/p&gt; &lt;p align="center"&gt; &lt;/p&gt; &lt;p align="center"&gt;시디 잘 들어간다.&lt;/p&gt; &lt;p align="center"&gt; &lt;/p&gt; &lt;p align="center"&gt; &lt;/p&gt; &lt;p align="center"&gt;종종 요긴하게 쓰일 듯.&lt;br /&gt;&lt;/p&gt; &lt;p align="center"&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-8023766692910586869?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/8023766692910586869/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040712-1013.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8023766692910586869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8023766692910586869'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040712-1013.html' title='[Naver Blog 2004/07/12 10:13] 종이로 시디케이스 접는 법..!!'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-2105204912304475712</id><published>2007-03-30T11:23:00.001+09:00</published><updated>2007-03-30T11:25:20.720+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/07/09 10:07] 삼국지 10 !!!~~~~</title><content type='html'>&lt;center&gt;&lt;img id="userImg7895675" style="" onclick="'popview(" src="http://blogfiles10.naver.net/data2/2004/7/9/201/%BB%EF%B1%B9%C1%F610-4312.jpg" onload="'setTimeout(" width="550" /&gt;&lt;/center&gt; &lt;p&gt;&lt;br /&gt;나왔다는 소식은 진작에 들었는데 어제 해 봤다.&lt;/p&gt; &lt;p&gt;재미있다... T-T  지금까지 것들 중에 가장 잘 만들었다.&lt;/p&gt; &lt;p&gt;누가 폰트를 패치해서 한자를 한글로 나오게 했다.&lt;/p&gt; &lt;p&gt;할만하게 되었지.&lt;/p&gt; &lt;p&gt;10월달에 한글판으로 정발된다지만... 걍 이거 할란다.&lt;/p&gt; &lt;p&gt;혹시 필요한 사람은 내 ftp 계정을 알려주겠음. ㅡㅡb&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-2105204912304475712?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/2105204912304475712/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040709-1007-10.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2105204912304475712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/2105204912304475712'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040709-1007-10.html' title='[Naver Blog 2004/07/09 10:07] 삼국지 10 !!!~~~~'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-9066110807368582914</id><published>2007-03-30T11:22:00.000+09:00</published><updated>2007-03-30T11:25:20.720+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/07/07 11:09] 원숭이 똥꼬는 빨개~</title><content type='html'>&lt;center&gt;&lt;img id="userImg423375" style="" onclick="'popview(" src="http://blogfiles4.naver.net/data2/2004/7/7/115/loipy_48.jpg" onload="'setTimeout(" /&gt;&lt;/center&gt; &lt;p&gt;&lt;br /&gt;어제 샤워 도중 내 엉덩이를 보고 놀랐다.. ㅜㅜ&lt;/p&gt; &lt;p&gt;원숭이 똥꼬급 땀띠가... 붉게.. 헉..&lt;/p&gt; &lt;p&gt;울고싶다... 이거 직업병이잖어..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-9066110807368582914?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/9066110807368582914/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040707-1109.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/9066110807368582914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/9066110807368582914'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040707-1109.html' title='[Naver Blog 2004/07/07 11:09] 원숭이 똥꼬는 빨개~'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-3342279759475023316</id><published>2007-03-30T11:16:00.001+09:00</published><updated>2007-03-30T11:25:20.721+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/07/06 21:29] 정보처리기사 실기 봤다.</title><content type='html'>&lt;p&gt;어제 예의상 공부해 줬는데 간만에 C 프로그래밍을 했더니 즐거웠다.&lt;/p&gt; &lt;p&gt;^^a&lt;/p&gt; &lt;p&gt;한 두어시간 보고 오늘 셤 봤는데..&lt;/p&gt; &lt;p&gt;순식간에 끝남..&lt;/p&gt; &lt;p&gt;요새 밥먹고 프로그래밍만 했더니 그냥그냥이더군.&lt;/p&gt; &lt;p&gt;게다가 내가 딱 한번 본 소스가 거의 그대로 문제로 나와서 가뿐하게 끝.&lt;/p&gt; &lt;p&gt;근데 주성대 버스 진짜 안오더군.&lt;/p&gt; &lt;p&gt;어케 거서 학교를 다니는지.. 참 안쓰럽네..&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;지금도 회사에서 신나게 PHP코딩하는중.&lt;/p&gt; &lt;p&gt;PHP보다는 레이어하고 필사전을 했지만..&lt;/p&gt; &lt;p&gt;이젠 다시 틈틈히 고민할 거 고민해야지..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-3342279759475023316?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/3342279759475023316/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040706-2129.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3342279759475023316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/3342279759475023316'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040706-2129.html' title='[Naver Blog 2004/07/06 21:29] 정보처리기사 실기 봤다.'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-8239766481599572358</id><published>2007-03-30T11:15:00.001+09:00</published><updated>2007-03-30T11:25:20.721+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/07/02 17:26] YBM시사닷컴, '아머드 코어 넥서스' 초회판 예약판매!!!</title><content type='html'>&lt;center&gt;YBM시사닷컴 게임사업부(&lt;a class="con_link" href="http://www.ybmgame.co.kr/" target="_blank"&gt;&lt;span style="color:blue;"&gt;www.ybmgame.co.kr&lt;/span&gt;&lt;/a&gt;)는 FromSoftware사의 “아머드 코어 넥서스” 초회판 예약판매를 오는 7월 5일 오전 11시부터 YBM시사닷컴, 롯데닷컴,  CJmall, Hmall, 게임투바이, 게임몰 등 주요 온라인 쇼핑몰에서 동시 실시한다. &lt;p style="line-height: 150%;" align="justify"&gt;  7월 29일 발매 예정인 “아머드 코어 넥서스”는 아머드 코어 시리즈의 대표 미션을 리메이크한 레볼루션 디스크와 신규 미션인 에볼루션 디스크로 구성되어 있으며 초회판에는 “아머드 코어 플레이스테이션 캐리어”가 포함된다. &lt;/p&gt; &lt;p style="line-height: 150%;" align="justify"&gt;  3D메카닉 액션게임인 "아머드 코어"의 최신작 “아머드 코어 넥서스”는 시리즈 사상 최초로 한국 특전기체 및 엠블렘이 포함되었으며, 이번 특전 기체 포함으로 “아머드 코어”를 처음 접하는 유저들도 보다 쉽게 아머드 코어를 접할 수 있게 되었다.(게임시작부터 기관총 난사!!!와 고화력 포의 사용이 가능하다!!!!!)특전 기체명은 유저 공모를 통해 “쥬신”(경량형), “치우천왕”으로 선정되었다. 네트웍 대전 또한 가능하다. &lt;/p&gt; &lt;p style="line-height: 150%;" align="justify"&gt;  1,000개 한정인 “아머드 코어 넥서스” 초회판 가격은 65,000원으로, 예약 구매자에게는 예약특전인 A4사이즈 100page 분량의 특별 화보집이 증정되며 예약 판매 기간은 7월 5일부터 7월 26일까지이다.&lt;/p&gt;&lt;/center&gt; &lt;center&gt; &lt;/center&gt; &lt;center&gt;&lt;img id="userImg9612108" style="" onclick="'popview(" src="http://blogfiles13.naver.net/data1/2004/7/2/220/ac_nex02.jpg" onload="'setTimeout(" /&gt;&lt;/center&gt; &lt;center&gt;아머드 코어 넥서스 자켓&lt;/center&gt;&lt;br /&gt;&lt;center&gt;&lt;img id="userImg6424292" style="" onclick="'popview(" src="http://blogfiles6.naver.net/data2/2004/7/2/117/ac_nex01.jpg" onload="'setTimeout(" width="550" /&gt;&lt;/center&gt; &lt;center&gt;아머드 코어  초회판 이미지 &lt;/center&gt;&lt;br /&gt;&lt;center&gt;&lt;img id="userImg7796450" style="" onclick="'popview(" src="http://blogfiles14.naver.net/data1/2004/7/2/77/ac_nex03.jpg" onload="'setTimeout(" width="550" /&gt;&lt;/center&gt; &lt;center&gt;아머드 코어 넥서스 PS2 캐리어 이미지 &lt;/center&gt; &lt;center&gt; &lt;/center&gt; &lt;div align="left"&gt; &lt;/div&gt; &lt;div align="left"&gt;우째쓸까~~ 무지 갖고 싶어지네..&lt;/div&gt; &lt;div align="left"&gt;근데 돈은 어디서 나냐...&lt;/div&gt; &lt;div align="left"&gt;칫... 꼭 예약하고 말겠다..&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-8239766481599572358?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/8239766481599572358/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040702-1726-ybm.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8239766481599572358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/8239766481599572358'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040702-1726-ybm.html' title='[Naver Blog 2004/07/02 17:26] YBM시사닷컴, &apos;아머드 코어 넥서스&apos; 초회판 예약판매!!!'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-20223428562583923</id><published>2007-03-30T11:14:00.000+09:00</published><updated>2007-03-30T11:25:20.722+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/06/18 13:02] Hitel RPG 동호회..</title><content type='html'>&lt;p&gt;그냥 생각나서 한번 가 봤다.&lt;/p&gt; &lt;p&gt;역시나... 2003년 9월 WOC 팀(구 뱀프극단)의 공지를 마지막으로 활동이 없군..&lt;/p&gt; &lt;p&gt;세월이 흐르면 세상이 바뀌는 걸 구시대 인간들은 그냥 사라질 수 밖에..&lt;/p&gt; &lt;p&gt;구시대 인간들 중에서도 나름대로 묘책이 있을텐데..&lt;/p&gt; &lt;p&gt;나이가 뭔지.. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-20223428562583923?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/20223428562583923/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040618-1302-hitel-rpg.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/20223428562583923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/20223428562583923'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040618-1302-hitel-rpg.html' title='[Naver Blog 2004/06/18 13:02] Hitel RPG 동호회..'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-29738970.post-4448842905780832402</id><published>2007-03-30T11:13:00.002+09:00</published><updated>2007-03-30T11:25:20.722+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='얘기꺼리'/><title type='text'>[Naver Blog 2004/06/16 13:05] 인턴사원..</title><content type='html'>&lt;center&gt;&lt;img id="userImg6875912" style="" onclick="'popview(" src="http://blogfiles14.naver.net/data2/2004/6/16/109/%C1%A6%B8%F1_%BE%F8%C0%BD.jpg" onload="'setTimeout(" /&gt;&lt;/center&gt; &lt;p align="center"&gt;&lt;br /&gt;언제해도 즐거운 게임이다. ^^&lt;/p&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;이달 말부터 인턴사원으로 갈 듯 하다.&lt;/p&gt; &lt;p&gt;밤낮 PHP 코딩만 할 지 모르겠다.&lt;/p&gt; &lt;p&gt;최악의 상황이겠지.&lt;/p&gt; &lt;p&gt;정시 퇴근을 위해 으쌰~&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/29738970-4448842905780832402?l=sam-jv.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sam-jv.blogspot.com/feeds/4448842905780832402/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040616-1305.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/4448842905780832402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/29738970/posts/default/4448842905780832402'/><link rel='alternate' type='text/html' href='http://sam-jv.blogspot.com/2007/03/naver-blog-20040616-1305.html' title='[Naver Blog 2004/06/16 13:05] 인턴사원..'/><author><name>Samuel</name><uri>http://www.blogger.com/profile/18326591820717088420</
