Posted
Filed under JSP, JAVA
[원문] : http://ir.bagesoft.com/640
Daemon
이란 백그라운드로 실행되면서, 사용자의 인터페이스(tty)가 없는 프로그램을 말한다. 우리가 흔히 사용하는 리눅스 서비스들은 대부분 데몬으로 동작하며, -d로 끝나는 프로그램(예: sshd, syslogd)이 모두 해당된다. 리눅스 명령인 nohup으로 백그라운드 구동은 가능하지만, kill 명령으로 종료해야 한다.
따라서 비정상 종료시의 처리를 하려면, OS로부터 signal을 받아야 하므로 데몬으로 구동시켜야 한다.
Apache Commons Daemon에서 제공하는 Jsvc를 이용하여, 간단한 데몬 프로그램을 작성해 보자.
(우리가 잘 알고 있는 Tomcat도 Jsvc를 이용하여, 데몬으로 프로세스를 실행한다고 한다.)
1. Jsvc 실행파일 생성
이미 컴파일된 Jsvc를 다운로드할 수는 있지만, 실제로 받아서 실행해 보면 에러를 출력하므로, 직접 컴파일하여야 한다.
Linux(CentOS 5.5)에 /opt/jdk1.6.0_24/에 JAVA를 설치했다고 가정한다.
mkdir /root/commons-daemon
cd /root/commons-daemon
wget http://www.apache.org/dist/commons/daemon/binaries/1.0.5/commons-daemon-1.0.5.jar
wget http://mirror.apache-kr.org//commons/daemon/source/commons-daemon-1.0.5-src.tar.gz
tar zxvf commons-daemon-1.0.5-src.tar.gz
cd commons-daemon-1.0.5-src/src/native/unix/
support/buildconf.sh
./configure --with-java=/opt/jdk1.6.0_24/
make
mv jsvc /root/commons-daemon
위와 같이 실행하면, 작업할 경로(/root/commons-daemon)에 jar와 jsvc파일이 생성되어 있을 것이다.

2. 실행할 JAVA 클래스 작성
jsvc에 의해서 실행되는 JAVA 클래스는 Daemon 인터페이스를 구현해야 한다. 또한 스레드로 실행되어야 하므로, Runnable도 구현해야 한다. 만약 스레드로 구동하지 않을 경우, 종료처리가 제대로 되지 않으며, "Service exit with a return value of 143"라는 오류를 표시할 것이다.
테스트를 위해, 1초마다 숫자를 하나씩 증가시키면서 찍는 프로그램을 JAVA로 아래와 같이 만들었다.
TestDaemon.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.bagesoft.test.daemon;
import org.apache.commons.daemon.Daemon;
import org.apache.commons.daemon.DaemonContext;
import org.apache.commons.daemon.DaemonInitException;
public class TestDaemon implements Daemon, Runnable {
private String status = "";
private int no = 0;
private Thread thread = null;
@Override
public void init(DaemonContext context) throws DaemonInitException,
Exception {
System.out.println("init...");
String[] args = context.getArguments();
if (args != null) {
for (String arg : args) {
System.out.println(arg);
}
}
status = "INITED";
this.thread = new Thread(this);
System.out.println("init OK.");
System.out.println();
}
@Override
public void start() {
System.out.println("status: " + status);
System.out.println("start...");
status = "STARTED";
this.thread.start();
System.out.println("start OK.");
System.out.println();
}
@Override
public void stop() throws Exception {
System.out.println("status: " + status);
System.out.println("stop...");
status = "STOPED";
this.thread.join(10);
System.out.println("stop OK.");
System.out.println();
}
@Override
public void destroy() {
System.out.println("status: " + status);
System.out.println("destroy...");
status = "DESTROIED";
System.out.println("destroy OK.");
System.out.println();
}
@Override
public void run() {
while (true) {
System.out.println(no);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (no > 1000) {
break;
}
no++;
}
}
}
위의 클래스를 jar로 묶어서 BageSoft.jar 라는 파일을 만들고 작업경로(/root/commons-daemon/)에 저장했다.
3. JAVA를 실행할 쉘스크립트 작성
쉘스크립트를 작성할 때, 위에서 다운 받아서 압축 풀었던 위치(commons-daemon-1.0.5-src/src/samples)에서 ServiceDaemon.sh를 참고하면 된다.
아래에서 $DAEMON_HOME은 작업 경로를 의미한다.
나중에 디버깅의 편의성 때문에 에러 출력을 표준출력과 같은 파일에 저장하도록 했다.
TestDaemon.sh
#!/bin/sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
JAVA_HOME=/opt/jdk1.6.0_24
JSVC=/root/commons-daemon/jsvc
USER=root
DAEMON_HOME=/root/commons-daemon
PID_FILE=$DAEMON_HOME/daemon.pid
OUT_FILE=$DAEMON_HOME/daemon.out
#ERR_FILE=$DAEMON_HOME/daemon.err
CLASSPATH=\
$DAEMON_HOME/commons-daemon-1.0.5.jar:\
$DAEMON_HOME/BageSoft.jar
MAIN_CLASS=com.bagesoft.test.daemon.TestDaemon
case "$1" in
start)
#
# Start Daemon
#
rm -f $OUT_FILE
$JSVC \
-user $USER \
-java-home $JAVA_HOME \
-pidfile $PID_FILE \
-outfile $OUT_FILE \
-errfile $OUT_FILE \
-cp $CLASSPATH \
$MAIN_CLASS
#
# To get a verbose JVM
#-verbose \
# To get a debug of jsvc.
#-debug \
exit $?
;;
stop)
#
# Stop Daemon
#
$JSVC \
-stop \
-nodetach \
-java-home $JAVA_HOME \
-pidfile $PID_FILE \
-outfile $OUT_FILE \
-errfile $OUT_FILE \
-cp $CLASSPATH \
$MAIN_CLASS
exit $?
;;
*)
echo "[Usage] TestDaemon.sh start | stop"
exit 1;;
esac
4. 실행/종료
실행
/root/commons-daemon/TestDaemon.sh start

로그를 남기도록 몇초 기다리고....
종료
/root/commons-daemon/TestDaemon.sh stop
제대로 처리 되는지는 daemon.out의 내용을 확인하면 된다.
init(), start(), stop(), destroy()가 모두 수행되면 정상이다.
아래는 start 후 10초 후에 stop 했을 때의 daemon.out의 내용이다.
init... init OK. status: INITED start... start OK. 0 1 2 3 4 5 6 7 8 9
status: STARTED stop... stop OK. status: STOPED destroy... destroy OK.

2012/12/12 09:09 2012/12/12 09:09
Posted
Filed under JSP, JAVA
jstl,<c:set name="" value="" scope="page" />
c:set은 기본으로 page스코프 이며 생략 되어 사용 가능 .
request 스코프를 사용해야 foward 했을때 값을 넘길 수 있음

default -scope : page <---

2011/03/22 21:33 2011/03/22 21:33
Posted
Filed under JSP, JAVA
여러개의 List 를 가지고 있는 Map 객체를 JSTL에서 처리하는 예.
        <c:forEach items="${serviceGroupMap}" var="serviceGroupListMap">
        <div id="${fn:replace(fn:replace(serviceGroupList.key, ' ',''),'&','')}">
            <div class="toolbar">
                <h1>${serviceGroupListMap.key}</h1>
                <a class="button back" href="#">Back</a>
            </div>
            <ul class="edgetoedge">
                <c:forEach items="${serviceGroupListMap.value}" var="serviceGroup">
                <li class="arrow"><a id="0" href="systems.html">
                <span class="severity${serviceGroup.severity }">&nbsp;&nbsp;</span>
                <span>${serviceGroup.name}</span>
                </a></li>
                </c:forEach>
            </ul>
        </div>
        </c:forEach>

기타 JSTL 관련 참조 http://www.cs.wcupa.edu/rkline/Java/jstl-examples.html
2011/03/22 21:03 2011/03/22 21:03
Posted
Filed under JSP, JAVA
  • ageScope page scope 의 변수들
    requestScope request scope 의 변수들
    sessionScope session scope 의 변수들
    applicationScope application scope 의 변수들
    param parameter 변수들 문자열
    paramValues parameter 변수들 문자열 배열
    header HTTP request 헤더
    headerValues HTTP request 헤더 문자열 배열
    initParam 컨텍스트 초기 변수 web.xml 에서 지정
    cookie 쿠키 변수들
    pageContext 현재 페이지의 pageContext 객체

EL 연산자

  • 연산자 구분 연산자
    관계 < lt > gt <= le >= ge == eq != ne
    산술 + - * / div % mod
    논리 && and || or ! not
    Empty empty

-연산자들간의 우선순위는 다음과 같다.
1. [] .
2. ()
3. - (단항) not ! empty
4. * / div % mod
5. + - (이항)
6. < > <= >= lt gt le ge
7. == != eq ne
8. && and
9. || or

2011/03/22 20:05 2011/03/22 20:05
Posted
Filed under JSP, JAVA
input type="test"
 --> ${param.identifier} OR ${param["identifier"]}

=================================
input type="checkbox" 다중
${paramValues.identifier[0]}
${paramValues.identifier[1]}


${paramValues.identifier[2]}

2011/03/22 19:58 2011/03/22 19:58
Posted
Filed under JSP, JAVA


 JSTL예제(c:forEach),(구구단)  수업  2006/09/28 12:42

 http://blog.naver.com/kabsa22/130009281235


<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- 포맷 라이브러리를 위한 taglib선언 -->
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!-- 엡 브라우저에서 전달한 메세지가 euc-kr로 인코딩되어 있다는 것을 알려준다. -->
<fmt:requestEncoding value="euc-kr"/>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
  <title>헤더 정보들</title>
 </head>
 <body>
  <h1>헤더 정보들</h1>
<!--헤더 정보들을 아이템으로 지정하고 아이템을 하나씩 추출해서forEach문으로 반복문 수행-->
  <c:forEach var="h" items="${ header }">
  <!-- 헤더이름을  key값으로 출력 -->
   <li><c:out value="${ h.key }"/> :
  <!-- 헤더값을 출력 -->
   <c:out value="${ h. value }"/>
  </c:forEach>
 </body>
</html>

===============================================================================

구구단

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- 포맷 라이브러리를 위한 taglib선언 -->
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!-- 엡 브라우저에서 전달한 메세지가 euc-kr로 인코딩되어 있다는 것을 알려준다. -->
<fmt:requestEncoding value="euc-kr"/>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
  <title>구구단</title>
 </head>
 <body>
  <h1 align=center>구구단</h1>
  <!-- t라는 이름으로 전달되는 파라미터의 값을 변수 t에저장한다. -->
  ,!--<c:set var="t" value="${ param.t }"/>-->
  <!-- 디폴터값을 5로 지정한다. -->
  <c:if test="${ empty t }">
   <c:set var="t" value="5"/>
  </c:if>
  <!-- forEach방목문을 돌려서1-9까지 값이 변화는 동안 계속 수행한다. -->
  <c:forEach var="a" begin="1" end="9" step="1">
   <c:out value="${t}"/> X <c:out value="${a}"/>=
   <c:out value="${ a*t }"/><br><!-- a*t값을 출력한다. -->
  </c:forEach>-->

<!--구구단2단에서9단까지바로 하면-->

<c:forEach var="a" begin="2" end="9" step="1">
   <c:forEach var="b" begin="1" end="9" step="1">
   <c:out value="${a}"/> X <c:out value="${b}"/>=
   <c:out value="${ a*b }"/><br><!-- a*b값을 출력한다. -->
   </c:forEach>
  </c:forEach>
 </body>
</html>
 태그저장  취소 구독하기
구독하기를 클릭해 보세요!이웃을 맺은 후 네이버me 메인에서
이웃의 새글을 보실수 있어요스크랩하기  덧글 1개  엮인글 쓰기
 

2011/03/21 22:09 2011/03/21 22:09
Posted
Filed under JSP, JAVA

public static String getSubStr(String _str, int _max){
 
  int int_byte        =        0;;
  String returnStr        =        "";
     
  for(int i=0 ; i<_max ; i++){
    String temp        =        "";
    temp        =        ""+_str.charAt(i);
    int_byte = int_byte+temp.getBytes().length;

    if(int_byte<=_max){
      returnStr        = returnStr+temp;       
    }else{
      break;
    }
 
  }
 
  return returnStr;
}

2011/03/11 13:07 2011/03/11 13:07
Posted
Filed under JSP, JAVA

빈을 생성한다. 인스턴스화 한다. param 태그를 사용해서 프로퍼티를 초기화 할 수 있다.


bean 태그의 속성

   - id : 빈을 참조하기 위한 ID

   - name : 초기화할 클래스명, 자바빈즈 스펙을 따라야 한다.


예제를 보자.

<s:bean id="user" name="com.User">

     <s:param name="name" value="'Stone'" />

     <s:param name="age" value="'27'" />

</s:bean>


<s:property value="#user.name" />

<s:property value="#user.age" />


출력 결과

Stone 27


User의 인스턴스를 생성하고 nam과 age를 초기화 한걸 볼 수 있다.

2010/09/16 09:15 2010/09/16 09:15
Posted
Filed under JSP, JAVA

최근 singleton 패턴 구현에 대한 질문을 받은 적이 있다. singleton 패턴은 인스턴스를 하나만 생성해서 그 객체를 공유해서 사용하는 패턴이다. 일반적으로 DB Pool과 같이 전체 시스템에서 하나의 자원을 공유해서 사용할 때 이 패턴을 활용할 수 있다.

이 패턴을 구현하는 방법은 synchronized getInstance(), double-checked getInstance(), static final instance 등 다양한데, 내 경우는 Singleton 클래스를 구현하기 위해 static initializer를 활용한 방법을 제안했다.

public class Singleton {
  private static Singleton _instance;

  static {
    _instance = new Singleton();
  }

  private Singleton() {}

  public static Singleton getInstance() {
    return _instance;
  }

}

이렇게 구현한 경우 클래스가 로딩되면서 객체가 생성되기 때문에 객체가 이중으로 생성될 수 없고, 가장 확실한 방법인 synchronized getInstance()에 비해서 매번 메소드 호출시에 동기화 작업을 안해줘도 되는 장점이 있다. (synchronized 키워드가 있는 경우 메소드 실행이 약 100배 정도 늦어진다고 한다.)

하지만 오늘 관련 정보를 찾아보니, 글 작성자는 명백히 이 방법보다는 synchronized getInstance()가 좋다고 한다.

getInstance()에서 객체를 생성할 때 장점은 lazy initialization(객체가 사용될 때까지 객체 생성을 연기)이 가능하다는 점과 내부 구현을 Pooling 등으로 변경할 때 쉽게 변경이 가능하다는 것이다. (이 부분은 static initializer도 가능하다.)

다만 Singleton 패턴을 사용해도 ClassLoader 마다 개별적으로 인스턴스가 생성되기 때문에 이 부분은 주의를 기울여야 한다. 특히 Servlet Container는 여러개의 ClassLoader를 사용할 수 있으니 이 점을 인지하고 있어야 한다.

This entry was posted in Java and tagged , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.
2010/09/06 14:22 2010/09/06 14:22