'Tomcat'에 해당되는 글 36

  1. 2012.05.22 이클립스에서 실행되지 않는 웹 어플리케이션
  2. 2012.05.18 tomcat.startup.bat -이거는 ant에서 실행시킬때
  3. 2011.11.24 [EP] JSTL(Apache Taglibs 1.0) 사용하기 1
  4. 2011.03.08 특정 포트를 사용하고 있는 프로그램 찾기
  5. 2011.02.18 Apache Tomcat User Guide - 3.2) Installation
  6. 2011.02.18 Apache Tomcat User Guide - 3.1) Introduction
  7. 2011.02.18 Apache Tomcat User Guide - 3) First webapp
  8. 2011.02.18 Apache Tomcat User Guide - 2) Setup
  9. 2010.12.23 Apache Tomcat User Guide - 1) Introduction
  10. 2010.08.27 Tomcat 표준출력을 파일로 남기기
  11. 2010.05.17 Eclipse에서 Tomcat 포트번호 변경하기
  12. 2010.04.05 Thread dump 생성
  13. 2010.03.29 Windows Aapache Tomcat 설정값 저장 위치
  14. 2010.02.20 톰캣 인스턴스 여러개 띄우기
  15. 2010.01.31 유닉스에 톰캣 컴파일해서 설치하기
  16. 2010.01.10 Ant에서 Tomcat Application 실행시키키
  17. 2010.01.09 [해석] Developing a Spring Framework MVC application step-by-step Chapter 1. Basic Application and Environment Setup
  18. 2009.12.27 윈도우 프로세스 - 이클립스에서 실행시킨 톰캣의 프로세스
  19. 2009.12.23 XML 파싱 에러
  20. 2009.12.21 윈도우 환경에서 자바 인코딩 변경하기
  21. 2009.12.12 Setting property 'source' to 'org.eclipse.jst.jee.server:edi' did not find a matching property.
  22. 2009.12.01 apache-tomcat-4.1.37-LE-jdk1.4
  23. 2009.10.15 Getting started with JavaServer Faces 1.2, Part 1
  24. 2009.08.24 모 시스템 개발환경 구축
  25. 2009.08.08 Spring 2 + JPA + Tomcat
  26. 2009.08.07 Eclipse에서 Tomcat 구동시 사용하는 설정파일
  27. 2009.06.23 Tomcat 설정 - server.xml
  28. 2009.05.20 Apache + Tomcat 연동 확인
  29. 2009.05.19 Tomcat 구동 쉘/배치파일 분석
  30. 2009.05.19 Tomcat 에 Heap 메모리 할당하기

이클립스에서 실행되지 않는 웹 어플리케이션

- Tomcat 5.5 인데 어플리케이션이 제대로 실행이 되지 않는다.
로그가 자세하게 않나온다. ==> [todo] 이거 설정 바꾸면 자세하게 나오지 않나?

심각: Error listenerStart

- web.xml의 순서가 잘못된 것으로 파악.

- 검색해보니 Log4jConfigListener를 ContextLoaderListener보다 먼저 하라고 하는데 나는 해당 안됨.
동일한 소스가 개발기, 운영기에서 잘 돌아가고 있음.
Listener 설정을 빼니깐 어느 정도 돌아가서 그런줄 알았음.

- 혹시나 해서 6.0에서 돌리니깐 에러가 자세하게 나옴.
클래스를 못찾는다.

- 여기 저기 뒤져보니 클래스 파일이 배포되지 않고 있었다.
D:\reps\eclipse_indigo_workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\TestWEBApp\WEB-INF\ 에 classes/가 없다.

왜.....?
여기 메커니즘은 잘 모르는데...
잘 실행되는 웹 어플리케이션과 비교해보니 조금 다른다.
무슨 이유인지 5번째 줄이 빠져 있다.

소스 디렉토리가 달라서 이걸 적용하다가 잘못된거 같기도 하고, SVN에서 받으면서 잘못 되었나???
3시간을 헤맷다.

이걸 잘 활용하면 환경 설정 파일을 다른 곳에 두고 배포할 수도 있겠다.
그리고 소스 디렉토리를 WEB-INF/ 아래에 두지마.
WEB-INF/ 가 통으로 배포되어서 소스까지도 배포된다.
(exclude 할 수 있을려나?)

- 그런데 다음날 실행해보니 또 404 에러가 떨어진다.
Clean을 한다.

tomcat.startup.bat -이거는 ant에서 실행시킬때

set JAVA_HOME=C:/Program Files/Java/jdk1.6.0_20/
set system.env.type=local.pantarei //prod, qa, dev, prod.app1, prod.app2, local.pantarei.home

cd /D D:\resources\programs\java\tomcat\apache-tomcat-6.0.32/
bin/startup.bat

[EP] JSTL(Apache Taglibs 1.0) 사용하기 1

- 환경
ServerInfo : SAP J2EE Engine/7.00
Servlet : 2.3
JSP : 1.2
web.xml 을 수정할 수 없음.

- JSTL (Apache Taglibs 1.0 구현체)을 사용하려고 함.
Tomcat 4, 5에서는 예제(standard-examples.war)가 잘 동작함.

- jstl.jar, standard.jar를 PORTAL-INF/lib/에 넣는다.

test.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
com.sapportals.portal.prt.servlets_jsp.server.jsp.ParseException:  Error in parsing taglib 'http://java.sun.com/jstl/core' tag in web.xml or .tld file of the taglib library.
        at com.sapportals.portal.prt.servlets_jsp.server.jsp.syntax.JspTaglibDirective.verifyAttributes(JspTaglibDirective.java:189)
        at com.sapportals.portal.prt.servlets_jsp.server.jsp.syntax.JspDirective.parse0(JspDirective.java:162)
        at com.sapportals.portal.prt.servlets_jsp.server.jsp.syntax.JspDirective.parse(JspDirective.java:117)
        at com.sapportals.portal.prt.servlets_jsp.server.jsp.syntax.ElementCollection.parse(ElementCollection.java:86)
        at com.sapportals.portal.prt.servlets_jsp.server.jsp.syntax.ParserImpl.parse(ParserImpl.java:595)
        at com.sapportals.portal.prt.servlets_jsp.server.jsp.JSPParser.parse(JSPParser.java:2170)
        at com.sapportals.portal.prt.servlets_jsp.server.jsp.JSPCompiler.compile(JSPCompiler.java:81)
        ...

tld 파일을 여기저기 넣어 보고 uri를 바꿔봐도 안됨.
(JSPCompiler를 디컴파일해서 uri를 어떻게 찾는지 보려고 했는데 어디에 있는지 찾지를 못했다.)

- htmlb를 사용하는 글을 보고 tld를 설정함.

portalapp.xml PORTAL-INF/taglib/에 c.tld를 넣는다.

test.jsp taglib 선언은 되는데 실제 사용할 때 에러가 발생한다.
com.sapportals.portal.prt.servlets_jsp.server.jsp.ParseException: java.lang.NullPointerException
        at com.sapportals.portal.prt.servlets_jsp.server.jsp.TagBeginGenerator.init(TagBeginGenerator.java:148)
        at com.sapportals.portal.prt.servlets_jsp.server.jsp.syntax.xmlsyntax.CustomJspTag.action(CustomJspTag.java:114)
        at com.sapportals.portal.prt.servlets_jsp.server.jsp.syntax.ElementCollection.action(ElementCollection.java:47)
        at com.sapportals.portal.prt.servlets_jsp.server.jsp.JSPParser.parse(JSPParser.java:2170)
        at com.sapportals.portal.prt.servlets_jsp.server.jsp.JSPCompiler.compile(JSPCompiler.java:81)
        at com.sapportals.portal.prt.servlets_jsp.server.jsp.JSPCompiler.run(JSPCompiler.java:140)
        at com.sapportals.portal.prt.core.broker.JSPComponentItem.compileJSP(JSPComponentItem.java:291)
        ...

- SAP NetWeaver 04, 7.1이 JSP 1.2를 지원하지 않는다고 함.
javax.servlet.jsp.JspFactory.getDefaultFactory().getEngineInfo().getSpecificationVersion()의 리턴값은 1.2인데...

- 커스텀 태그라이브러리를 작성해 보니 JSP 1.1 형식으로는 가능
Taglibs의 c.tld를 1.1형식으로 변경하면 가능할 거 같다.

특정 포트를 사용하고 있는 프로그램 찾기

팀원이 Tomcat 이 죽은거 같다고 한다.
웹페이지 접속이 안된다고 하는데.

- netstat 로 확인해 보니 정상적이다.
혹시 이 프로세스가 80 포트를 점유하고 있을수도 있으므로 PrcView 로 확인해본다.


역시 Tomcat 이다.
이 Tomcat 이 어떻게 실행되었는지 확인해 본다.
Original Filename 이 prunsrv.exe 다.


Process Tree 로 보니 services.exe 아래에 있다.


Apache Tomcat User Guide - 3.2) Installation

JDK
Tomcat 7.0 은 J2SE 6.0 이 필요하다.

Tomcat

Ant

CVS

Apache Tomcat User Guide - 3.1) Introduction

이 문서는 아키텍쳐를 논의하거나 ... 개발 툴에 대한 것을 깊이있게 다루지는 않는다.
여기서는 텍스트 에디터, 커맨드 라인 툴을 사용한다.

http://java.sun.com/products/jsp/
JavaServer Pages (JSP) Specification, Version 2.0.
Specific information on scripting (Chapter 6)
tag extensions (Chapter 7)
packaging JSP pages (Appendix A)

http://java.sun.com/products/servlet/download.html
Servlet API Specification, Version 3.0.
web application directory structure and deployment file (Chapter 9)
methods of mapping request URIs to servlets (Chapter 11)
container managed security (Chapter 12)
syntax of the web.xml Web Application Deployment Descriptor (Chapter 13)

http://java.sun.com/j2ee/blueprints/
Sun BluePrints (tm) Design Guidelines for J2EE.
servlet and JSP design 장은 J2EE 환경이 아니더라도 유용한 내용을 담고 있다.


Apache Tomcat User Guide - 3) First webapp

Craig R. McClanahan 아저씨가 많이 도와줬다.

Apache Tomcat User Guide - 2) Setup

자세한 내용은 RUNNING.txt 을 볼 것.

Windows에서는 기본적으로 서비스로 설치된다.
보안을 위해서는 권한이 제한된 다른 계정으로 서비스를 실행시키는 것이 좋다.

[todo] Windows service HOW-TO
http://tomcat.apache.org/tomcat-7.0-doc/windows-service-howto.html

Unix 에서는 Tomcat 을 commons-daemon 프로젝트의 jsvc 를 이용해서 데몬으로 실행시킬 수 있다.
-user 옵션을 사용해서 데몬 초기화 후 사용자를 변경할 수 있다.
이러면 root 가 아니더라도 80 포트로 Tomcat 을 띄울 수 있다.

Commons-Daemon JAR 파일이 Tomcat 을 실행시키는 런타임 클래스패스에 있어야 한다.
bootstrap.jar manifest 파일 Class-Path 에 Commons-Daemon JAR 파일이 기술되어 있지만 ClassNotFoundException, NoClassDefFoundError 가 발생하면 jsvc 실행시 -cp 옵션에 명시해주면 된다.

Apache Tomcat User Guide - 1) Introduction

Context is a web application

$CATALINA_HOME, $CATALINA_BASE

톰캣 시작시 설정을 읽어들이므로 설정 파일을 수정하면 재시작이 필요함.

3, 4 버전대 server.xml 과 차이가 많이 난다.

Tomcat 표준출력을 파일로 남기기

고객사에 모듈 업그레이드를 했는데 에러가 난다.
로그를 확인해야 하는데 로그가 없다.
클래스 로딩되는 상황을 확인해야 하는데 표준출력이 어디로 가는건지...

콘솔에서 starup.bat 를 실행시키거나 startup.bat 를 더블클릭해서 Tomcat을 시작하는 경우 표준출력이 콘솔에 출력되어서 지나간 로그를 확인하기가 힘들다.
(Tomcat 버전에 관계없이 당연한 현상임)


Tomcat이 새창으로 구동되어서 표준출력을 파일로 리다이렉션을 시켜도 파일이 제대로 남지 않는다.
로그가 많아서 필요한 로그는 새창에서 지나가 버림.
startup.bat, catalina.bat 를 이것저것 수정해도 안됨.

로그를 남기려면 새창을 띄우면 안됨.
새창을 띄우는 부분을 찾아서 수정하면 될거 같다.


또는
rem Execute Java with the applicable properties
if not "%JPDA%" == "" goto doJpda
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% > c:/tomcat.log
goto end

이렇게 하면 표준출력이 파일로 떨어진다.
(서비스로 구동시키면 stdout.log, stderr.log 가 생길거야.)

- 회고
운영되는 서버를 왜 이렇게 구동시키지? 우....띠
예전에 이런 문제가 발생했을때 확실히 분석해서 방법을 알아뒀으면 오늘같은 고생은 안했을건데.

로그보고 에러 잡는 일이 남았다. 이제부터 진짜 일이지.

Eclipse에서 Tomcat 포트번호 변경하기

- Server name에 포트번호도 넣어 두자.
admin 포트는 8005 -> 8101
HTTP 포트는 8080 -> 8081
AJP 포트는 8009 -> 8201

Thread dump 생성

- Unix
  • # Ctrl+\ //console
  • # kill -3 pid //damon, man page에서 QUIT에 해당하는 시그널을 확인할 것.

- Windows
  • Ctrl+Break //console
  • 윈도우즈 서비스로 구동중이라면 SendSignal을 이용해서 원하는 프로세스에 Signal(Ctrl+Break)을 보낼 수 있다.
  • Tomcat 6.0은 모니터 프로그램을 통해서 Thread dump를 남길수 있다.
    이 때 덤프는 jakarta_service_yyyymmdd.log에 남는다.


- todo 파일이 생성되는 곳..............

Windows Aapache Tomcat 설정값 저장 위치




톰캣 인스턴스 여러개 띄우기

톰캣 바이너리 하나로 인스턴스를 여러개 띄울 수 있다.

인스턴스 디렉토리(instanceN/)을 만들고
conf/를 복사하고 temp/를 만든다.
(logs/, work/는 자동으로 생긴다. webapps/는 사용하지 않는다면 없어도 될듯)

server.xml을 수정한다.
  • 인스턴스1 포트를 81NN대로 수정한다.
    인스턴스2는 82NN대로 설정한다.
  • Context를 설정한다.

인스턴스 구동 배치파일(instanceN/bin/startup.bat)을 작성한다.
@echo off

set CATALINA_HOME=E:\resources\programs\java\apache-tomcat-6.0.18
set CATALINA_BASE=E:\instanceN
rem set CATALINA_BASE=C:\Documents and Settings\computer\바탕 화면\tomcat //공백이 있다고 "로 감싸지 않는다.
"%CATALINA_HOME%/bin/startup.bat"

각 인스턴스를 구동하고 접속해 본다.
- http://localhost:8180/test
- http://localhost:8280/test

소스는 한곳을 보고 있기 때문에 수정하면 모든 인스턴스에 적용된다.

- Manager Application[각주:1]
CATALINA_HOME/webapps/manager/ 를 복사해서 CATALINA_BASE/webapps/ 에 두면 사용할 수 있다.



  1. 2010-08-24 추가 [본문으로]

유닉스에 톰캣 컴파일해서 설치하기

- 유닉스에서 개발 웹 서버 설치, 설정하기
- Install and configure a development Web server in UNIX

- 시스템 요구 사항
  • 하드디스크 용량 10GB, 메모리 최소 512MB
  • 웹 브라우저
  • JRE 5.0 이상: Tomcat 6에서는 해당 JRE가 필요
  • C 컴파일러 : 솔라리스나 IBM AIX의 기본 설치본에는 이런 컴파일러가 없다. Using the GNU C/C++ compiler on AIX를 참고한다.
  • 파일 추출 도구 : 서버에서 파일을 적절히 추출하려면 gunzip, tar, bzcat, 그리고 가능하다면 GNU make와 tar(gmake, gtar로서 GNU 사이트에서 다운로드 가능)가 필요하다.
    서버에서 도구들이 제대로 동작하는지 체크해 보려면 다음 명령어를 실행해본다.
    # cd /usr
    # find . –name *.tar //(repeat for *make, *zip, etc.)
  • 톰캣 코드
- 유닉스와 윈도에서 톰캣 설정 차이점
  • 유닉스 서버에서는 bzcat, gunzip, tar(혹은 gtar)가 필요
  • PATH 설정
  • 기본 운영체제 파일 시스템(/var, /tmp 등)에 적절한 권한이 필요
  • ID, 그룹, 적절한 접근 권한에 대해 고려해야 함
  • GUI가 아닌 CLI
  • 윈도우는 자동화된 배치 파일 처리에 .bat을, 실행 파일에 .exe 파일을 쓴다.
  • 유닉스에서는 기본적으로는 실행 스크립트 등에 .sh나 .ksh 확장자를 사용한다.
- 경로 설정
JAVA_HOME
# export JAVA_HOME=/usr/jdk/instances/jdk1.5.0 //JRE 또는 JDK
# JAVA_HOME=/usr/bin/java; export JAVA_HOME

# echo $JAVA_HOME
/usr/jdk/instances/jdk1.5.0

CATALINA_HOME
# export CATALINA_HOME=/opt/apache-tomcat-6.0.16

- 셸 설정
홈디렉터리에 .profile 파일을 생성한다.
bash-3.00# cd ~/ (home dir)
bash-3.00# vi .profile
# /bin/sh
stty istrip
PATH=$PATH:/usr/bin:/usr/local/bin:/usr/ucb:/etc
export PATH
umask 077

export SHELL=/usr/bin/ksh
export ENV=$HOME/.kshrc
export EDITOR=vi
export FCEDIT=vi

#Tomcat specific PATHs
export JAVA_HOME=/usr/jdk/instances/jdk1.5.0
export CATALINA_HOME=/opt/apache-tomcat-6.0.16

bash-3.00# PATH=/usr/ccs/bin:$PATH; export PATH (for make cmd)
bash-3.00# PATH=/usr/sfw/bin:$PATH; export PATH

- 사용자와 그룹
여러 사용자가 서버를 사용하게 된다면 당연히 각기 다른 사용자가 다양한 도구와 파일 시스템에 접근할 수 있도록 허용할 사용자와 그룹 권한을 설정하고 싶을 것이다. root가 아닌 사용자로 톰캣을 설치하여 동작시키려 한다면 이 또한 필수다(대부분의 실 서비스 환경에서 추천되는 방식이다).

# /usr/sbin/groupadd -g {구체적인 gid 명시. 명시하지 않으면 OS가 gid를 알아서 할당해줄 것이다.} {그룹 이름}
# /usr/sbin/groupadd -g 10004 tomcatgroup

# /usr/sbin/useradd -d {사용자 홈 디렉터리} -g {사용자가 속한 주 그룹} -u {구체적인 UID 명시. 이 란은 비워둘 수 있다. 명시하지 않으면 운영체제가 UID를 알아서 할당해줄 것이다.) -s {해당 사용자에 대한 기본 셸} -c "{사용자에 대한 상세 정보 명기}" {사용자 이름}
# /usr/sbin/useradd -d /export/home/tomcat -g tomcatgroup -u 10010 -s /bin/ksh -c "Main Tomcat Administrative User" tomcat

- 서버 설치 파일 다운로드, 추출하기
//파일을 /opt 디렉터리 아래로 옮긴다(/opt 디렉토리는 대부분의 신규 소프트웨어가 설치되는 디렉터리다).
# mv *tar.gz /opt
# ls -ltr /opt

//권한 설정하기
# cd /opt
# chmod +x *gz //same as chmod 775
# umask 007 //사용자가 770 권한을 갖고 신규 파일을 생성할 수 있도록 한다. chmod를 역으로 생각해 보라.

//설치 파일 추출하기
# gunzip *.gz
# tar -xvf *.tar
# ls -latr

# rm *.exe
# rm *.bat

- 서버 설정, 컴파일
# cd $CATALINA_HOME/bin
# ./configure --with-java=/usr/java
//- or -
# export JAVA_HOME
# ./configure

//코드 컴파일하기
# gunzip jsvc.tar.gz
# pwd
/opt/apache-tomcat-6.0.16/bin
# tar -xvf jsvc.tar
# gmake //gmake가 위치한 경로가 PATH에 있는지 확인하기 바란다(예를 들어 ./sfw/bin/).
//톰캣 사이트에서는 FreeBSD 시스템의 자체 BSD make 명령어 대신 GNU make(gmake)를 사용해야 한다고 언급하고 있다.

# chmod 775 jsvc[각주:1]
# cp jsvc ..
# cd ..

- 서버 시작[각주:2]
# cd $CATALINA_HOME/bin
# ./startup.sh
# cd ../logs

# tail -50 catalina.out

- 시작 데몬[각주:3] 구동하기
#./jsvc \
–home /usr/jdk/instances/jdk1.5.0 \
–Dcatalina.home=/opt/apache-tomcat-6.0.16 \
-cp ./bin/bootstrap.jar \
-outfile ./logs/catalina.out \
-errfile ./logs/catalina.err \
org.apache.catalina.startup.Bootstrap
//root가 아닌 사용자로 구동하려면 -user 옵션을 사용
//특정 .pid 파일 위치를 명시하려면 -pid 옵션을 사용

# ./jsvc -help

- 톰캣 설치 테스트하기
기본 톰캣은 http 포트 8080에 내부 HTTP 서버를 설치한다(Coyote HTTP/1.1).

- 톰캣 웹 애플리케이션 매니저에 특정 사용자 접근 허용하기
tomcat-users.xml에 role과 user 추가
//보안을 위해 tomcat-user.xml 파일을 파일 소유자만 접근할 수 있도록 제한한다.
# chmod 600 tomcat-users.xml

* 엔터프라이즈 웹 아키텍처 대 독립형(stand-alone) 웹 아키텍처에 대한 비교
  1. jsvc 는 런처(launcher) 프로세스, 통제(controller) 프로세스, 통제되는(controlled) 프로세스 이렇게 세 개의 프로세스를 사용한다. 통제되는 프로세스는 주 자바 쓰레드다. 이 주 자바 가상 머신(JVM)이 비정상적으로 종료되면 통제 프로세스, 즉 컨트롤러 다음에 재시작한다. jsvc는 데몬 프로세스이므로 root로 시작해야 한다. 인자값으로 -user를 주면 root 권한이 없는 사용자로도 동작시킬 수 있다. [본문으로]
  2. LifecycleListeners를 구현하여 시작 프로세스를 입맛에 맞게 고칠 수도 있다. [본문으로]
  3. 데몬은 비 대화형(non-interactive) 서버 애플리케이션으로서 명시한 시그널(signal)들을 운영체제가 통제하게 된다. 윈도에서 서비스를 떠올려보자. 윈도의 서비스는 서버 애플리케이션의 정상적인 셧다운을 위해 제공된다. 운영체제는 셧다운이 절박한 상황인 경우 서버 애플리케이션에게 이를 고지하게 되고 애플리케이션은 수행중인 과정을 끝내기 전에 어떤 작업을 수행할 수 있도록 할 여지가 생기게 된다. [본문으로]

Ant에서 Tomcat Application 실행시키키

- build.xml

- build.properties
appserver.home=E:/resources/programs/java/apache-tomcat-6.0.18
appserver.lib=${appserver.home}/lib
deploy.path=${appserver.home}/webapps

tomcat.manager.url=http://localhost:8080/manager
tomcat.manager.username=tomcat
tomcat.manager.password=s3cret

- appserver.home/conf/tomcat-users.xml

- 확인
$ ant list
Buildfile: build.xml

list:
     [list] OK - Listed applications for virtual host localhost
     [list] /springapp:running:0:springapp
     [list] /manager:running:0:manager
     [list] /:running:0:ROOT
     [list] /docs:running:0:docs
     [list] /examples:running:0:examples
     [list] /host-manager:running:0:host-manager

BUILD SUCCESSFUL
Total time: 3 seconds

출처 : Developing a Spring Framework MVC application step-by-step

[해석] Developing a Spring Framework MVC application step-by-step Chapter 1. Basic Application and Environment Setup

http://web.archive.org/web/20161119155731/http://docs.spring.io/docs/Spring-MVC-step-by-step/part1.html

Chapter&nbsp;1.&nbsp;Basic Application and Environment Setup.pdf


1장. 기본 어플리케이션 및 환경설정

1.1. 프로젝트 디렉토리 생성

모든 소스와 작성할 파일을 저장할 디렉토리를 springapp/라고 하자.
자바소스를 저장할 src/를 만든다.
어플리케이션을 패키징하고 배포할 WAR에 들어갈 모든 파일을 저장할 war/를 만든다.
war/에는 자바소스를 제외한 JSP 소스, 설정파일이 저장된다.

1.2. index.jsp 작성하기

아주 간단한 index.jsp를 war/에 작성하자.
index.jsp는 우리가 만드는 어플리케이션의 시작점이 된다.
'springapp/war/index.jsp': war/에 WEB-INF/를 만들고 WEB-INF/ 아래에 web.xml을 만든다.
'springapp/war/WEB-INF/web.xml':
1.3. Tomcat에 배포하기

이 Tutorial에서 계속 사용될 Ant 빌드 스크립트를 만들자.
이 빌드 스크립트에는 컴파일, 빌딩, 배포하는 타겟이 있고, 일부는 특정 서버에만 사용되는 것도 있다.
'springapp/build.xml': Tomcat이 아닌 다른 WAS를 사용한다면 빌드 스크립트 마지막 부분은 지워도 된다.
WAS의 hot deploy 특성에 따르거나, 직접 서버를 내렸다 올려야 한다.

IDE를 사용한다면 build.xml의 Tomcat 타겟에 에러 표시가 보일지도 모르는데 무시해도 된다.

Ant 빌드 스크립트가 개발을 좀더 쉽게 할 수 있게 도와 줄것이다.
여기에 사용된 대부분의 내용은 Ant나 Tomcat의 기본적인 내용이므로 자세한 설명은 생략한다.
빌드 파일 내용을 springapp/에 build.xml에 넣기만 하면 된다.
그리고 같은 위치에 build.properties를 만들고 서버가 설치된 위치를 맞춘다.
'springapp/build.properties':
# Ant properties for building the springapp

appserver.home=${user.home}/apache-tomcat-6.0.14
# for Tomcat 5 use $appserver.home}/server/lib
# for Tomcat 6 use $appserver.home}/lib
appserver.lib=${appserver.home}/lib

deploy.path=${appserver.home}/webapps

tomcat.manager.url=http://localhost:8080/manager
tomcat.manager.username=tomcat
tomcat.manager.password=s3cret

당신이 시스템에 Tomcat을 설치하지 않았다면 Tomcat 소유주가 appserver.home/webapps/에 대해 모든 권한을 줘야 한다.
또는 소유주가 appserver.home/webapps/springapp/를 만들고 이 디렉토리에 모든 권한을 줘야 한다.
리눅스에서는 chmod a+rwx springapp 라는 명령어를 사용하면 모든 사용자에게 모든 권한을 줄수 있다.

'appserver.home/conf/tomcat-users.xml'에 사용자를 추가한다. 이제 모든 준비가 다 되었고 springapp/에서 ant 명령을 실행시킨다.
빌드하거나 배포하려면 deploy나 deploywar 타겟을 실행시킨다.

1.4. 어플리케이션 확인

${appserver.home}/bin/startup.bat 을 실행시켜서 Tomcat을 시작하자.
Tomcat이 우리가 만든 어플리케이션을 올렸는지 list 태스크로 확인할 수 있다.

브라우저로 http://localhost:8080/springapp/index.jsp을 열어보자.

1.5. Spring 프레임워크 다운로드

Spring Framework 2.5를 다운로드 받고 적당한 곳에 압축을 푼다.

1.6. web.xml 수정

springapp/war/WEB-INF/web.xml을 수정한다.
Front Controller인 DispatcherServlet을 설정한다.
나중에 설정할 정보에 기반하여 보내질 모든 요청을 처리한다.
이 서블릿 정의는 servlet-mapping 엔트리로 여기서 사용될 URL 패턴을 매핑한다.
우리는 htm 확장자를 가진 모든 URL을 springapp 서블릿으로 보내도록 설정한다.
'springapp/war/WEB-INF/web.xml':

springapp-servlet.xml을 springapp/war/WEB-INF/에 만든다.
이 파일은 DispatcherServlet에서 사용되는 빈에 대한 정의를 한다.
모든 웹 관련 컴포넌트가 사용할 WebApplicationContext이다. =-=> ???
이 파일의 이름은 web.xml 의 servlet-name 엘리먼트에 -servlet을 붙여서 만든다.
이것은 Spring Web MVC 프레임워크의 표준 명명법이다.
이제 /hello.htm 에 대한 빈을 설정하고 class는 springapp.web.HelloController로 하자.
이것은 /hello.htm 이라는 URL에 대한 요청을 controller가 처리하게 한다.
Spring Web MVC 프레임워크는 요청 URL과 처리할 객체를 매핑하는데 HandlerMapping 인터페이스 구현체를 사용한다.
DispatcherServlet과 달리 HelloController는 특정 페이지에 대한 요청을 처리한다.(Fowler는 이것을 Page Controller라고 한다.)
DispatcherServlet이 사용하는 기본적인 HandlerMapping은 BeanNameUrlHandlerMapping이다.
이 클래스는 빈이름을 요청의 URL과 매핑해서 DispatcherServlet이 어떤 컨트롤러를 호출할지 알려준다.
'springapp/war/WEB-INF/springapp-servlet.xml':

1.7. WEB-INF/lib에 라이브러리 복사하기

war/WEB-INF/lib/를 만들고 Spring 배포본에서 spring.jar, spring-webmvc.jar, commons-logging.jar를 복사해 넣는다.
이 라이브러리는 서버에 배포되고 빌드에 사용된다.

1.8. Controller 만들기

springapp.web 패키지에 HelloController를 만든다.
src/springapp/web/에 HelloController.java를 만든다.
'springapp/src/springapp/web/HelloController.java':

이것은 아주 기본적인 Controller 구현이다.
우리는 나중에 Spring에서 제공하는 Controller 구현체를 구현해서 확장할 것이다.
Spring Web MVC에서 Controller는 요청을 처리하고 ModelAndView를 리턴한다.
이 경우에는 hello.jsp이다.
이렇게 리턴한 모델은 ViewResolver에 의해서 수행된다.
우리는 명시적으로 ViewResolver를 지정하지 않았기 때문에 Spring에 기본적으로 제공된다.(view 이름에 해당하는 URL로 포워딩한다.)
이 핸들러로 실제로 요청이 왔는지 로거를 찍어본다.
Tomcat을 사용하면 로그가 appserver.home/log/catalina.out에 출력된다.

IDE를 사용하면 lib/의 jar파일을 빌드 패스에 추가해야 한다.
서블릿 컨테이너의 servlet-api.jar도 추가해야 HelloController.java가 제대로 컴파일된다.

1.9. Controller에 테스트 작성하기

테스트는 소프트웨어 개발에 있어서 필수적이다.
애자일 개발에 있어서도 핵심 practice이다.
controller에 복잡한 로직을 넣기 전에 테스트를 작성한다.
테스트는 개발이 진행됨에 따라 변경에 대한 신뢰를 줄수 있다.
springapp/ 아래에 test/를 만들어서 테스트를 작성한다.

HelloControllerTests 테스트 클래스를 만들고 JUnit의 TestCase를 상속한다.
단위 테스트는 handleRequest()가 리턴하는 뷰이름이 hello.jsp인지 확인한다.
'springapp/test/springapp/web/HelloControllerTests.java':

테스트를 실행시키려면, build.xml에 테스트 태스크를 추가한다.
우선 junit.jar를 복사해서 넣는다.
테스트를 컴파일하고 실행시키는 태스크를 하나로 두는 대신 buildtests와 tests로 나눈다.
springapp/resourcs/devlib/를 두고 여기에 junit.jar를 넣는다.

build.xml에 다음의 내용을 추가한다.
<property name="resources.dir" value="resources"/>
<property name="devlib.dir" value="${resources.dir}/devlib"/>
...
<path id="devlib-classpath">
    <fileset dir="${devlib.dir}">
        <include name="*.jar"/>
    </fileset>
</path>

buildtests, tests 타겟에 <classpath refid="devlib-classpath"/>를 추가한다.

IDE에서 테스트를 실행시키려면 junit.jar를 빌드 패스에 추가한다.
'springapp/build.xml':

애자일의 또다른 practice는 지속적인 통합이다.
빌드할 때마다 테스트를 실행시켜서 개발이 진행되면서 어플리케이션이 제대로 동작하는지 확인할 수 있다.

1.10. View 작성하기

이미 앞에 언급된대로 hello.jsp로 포워딩한다.
war/에 둔다.
'springapp/war/hello.jsp':

1.11. 어플리케이션 컴파일, 배포

depoy 타겟을 실행시키고 reload 타겟을 실행시키면 빌드하고 Tomcat을 리로드한다.
Ant 출력과 Tomcat 로그를 확인한다.

1.12. 어플리케이션 테스트

브라우저로 http://localhost:8080/springapp/hello.htm 으로 들어가본다.

1.13. 요약

  • 설정이 제대로 되었는지 확인하기 위해 index.jsp를 만들었다. 나중에 실제 링크가 있는 페이지로 만들것이다.
  • DispatcherServlet과 springapp-servlet.xml
  • 지금은 단순히 ModelAndView만 리턴하는 HelloController. 나중에 model을 구현한다.
  • 뷰이름을 검증하기 위한 HelloControllerTests
  • 아주 간단한 hello.jsp



윈도우 프로세스 - 이클립스에서 실행시킨 톰캣의 프로세스


[todo] java.library.path 관련해서 분석해 볼 것.

XML 파싱 에러

무시무시한 XML 파싱 에러가 났다.
Caused by: org.jdom.input.JDOMParseException: Error on line 15: The element type "xxx:TestName" must be terminated by the matching end-tag "</xxx:TestName>".
    at org.jdom.input.SAXBuilder.build(SAXBuilder.java:504)
    at org.jdom.input.SAXBuilder.build(SAXBuilder.java:807)
    ...
    ... 37 more
Caused by: org.xml.sax.SAXParseException: The element type "xxx:PartyName" must be terminated by the matching end-tag "</xxx:TestName>".
    at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)

시스템이 영문 윈도우즈라 file.encoding을 EUC-KR로 지정해 두었다.
외부시스템과 검증테스트를 하다보니 위와 같은 에러가 남.
개발자와 통화를 하던중 한글이 깨진 경우라고 함.
생성된 MIME 파일을 살펴보니 한글이 깨진 경우가 나왔다.

XXX-20091223162459-72723.0
    <XxxDateTime>20091223162532</XxxDateTime>
    <DescriptionText>성공적으로 처리 되었습니다.</DescriptionText>

XXX-20091223162459-72723.s
      <xxx:To>
        <xxx:TestID>1234512345</xxx:TestID>
        <xxx:TestName>(주)XXX</xxx:TestName>
      </xxx:To>

XXX-20091223162541-07225.s
      <xxx:To>
        <xxx:TestID>1234512345</xxx:TestID>
        <xxx:TestName>(二??대?????ㅽ???/xxx:TestName>
      </xxx:To>

file.encoding을 8859_1, UTF-8로 수정하면 정상적으로 처리된다.
시스템의 페이지 인코딩인 UTF-8로 설정했다.

윈도우 환경에서 자바 인코딩 변경하기

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

Setting property 'source' to 'org.eclipse.jst.jee.server:edi' did not find a matching property.

- Eclipse(3.4)에서 Tomcat(6.0)을 실행시키는데 이런 에러가 발생했다.
  1. 톰캣을 중지시키고
  2. Server Overview - Server Options에서
  3. Publish module context to separate XML files를 체크하고 저장
  4. 톰캣을 다시 시작한다.

apache-tomcat-4.1.37-LE-jdk1.4

What's the difference between Tomcat 4.1.x and Tomcat 4.1.X-LE-jdk1.4?
Tomcat LE버전과 Full 버전 차이점 

[todo] 그런데 이 환경에서 xml 관련 라이브러리를 사용하려면?

Getting started with JavaServer Faces 1.2, Part 1

JSF 1.2 시작하기, Part 1
Getting started with JavaServer Faces 1.2, Part 1

- Dynamic Web Project에 JSF 예제 돌리기
  1. 필요한 라이브러리를 PROJECT/WEB/WEB-INF/lib/에 추가한다.
    1. C:\Program Files\glassfish-v3-prelude\glassfish\modules\web\jsf-impl.jar
    2. C:\Program Files\glassfish-v3-prelude\glassfish\modules\jsf-api.jar
    3. jstl.jar
  2. 환경설정파일을 추가, 수정한다.
    1. faces-config.xml
    2. web.xml
  3. 예제 소스를 추가한다.
    1. /index.jsp
    2. /pages/calculator.jsp
    3. src/com/arcmind/jsfquickstart/model/Calculator.java
  4. 브라우저로 확인한다.
- MyFaces 구현체로도 가능할거야. [todo]

[todo] 원리를 좀더 추가해야 하지 않나?

모 시스템 개발환경 구축

D사 W시스템 개발환경 구축
  1. SunOne 6.1 과 동일한 Servlet/JSP 스펙인 Tomcat 4.1.40 설치
  2. JDK 1.4.1_30
  3. 이클립스 소스위치를 WEB-INF/src/ 로 변경, 이클립스 src 는 제거
  4. 기존 소스에서 WEB-INF/classes/ 는 제거 : 위 경우처럼 이클립스 설정을 변경하는 것이 더 좋은 방법임.
  5. com.inicis.inipay.INIpay41.class 를 디컴파일해서 소스에 추가함.(jar로 묶어도 될듯)
  6. (소스에서) 환경설정파일 위치 지정
  7. 환경설정파일에서 경로 변경
  8. server.xml에서 DataSource 설정
  9. 드라이버파일 추가
  10. web.xml 수정 : SunOne에서는 문제가 없는데 Tomcat에서는 dtd 체크를 해서 에러가 발생함.
[todo] web.xml 수정한거 올리기

Spring 2 + JPA + Tomcat

- 스프링 2와 JPA 시작하기

* 도메인 분석을 수행함
* 비즈니스 객체와 서비스를 구현함
* 비즈니스 객체에 대한 단위 테스트
* 스프링 JPA를 사용해 비즈니스 객체에 데이터 접근 코드 쉽게 추가
* 스프링 DAO(Data Access Object)를 사용해 서비스 구현
* DB2® Express-C와 연동한 서비스에 대한 통합 테스트 코드 작성
* 사용자 인터페이스에 기반을 둔 스프링 Model-View-Controller(MVC)를 위한 컨트롤러 생성
* 사용자 인터페이스를 위한 뷰(view) 디자인
* 애플리케이션을 위한 배치 가능한 WAR 파일 생성
* 아파치 톰캣(Apache Tomcat) 서버에 애플리케이션을 구성하고 배치함

- 도메인 모델 분석
직원엔터티에서 주소를 분리한다.
오퍼레이션을 정의한다.
Employee.java 에서 setEmpid() 를 제거한다.(JPA 에 의해서 관리된다.)

- JPA 어노테이션에 대한 설명
Employee와 Address 인스턴스가 일대일 관계(@OneToOne(casecade=CascadeType.ALL)) 어노테이션으로 기술되어)를 맺고 있는 것을 기억하자. 이 어노테이션은 Employee 객체를 대상으로 하는 모든 엔티티 매니저 오퍼레이션이 그 객체와 관련된 Address 객체에도 영향을 준다는 것을 의미한다. 이 말은 RDBMS에 Employee 기록을 추가하는 어느 작업이든지 그에 대응하는 Address 기록도 만들어지는 것을 뜻한다. 이것은 RDBMS에서 종종 찾을 수 있는 연속되는 삭제 참조 무결성 개념의 확장된 개념이라 보면 되겠다.

- HSQLDB 이용, DB2 로 변경

- RDBMS로 수행하는 DAO 통합 테스트 작성하기

- SpringMVC

- 스프링 2를 위해 톰캣 준비하기
   1. 톰캣에 스프링 2 클래스로더 추가 : server/lib/spring-tomcat-weaver.jar, META-INF/context.xml
   2. 톰캣에 스프링 2 컨텍스트 로더 리스너(context loader listener) 추가
   3. 톰캣에 DB2 JDBC 드라이버 복사
   4. 톰캣을 위해 JNDI DB2 데이터소스 구성

- 참고
스프링 2와 JPA 시작하기 - 에러해결
Spring -JPA-Tomcat

[todo] 이거 설정만 바꾸면 다른 JPA 구현체로 바꿀수 있나?(2.0에서는 다른 구현체를 지원하지 않음. 2.5 는 에러남. 결국은 에러를 해결해야 하는데...)
[todo] 직접 해보기...금방될거야

Eclipse에서 Tomcat 구동시 사용하는 설정파일

CATALINA_HOME 은 Tomcat 이 설치된 위치가 되고
CATALINA_BASE 는 WORKSPACE/.metadata/.plugins/org.eclipse.wst.server.core/tmpN 으로 된다.

Servers 프로젝트내에 위치한 설정파일은 WORKSPACE/Servers/Tomcat v6.0 Server at localhost-config/ 에 위치한다.
여기에서 수정한 tomcat-users.xml 은 CATALINA_BASE/conf/ 에 디플로이된다.
(web.xml 은 수정해도 반영되지가 않네...)


- work/도 CATALINA_BASE 아래에서 찾을 수 있다.

Tomcat 설정 - server.xml

- Context
  • useNaming 이 false 인 경우 다음 코드에서 에러가 발생한다.

Apache + Tomcat 연동 확인

이미지나 정적 파일처리는 아파치에서 하게 된다.

톰캣을 내리고 이미지를 요청해서 처리가 되면 아파치에서 이미지를 제대로 처리한다는 말이다.
그러나 503 Service Unavailable 에러가 발생한다.

그래서 server.xml 에서 다음의 Valve 를 활성화시킨다.
<Valve className="org.apache.catalina.valves.AccessLogValve"
         directory="logs"  prefix="localhost_access_log." suffix=".txt"
         pattern="common" resolveHosts="false"/>

이미지를 요청하면
# tail -f tomcat/logs/localhost_access_log.2009-05-19.txt
111.20.30.90 - - [19/May/2009:22:49:57 +0900] "GET /images/prev.gif HTTP/1.1" 304 -

# tail -f apache/logs/access_log
111.20.30.90 - - [19/May/2009:22:49:57 +0900] "GET /images/prev.gif HTTP/1.1" 304 -

아파치에서 이미지파일을 처리한다면 톰캣 access 로그에는 남지 않아야 되지 않나?

그리고 존재하지 않는 이미지 파일을 요청하면 404 에러가 발생하는데 아파치에 설정된 404 페이지가 나와야 한다.
그런데 지금은 톰캣의 404 페이지가 나온다.

[todo] modjk 설정을 다시 해봐야 할듯, 아마도 모든 요청이 tomcat 으로 가게 되어서 그럴거야

Tomcat 구동 쉘/배치파일 분석

- HP-UX, Tomcat/5.5.27
catalina.sh
  1. OS 종류를 확인하고 변수 설정
  2. setenv.sh 실행
  3. setclasspath.sh 실행
  4. touch "$CATALINA_BASE"/logs/catalina.out
  5. $JAVA_WRAPPER "$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS \
        -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
        -Dcatalina.base="$CATALINA_BASE" \
        -Dcatalina.home="$CATALINA_HOME" \
        -Djava.io.tmpdir="$CATALINA_TMPDIR" \
        org.apache.catalina.startup.Bootstrap "$@" start \
        >> "$CATALINA_BASE"/logs/catalina.out 2>&1 &

- Windows, Tomcat/4.1.37-LE-jdk1.4
startup.bat
catalina.bat
  1. CATALINA_OPTS 설정
  2. setenv.bat 실행
  3. setclasspath.bat 실행
  4. echo Using CATALINA_BASE:   %CATALINA_BASE%
    echo Using CATALINA_HOME:   %CATALINA_HOME%
    echo Using CATALINA_TMPDIR: %CATALINA_TMPDIR%
    echo Using JAVA_HOME:       %JAVA_HOME%

- Windows, Tomcat/6.0.18
startup.bat
  1. CATALINA_HOME 변수로 %CATALINA_HOME%\bin\catalina.bat를 확인한다.
  2. 현재 디렉토리를 CATALINA_HOME 으로 두고 위와 같이 확인한다.
  3. 그래도 catalina.bat를 찾지 못하면 에러
  4. 전달된 인자를 설정하고
  5. catalina.bat start 를 실행시킨다.
catalina.bat
  1. 위와 같이 CATALINA_HOME 변수 확인
  2. setenv.bat 실행
  3. setclasspath.bat 실행
  4. CLASSPATH 설정
  5. echo Using CATALINA_BASE:   %CATALINA_BASE%
    echo Using CATALINA_HOME:   %CATALINA_HOME%
    echo Using CATALINA_TMPDIR: %CATALINA_TMPDIR%
    echo Using JAVA_HOME:       %JAVA_HOME%




Tomcat 에 Heap 메모리 할당하기

Q사 T시스템 사이트가 열리지 않는 경우가 발생

Tomcat 구동시 Heap 메모리를 증가시켰는데도 Hangup 현상이 계속 발생함.

# ps -efx | grep java //x 옵션을 사용해서 프로세스를 확인
root 10733     1  0  5월 15  ?         2:56 /opt/java1.5/bin/IA64N/java -Dserver.type=real -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -XdoCloseWithReadPending -Djava.endorsed.dirs=/opt/WS/tomcat/common/endorsed -classpath :/opt/WS/tomcat/bin/bootstrap.jar:/opt/WS/tomcat/bin/commons-logging-api.jar -Dcatalina.base=/opt/WS/tomcat -Dcatalina.home=/opt/WS/tomcat -Djava.io.tmpdir=/opt/WS/tomcat/temp org.apache.catalina.startup.Bootstrap start
oracle 12243 12238  0  2월 19  ?        94:04 /oracle/app/oracle/product/10g/db_1/jdk/bin/IA64N/java -server -Xmx256M -XX:MaxPermSize=96m -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XdoCloseWithReadPending -DORACLE_HOME=/oracle/app/oracle/product/10g/db_1 -Doracle.home=/oracle/app/oracle/product/10g/db_1/oc4j -Doracle.oc4j.localhome=/oracle/app/oracle/product/10g/db_1/HOST/sysman -DEMSTATE=/oracle/app/oracle/product/10g/db_1/HOST -Doracle.j2ee.dont.use.memory.archive=true -Djava.protocol.handler.pkgs=HTTPClient -Doracle.security.jazn.config=/oracle/app/oracle/product/10g/db_1/oc4j/j2ee/OC4J_DBConsole_HOST/config/jazn.xml -Djava.security.policy=/oracle/app/oracle/product/10g/db_1/oc4j/j2ee/OC4J_DBConsole_HOST/config/java2.policy -Djava.security.properties=/oracle/app/oracle/product/10g/db_1/oc4j/j2ee/home/config/jazn.security.props -DEMDROOT=/oracle/app/oracle/product/10g/db_1/HOST -Dsysman.md5password=true -Drepapi.oracle.home=/oracle/app/oracle/product/10g/db_1 -Ddisable.checkForUpdate=true -Djava.awt.headless //이놈은 뭘까?

프로세스를 확인해보니 옵션이 적용되지 않았다.[각주:1]

catalina.sh에 CATALINA_OPTS="$CATALINA_OPTS -server -Xms1024m -Xmx2048m" 을 추가했는데도...

확인해보니 catalina.sh에서 setenv.sh을 호출하는데 거기에서 CATALINA_OPTS="-XdoCloseWithReadPending" 이러고 있다.(Tomcat 구동 쉘/배치파일 분석 참고)
윽...

setenv.sh에 설정옵션을 넣고 재구동시킴.

JAVA_OPTS="-Dserver.type=real" //real 보다는 prod가 낫지 않나?
CATALINA_OPTS="$CATALINA_OPTS -server -Xms512m -Xmx1024m -XX:MaxPermSize=256m"
umask 072 //Tomcat 루트권한으로 구동되므로 생성되는 파일을 다른 사용자도 확인가능하도록 한다.

며칠 지켜봐야 할거 같다.


  1. ps -ef 로만 확인하니깐 그렇다. 사소한 것도 확인하도록~ [본문으로]