'개발'에 해당되는 글 188건
- 2009.04.01 JBoss Slim Domain 구성
- 2009.03.27 #### Linux_명령어 모음 (아주 잘 나와있음)#### 강추!!! 6
- 2009.03.26 [JBOSS/TOMCAT] JBOSS/TOMCAT 에서 심볼릭링크 디렉토리 허용 방법
- 2009.03.25 정규식
- 2009.03.19 JBoss 한글 처리(다국어 포함) - Encoding Filter
- 2009.03.18 17.4. 스토어드 루틴 및 트리거의 바이너리 로깅
- 2009.03.17 [java][성능] JVM GC와 메모리 튜닝
- 2009.03.17 미리 보는 미래 개발환경「자바SE 6
- 2009.03.17 JDK 5.0 에서의 새로운 변화
- 2009.03.16 대충의 JBoss-4.2.3 GA 릴리즈 노트 정리
JBoss Slim Domain 구성
JBoss Cluster domain을 구성하던 중 불필요한 기능을 없애야 해서 뺀 도메인을 첨부합니다.
뺀 기능이 너무 많아 현재 있는 기능만 보면 다음과 같습니다.
- Clustering
- Web Application(Web Container)
- JMX
위의 것을 남기고 모두 없앴습니다.
- CORBA IIOP
- JMS
- SNMP
- Client Deployer 등등
Attache : Domain Configuration - Server/conf directory
JBoss Slimming EAP4.3
Client Deployer Service
- Client에서 J2EE를 Deploy할 경우 서비스이며 원격 deploy같은 기능
- 1. $SERVER_HOME/deploy/client-deployer-service.xml 삭제
JBoss MQ
- JBoss MQ를 사용하지 않을 경우 제거 가능
- 1. $SERVER_HOME/deploy/jms 디렉토리 삭제
- 2. $SERVER_HOME/lib/jbossmq.jar 파일 삭제
JMS Queue/Topic 삭제
- 1. $SERVER_HOME/conf/jboss-service.xml 파일을 여세요
- 2. 다음을 주석으로 막아버리세요
jboss.mq:service=DestinationManager
Client User Transaction
- 클라이언트측에서 서버의 UserTransaction을 얻어가서 안쓸경우
- 1. $SERVER_HOME/conf/jboss-service.xml파일을 연다
- 2. jboss:service=ClientUserTransaction 에 주석처리
- 3. 370라인쯤의 아래를 찾아 주석처리 mbean code="org.jboss.tm.usertx.server.ClientUserTransactionService"
- 4. $SERVER_HOME/conf/xmdesc/ClientUserTransaction-xmbean.xml을 삭제하거나 편집기로 열어 주석처리
CORBA/IIOP
- CORBA/IIOP 프로토콜을 사용하지 않을 경우 삭제 가능
- 1. $SERVER_HOME/conf/jboss-service.xml파일을 연다
- 2. org.jboss.management.j2ee.LocalJBossServerDomain를 찾아 CorbaORB 애트리뷰트를 주석처리
- 3. $SERVER_HOME/deploy/iiop-service.xml파일을 삭제하거나 주석처리
Web Service
- 웹서비스를 사용하지 않을 경우
- 1. $SERVER_HOME/deploy/jbossws.jar 디렉토리 삭제
- 2. $SERVER_HOME/conf/standardjboss.xml파일을 연후
org.jboss.ws.server.ServiceEndpointInterceptor 를 주석처리
- 3. $SERVER_HOME/lib/jboss-saaj.jar & jboss-jaxrpc.jar 삭제
EJB3
- EJB3를 사용하지 않을 경우 - 삭제할 경우 JMX-console을 사용할 경우 에러남
- 1. #SERVER_HOME/deploy/ejb3*에 관련된 것을 삭제
- 2. $SERVER_HOME/lib/ejb3-persistence.jar jboss-ejb3x.jar 삭제
UDDI Service
- Web Service UDDI를 사용하고 싶지 않을 경우
- 1. $SERVER_HOME/deploy/juddi-service.sar 디렉토리 삭제
Bean Shell Deployer
- Shell에서 deploy할 수 있는 모듈을 사용하지 않을 경우
- 1. $SERVER_HOME/deploy/bsh-deployer.xml을 삭제
- 2. $SERVER_HOME/lib/bsh* 삭제
UUID Key Generator
- CMP EJB에서 primary key를 생성하기 위한 것인데 불필요하면 제거
- 1. $SERVER_HOME/deploy/uuid-key-generator.war 디렉토리를 삭제
- 2. $SERVER_HOME/lib/autonumber-plugin.jar 파일을 삭제
RMI over HTTP 삭제
- RMI를 HTTP로 터널링할 필요가 없을 경우에 삭제 가능합니다.
- 1. default설정일 경우 $SERVER_HOME/deploy/http-invoker.sar디렉토리를 삭제하세요
- 2. 클러스터 설정일 경우 $SERVER_HOME/deploy/httpha-invoker.sar디렉토리를 삭제하세요
JBoss Messaging
- JBoss MQ를 사용하지 않을 경우 제거 가능
- 1. $SERVER_HOME/deploy/jboss-messaging.sar 디렉토리 삭제
- 2. $SERVER_HOME/lib/jboss-messaging*.jar 파일 삭제
CacheInvalidation Service
- CMP EJB에서 CacheInvalidation을 사용하지 않을 경우 삭제할 수 있음
- 1. $SERVER_HOME/deploy/cache-invalidation-service.xml 삭제
- 주의 : HA Cluster를 사용할 경우 에러 발생할 수 있습니다.
JavaMail
- 1. $SERVER_HOME/deploy/mail-service.xml 파일 삭제
- 2. $SERVER_HOME/lib/mail* 삭제
#### Linux_명령어 모음 (아주 잘 나와있음)#### 강추!!!
A | ||||||
|
B | ||||||
| ||||||
| ||||||
c |
C | ||||||||||
| ||||||||||
| ||||||||||
|
D | ||||||||||||||
| ||||||||||||||
| ||||||||||||||
e |
E | ||||||||||||
| ||||||||||||
| ||||||||||||
|
F | ||||||||||||||
| ||||||||||||||
| ||||||||||||||
|
G | ||||||||||
| ||||||||||
| ||||||||||
|
H | ||||||
| ||||||
| ||||||
|
I | ||||||||||||
| ||||||||||||
| ||||||||||||
j |
J | ||||||||
| ||||||||
| ||||||||
|
K | ||||
| ||||
| ||||
|
L | ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
|
M | ||||||||||||||||||||
| ||||||||||||||||||||
| ||||||||||||||||||||
n |
N | ||||||||
| ||||||||
| ||||||||
|
O | ||
| ||
| ||
|
P | ||||||||||||||||||||||
| ||||||||||||||||||||||
| ||||||||||||||||||||||
q |
Q | ||||
| ||||
| ||||
|
R | ||||||||
| ||||||||
| ||||||||
|
S | |||||||||||||||
swapon 스왑 공간을 초기화하는 데는 swapon 명령을 사용한다. 이 명령은 커널에게 해당 공간을 스왑으로 사용할 수 있다는 점을 알려준다. 이 명령에게는 추가하고자 하는 스왑 공간의 경로를 인수로 전달해 주어야 한다. 임시 스왑 파일을 스왑 공간에 추가하고자 한다면 다음과 같이 한다.
스왑 공간들은 /etc/fstab 파일에 의해서 자동적으로 사용될 수도 있다.
시스템이 시작될 때, 스크립트를 통해서 swapon -a 명령이 실행되는데 이 명령은 /etc/fstab에 나열되어 있는 스왑 공간들을 모두 사용하게 해 준다. 그래서 흔히 swapon 명령은 추가적인 스왑이 필요할 때만 사용되는 것이 보통이다. free 명령을 쓰면 스왑의 사용 상황을 모니터 할 수 있다. 이것은 현재 얼마나 많은 용량의 스왑이 사용되고 있는지 알려준다.
여기서 Mem: 이라고 쓰여진 첫째줄은 실제 물리적 메모리의 상황을 보여주는 것이다.커널은 물리적 메모리를 약 1 megabyte 정도 사용하는데, total이라고 쓰여진 세로줄에서 보여주는 전체메모리 양에는 이 커널이 차지하는 공간이 빠져 있다. used라는 세로줄은 현재 사용중인 메모리 양을 보여주고 있으며(두번째 가로줄은 버퍼 로 사용되는 부분을 제외하고 계산한 양이다), free란 세로줄에서는 전혀 사용되지 않은 양을 보여주고 있다. 또한 shared란 부분은 프로세스간에 공유되고 있는 메모리를 나타내고 있는 것이므로, 그 양이 많은 것은 기쁜 일이다. buffers는 현재 디스크 버퍼 캐쉬로 사용되는 메모리 양을 보여주고 있다. 마지막 줄인 Swap:은 위와 같은 항목을 스왑 공간에 똑같이 적용시킨 내용이다. 이 항목이 모두 제로라면, 스왑 공간이 아예 동작하고 있지 않다는 뜻이다. 같은 정보를 top 명령이나 /proc/meminfo 파일을 통해 얻을 수 있다. 그러나 어느 경우든, 특정한 스왑 공간에 대한 정보를 얻는 것은 좀 어렵다. 스왑 공간은 swapoff 명령으로 기능을 멎게 할 수 있다. 그러나 임시로 잡은 스왑 공간이 아니라면, 스왑을 끌 필요는 없다. 만약 스왑을 끄게되면, 스왑 공간에 들어있던 메모리 페이지들이 먼저 실제 메모리로 들어가야 되는데, 실제 메모리에 여유가 없는 경우에는 또 다른 스왑 공간으로 방출되게 된다. 그런데 이 메모리 페이지들을 모두 수용하기에 가상메모리마저도 부족하다면, 그때부터는 리눅스 시스템이 무진장 버벅대기 시작할 것이다. 시간이 아주 많이 걸린 후에는 좀 잠잠해지겠지만, 여전히 시스템은 사용불능 상태에 있게 된다. 따라서 스왑을 끄기 전에, 충분한 여유 메모리가 있는지 꼭 확인해 보아야만 한다(free 같은 것으로). swapon -a 명령으로 자동적으로 사용되는 스왑 공간들은, 마찬가지로 swapoff -a 명령을 써서 끌 수 있다. 이것도 역시 /etc/fstab 파일에 나열되어 있는 스왑 공간만을 끄기 때문에, 나머지 수동으로 추가시킨 스왑들은 영향을 받지 않는다. 때 때로, 실제 메모리가 많이 비어 있는데도 불구하고 스왑을 아주 많이 쓰고 있는 경우를 보게 될 수가 있다. 보통 이런 일이 발생하는 경우는 이렇다. 어떤 덩치 큰 프로세스가 실제 메모리를 많이 점유하는 바람에 시스템이 스왑을 많이 사용하게 되었다고 하자. 이 프로세스가 종료되면 실제 메모리엔 여유 공간이 많이 남게 되지만, 스왑으로 한번 내려간 데이터는 그것이 당장 필요하지 않는 한 실제 메모리로 불려지지 않는다. 따라서 스왑 영역을 많이 사용하면서도 실제 메모리가 많이 비어있는 현상이 꽤 오래 지속될 수 있는 것이다. 그러므로 이런 현상에 특별히 신경쓸 필요는 없다. 하지만, 최소한 그 원리는 이해하고 있어야 나중에 불안하지 않을 것이다.
| |||||||||||||||
| |||||||||||||||
|
T | ||||||||||||
| ||||||||||||
| ||||||||||||
|
U | ||||||
| ||||||
| ||||||
|
V | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
W | ||||||||||||||||||
| ||||||||||||||||||
| ||||||||||||||||||
|
X | ||||
| ||||
| ||||
|
| ||
| ||
| ||
|
Z | ||
|
[JBOSS/TOMCAT] JBOSS/TOMCAT 에서 심볼릭링크 디렉토리 허용 방법
둘다 설정 파일 위치만 다르고 동일하기 때문에 이번 쓰래드는 JBOSS/TOMCAT으로 기술한다.
앞으로도 JBOSS와 TOMCAT에 둘다 적용 가능한 부분은 JBOSS/TOMCAT으로 JBOSS만 적용 되는 부분은 JBOSS로 TOMCAT에만 적용 되는 부분은 앞에 TOMCAT을 붙이겠다.
기본적으로 JBOSS/TOMCAT에서는 WEB Application 디렉터리 바깥으로 심볼릭 링크를 허용하지 않는다.
그러나 만약에 허용 하는 경우에는 Context의 allowLinking 값을 true로 설정하는 경우 외부의 심볼릭 링크를 허용하게 된다.
Default Context는 jboss-web.deployer/context.xml(TOMCAT의 경우 server.xml)에서 설정하게 되며, Web Application 별로 설정하고 싶은 경우에는 WEB-INF/context.xml에서 설정하게 된다.
참고로 심볼릭링크를 사용하는 경우 JBOSS나 TOMCAT을 구동하는 사용자가 해당 디렉터리를 읽을 수 잇는 권한이 설정 되어야 한다.
설정 예시
ROOT.war/WEB-INF/context.xml
<Context cookies="true" crossContext="true" allowLinking="true">
<!-- Session persistence is disable by default. To enable for all web
apps set the pathname to a non-empty value:
<Manager pathname="SESSIONS.ser" />
To enable session persistence for a single web app, add a
WEB-INF/context.xml
-->
<Manager pathname="" />
<!-- Install an InstanceListener to handle the establishment of the run-as
role for servlet init/destroy events.
-->
<InstanceListener>org.jboss.web.tomcat.security.RunAsListener</InstanceListener>
</Context>
참고로 심볼릭 링크 허용은 보안상의 문제를 일으킬 수 있다. 그러므로 Default Context에 설정하기 보다는 필요한 Web Application에만 설정하도록 한다.
그리고 Windows에서는 이를 허용할 경우, JSP 소스가 노출되는 문제가 있으므로 설정해서는 안된다.
(*) 다큐먼트에 나와있는 주의 사항
NOTE: This flag MUST NOT be set to true on the Windows platform (or any other OS which does not have a case sensitive filesystem), as it will disable case sensitivity checks, allowing JSP source code disclosure, among other security problems.
JBoss 한글 처리(다국어 포함) - Encoding Filter
JBoss에서 한글 처리를 하기 위해서는 2가지의 작업이 필요합니다.
1. Web Application에 filter를 등록하기
첨부하는 파일을 이용하여 web.xml에 Encoding Filter를 등록하도록 합니다.
다음의 내용을 web.xml에 추가합니다.
<filter-name>Set Character Encoding</filter-name>
<filter-class>filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
JBoss level에서 엄격하게 스펙을 적용하는 통에.. 위의 url-pattern은 * 이 아니고 /* 이어야 합니다.
<Connector ... URIEncoding="UTF-8"/>
위와 같이 설정하면 다국어 지원까지 가능한 애플리케이션을 만들 수 있습니다.
17.4. 스토어드 루틴 및 트리거의 바이너리 로깅
리 플리케이션의 경우, 마스터 서버는 자신의 바이너리 로그에 포함된 이벤트를 자신의 슬레이브에 전달하는데, 이렇게 함으로서 서버에서 이루어진 데이터의 변경과 동일한 내용을 전달된 이벤트가 실행하도록 하게 한다 . Section 6.2, “리플리케이션 구현 소개” 참조.
특정 데이터 복구 동작은 바이너리 로그의 사용을 요구한다. 백업 파일이 재저장된 후에, 백업이 이루어진 후 기록된 바이너리 로그에 있는 이벤트가 재 실행된다. 이러한 이벤트들은 백업이 이루어지는 시점부터 데이터 베이스를 갱신하게 낸다. Section 5.10.2.2, “복구를 위한 백업 사용하기” 참조.
이 섹션에서는 MySQL 5.0에 있는 스토어드 루틴(프로시저 및 함수)와 트리거에 관련된 바이너리 로깅의 개발을 설명하도록 하겠다. 첫 번째로는 로깅 실행에서 발생하는 변경 사항에 대해 정리를 할 것이고, 그 다음에는 스토어드 루틴의 사용에서 있게 되는 실행의 현재 조건문(current condition)에 대해 언급하기로 한다. 마지막으로, 언제 그리고 어떻게 다앵한 변경이 만들어 지는지에 대한 정보를 제공하는 실행에 대한 자세한 내용을 설명하겠다. 이러한 상세 내용들은 현재의 로깅 행위에 관련된 몇몇 사항이 이전 버전과는 어떻게 달리 실행되는지를 보여 준다.
일반적으로, 여기에서 설명하는 논제들은 바이너리 로깅이 SQL명령문 레벨에서 생긴다는 사실에서부터 출발한다. 향후의 MySQL버전은 로우-레벨(row-level) 바이너리 로깅을 실행할 예정이며, SQL명령문의 실행으로 인해 각 개별 열(row)을 변경시키는 것을 열거할 것이다.
다른 것들은 고려하지 말고, --log-bin옵션으로 서버를 구동해서 바이너리 로깅을 활성화 시켰다고 가정하자. ( Section 5.12.3, “The Binary Log” 참조.) 만일 바이너리 로그가 활성화 되지 않는다면, 리플리케이션은 불가능하게 되거나, 또는 데이터 복구를 위한 바이너리 로그가 불가능하게 된다.
MySQL 5.0 에서 스토어드 루틴 로깅의 개발은 아래와 같이 요약할 수 있다 :
MySQL 5.0.6 이전 버전 : 스토어드 루틴 로깅의 초기 실행에서, 스토어드 루틴과 CALL 명령문을 생성하는 명령문은 로그 되지 않음. 이러한 누락은 리플리케이션과 데이터 복구에 문제를 야기할 수 있다.
MySQL 5.0.6 : 스토어드 루틴과 CALL 명령문을 생성하는 명령문은 로그 되어짐. 스토어드 함수 호출은 데이터를 업데이트 하도록 하는 명령문이 실행될 때 로그 되어 진다 (이러한 명령문들이 로그 되어졌기 때문에). 하지만, 비록 함수 자체에서 데이터의 변경이 이루어 진다 하더라도, 데이터를 변경시키지 않는 SELECT와 같은 명령문이 실행될 때에는 로그 되어지지 않는다; 이것은 문제를 일으키게 된다. 어떤 환경에서는, 서로 다른 시간 또는 서로 다른(서버 및 슬레이브)기계에서 함수 및 프로시저가 실행된다면 서로 다른 영향을 받을 수 있기 때문에 데이터 복구 또는 리플리케이션 자체가 불안정할 수 있다. 이런 문제를 처리하기 위해, 안정적인 루틴의 동일성을 제공하고, 충분한 권한을 갖고 있는 사용자에 의한 행위를 제외한, 일반적으로 불안정한 루틴을 방지하기 위한 조치가 실행된다.
MySQL 5.0.12: 스토어드 함수에 대해서는, 데이터를 변경시키는 함수 호출이 SELECT와 같이 로그 되지 않는(non-logged)명령어 내에서 발생할 때, 서버는 그 함수를 호출하는 DO 명령문을 로그 시킴으로써 데이터가 복구되거나 슬레이브 서버에 리플리케이션되는 동안 함수가 실행되도록 한다. 스토어드 프로시저에 대해서는, 서버는 CALL 명령문을 로그 시키지 못한다. 대신에, 서버는 CALL명령문의 결과로 실행되는 프로시저에 포함되어 있는 개별 명령문은 로그 시킨다. 이것은 프로시저가 마스터 서버가 아닌 슬레이브 서버상에서 서로 다른 실행 경로를 따라 실행될 때 발생할 수 있는 문제들을 제거한다.
MySQL 5.0.16: MySQL 5.0.12에서 제공하는 프로시저 로깅 변경을 통해 불안정한 루틴상의 조건문이 스토어드 프로시저에 대해 안정적으로 동작하도록 해 준다. 따라서, 이러한 조건문을 제어하는 사용자 인터페이스를 함수에 적용 되도록 수정한다. 프로시저 생성자를 더 이상 제한 할 수 없게 되는 것이다.
앞에서 설명한 변경의 결과로, 바이너리 로깅이 활성화될 때에 다음에서 설명하는 조건문을 스토어드 함수에 적용할 수 있게 된다. 이러한 조건문은 스토어드 프로시저 생성에는 적용되지 않는다.
스토어드 함수를 생성 또는 변경하기 위해서는, 일반적으로 CREATE ROUTINE 또는 ALTER ROUTINE 권한을 요구하는 것에 더불어. 반드시 SUPER 권한을 가져야 한다.
스 토어드 함수를 생성할 때에는, 그것이 확정적(deterministic)인지 또는 그것이 데이터를 수정하는 않는다는 것을 선언해야 한다. 그렇지 않으면, 그 함수는 데이터 복구 또는 리플리케이션에 대해 덜 안정한 상태가 되어 버린다. 함수의 특성 중에 두 가지가 여기에 적용된다 :
DETERMINISTIC and NOT DETERMINISTIC 특성은 함수가 주어진 입력 값에 대해 항상 동일한 결과를 만드는지 아닌지를 나타낸다. 어떤 특성도 주어지지 않으면, 디폴트는NOT DETERMINISTIC 이며, 따라서 함수를 확정적인 것으로 선언하기 위해서는 DETERMINISTIC를 확실하게 지정해 주어야 한다.
NOW() 함수(또는 동일 기능 함수) 또는 RAND()의 사용은 함수를 반드시 non-deterministic하게 만들어 주는 것은 아니다. NOW()의 경우, 바이너리 로그는 타임스탬프와 복사본은 올바르게 포함한다. 또한, RAND()도 함수내에서 일단 한번 호출 되어 지면 정확하게 복사본을 만들게 된다. (함수 실행 타임스탬프 및 무작위 수는 마스터 서버 및 슬레이브 상에 있는 동일한 암시적 입력(implicit input)으로 간주할 수 있다.)
CONTAINS SQL, NO SQL, READS SQL DATA, 및 MODIFIES SQL DATA 특성은 함수가 데이터를 읽거나 또는 쓰는 정보를 제공한다. NO SQL 또는 READS SQL DATA 는 함수가 데이터를 변경하지 않는다는 것을 나타내는 것이다. 하지만 어떠한 특성도 주어지지 않으면 디폴트가 CONTAIN SQL이 되기 때문에 반드시 이러한 것 중에 하나를 명확히 지정해 주어야 한다.
CREATE FUNCTION 명령문이 디폴트로 수용되도록 하기 위해서는, DETERMINISTIC 또는 NO SQL 및 READS SQL DATA 중에 한 개는 반드시 확실하게 표현되어야 한다. 그렇지 않으면 에러가 발생한다:
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL,
or READS SQL DATA in its declaration and binary logging is enabled
(you *might* want to use the less safe log_bin_trust_function_creators
variable)
함수의 특성에 대한 평가는 생성자의 “honesty”를 근거로 한다: MySQL은 DETERMINISTIC으로 선언된 함수가 non-deterministic결과를 만드는 명령문을 갖고 있지 않음을 검사하지 않는다.
함 수 생성(SUPER권한이 있어야 하며 함수가 deterministic으로 선언되거나 또는 데이터를 수정하지 않아야 함)에서 앞에서 언급한 조건을 피하기 위해서는, 글로벌 시스템 변수log_bin_trust_function_creators 를 1로 설정 해야 한다. 디폴트로는, 이 변수의 값은 0이지만, 아래와 같이 변경할 수 있다:
· mysql> SET GLOBAL log_bin_trust_function_creators = 1;
또한, 이 변수는 서버를 구동할 때 --log-bin-trust-function-creators 옵션을 사용해서 설정할 수 있다.
만일 바이너리 로깅이 활성화되지 않으면, log_bin_trust_function_creators 는 적용되지 않으며 루틴 생성을 위한 SUPER는 필요 없게 된다.
트 리거는 스토어드 함수와 유사하고, 따라서 앞에서 언급한 주의 사항 역시 트리거에도 적용된다. 트리거에 대한 예외적인 사항은 다음과 같다: CREATE TRIGGER 는 옵셔널(optional) DETERMINISTIC 특성을 갖지 않기 때문에, 트리거는 항상 deterministic으로 간주된다. 하지만, 이러한 가정은 어떤 경우에서는 틀릴 수도 있다. 예를 들면, UUID() 함수는non-deterministic (그리고 복사되지 않음)이다. 이러한 함수를 트리거에 사용할 경우에는 주의하여야 한다.
트리거는 테이블을 업데이트할 수 있으며(MySQL 5.0.10 버전 현재), 따라서 SUPER권한이 없고 log_bin_trust_function_creators 의 값이 0 이라면, CREATE TRIGGER 과 함께 나타나는 스토어드 함수에 대한 에러 메시지와 비슷한 에러가 발생하게 된다.
이 섹션의 나머지에서는 스토어드 루틴 로깅 개발에 대해서 상세하게 설명하기로 한다. 상세 설명 중에 몇 가지는 현재 스토어드 루틴 사용에서 로깅 관련 조건문에 대한 이론적인 기본 지식을 제공하여 준다.
MySQL 5.0.6 이전 버전에서 루틴 로깅: 스토어드 루틴을 생성하고 사용하는 명령문이 바이너리 로그되는 것이 아니라, 스토어드 루틴내에서 선언된 명령문이 로그되어 진다. 아래의 명령문을 작성 하였다고 가정하자:
CREATE PROCEDURE mysp INSERT INTO t VALUES(1);
CALL mysp;
이 예에서 보면, INSERT 명령문만이 바이너리 로그에서 나타난다. CREATE PROCEDURE 와 CALL 명령문은 나타나지 않는다. 바이너리 로그에서 루틴 관련(routine-related) 명령문이 없다는 것은 스토어드 루틴이 올바르게 복사되지 않았다는 것을 의미한다. 이것은 또한 데이터 복구 동작에 대해, 바이너리 로그에 있는 이벤트의 재실행은 스토어드 루틴를 복구시키지 않는다는 것을 의미하기도 한다.
MySQL 5.0.6에서 루틴 로깅 변경: 스토어드 루틴 생성과 CALL 명령문(그리고 관련된 리플리케이션 및 데이터 복구 문제)에 대한 로깅 부재를 연결(address)하기 위해, 스토어드 루틴에 대한 바이너리 로깅의 특성은 여기에서 설명하였듯이 변경되었다. (아래의 리스트중에 몇 가지 항목은 다음 버전에서 다루어지기 때문에 제외한다.)
서버는CREATE PROCEDURE, CREATE FUNCTION, ALTER PROCEDURE, ALTER FUNCTION, DROP PROCEDURE, 및 DROP FUNCTION 명령문을 바이너리 로그에 쓴다. 또한, 서버는 프로시저내에서 실행되는 명령문이 아닌, CALL 명령문을 로그 한다. 아래의 명령문을 작성하였다고 가정하자:
· CREATE PROCEDURE mysp INSERT INTO t VALUES(1);
· CALL mysp;
이 예문에서 보면, CREATE PROCEDURE 및 CALL 명령문은 바이너리 로그에서 나타나지만, INSERT 명령문은 나타나지 않는다. 이것은 MySQL 5.0.6 이전 버전에서 발생했던 INSERT만 로그되는 문제를 해결해 준다.
CALL 명령문 로깅은 리플리케이션에 대한 보안 문제를 갖게 되는데, 두 가지 요소로 인해 이런 문제가 생긴다:
프로시저가 마스터와 슬레이브 서버상에 있는 서로 다른 실행 경로를 따라갈 수 있게 한다.
슬레이브에서 실행되는 명령문은 전체 권한을 갖고 있는 슬레이브 SQL 쓰레드(Thread)에 의해 실행된다.
비 록 사용자가 루틴을 생성하기 위해서는 반드시 CREATE ROUTINE권한을 가져야 함을 의미 하지만, 전체 권한을 갖는 SQL 쓰레드가 실행하는 명령문이 있는 슬레이브 위에서만 실행될 위험한 명령문을 작성할 수 있다. 예를 들면, 마스터 와 슬레이브 서버가 서버 ID 1과 2를 갖고 있다면, 마스터 서버의 사용자는 아래와 같이 불안정한 프로시저 unsafe_sp() 를 생성해서 호출할 수 있다:
mysql> delimiter //
mysql> CREATE PROCEDURE unsafe_sp ()
-> BEGIN
-> IF @@server_id=2 THEN DROP DATABASE accounting; END IF;
-> END;
-> //
mysql> delimiter ;
mysql> CALL unsafe_sp();
CREATE PROCEDURE 와 CALL 명령문은 바이너리 로그를 작성할 수 있고, 따라서 슬레이브는 이것을 실행할 수 있다. 슬레이브 SQL 쓰레드는 전체 권한이 있기 때문에, accounting 데이터 베이스를 끝내는(drop) DROP DATABASE 명령문을 실행한다. 따라서, CALL 명령문은 마스터와 슬레이브에서 서로 다른 영향을 받게 되고, 이것은 리플리케이션이 안전하게 이루어 지지 않게 된다.
앞선 예문은 스토어드 프로시저를 사용하고 있으나, 바이너리 로그를 작성하는 명령문 내에서 호출되는 스토어드 함수에 대해서도 비슷한 문제가 발생한다: 함수 호출은 마스터와 슬레이브에 서로 다른 효과를 나타낸다.
바 이너리 로깅을 갖는 서버에 대해 이러한 위험을 피하도록 하기 위해, MySQL 5.0.6은 스토어드 프로시저와 함수는 반드시 일반적인 CREATE ROUTINE 권한을 요구하는 것과 아울러 SUPER권한을 갖도록 한다. 비슷하게, ALTER PROCEDURE 또는 ALTER FUNCTION을 사용하기 위해서는, ALTER ROUTINE
[java][성능] JVM GC와 메모리 튜닝
자바스터디 네트워크 [www.javastudy.co.kr]
조대협 [bcho_N_O_SPAM@j2eestudy.co.kr]
모든 Java Application은 JVM(Java Virtual Machine)위에서 동작한다.
이 JVM이 동작하는데 있어서, 메모리의 구조와 특히 GC는 Application의 응답시간과 성능에 밀접한 관계를 미친다. 이번 강좌에서는 JVM 의 메모리 구조와 GC 알고리즘 (JDK 1.4.X에 포함된 새로운 알고리즘 포함) 그리고, JVM의 메모리 튜닝을 통한 Application의 성능향상방법에 대해서 알아보도록 하자.
1.GC란 무엇인가?
GC는 Garbage Collection의 약자로 Java 언어의 중요한 특징중의 하나이다.
GC는 Java Application에서 사용하지 않는 메모리를 자동으로 수거하는 기능을 말한다.
예전의 전통적인 언어 C등의 경우 malloc, free등을 이용해서 메모리를 할당하고, 일일이 그 메모리를 수거해줘야했다. 그러나 Java 언어에서는 GC 기술을 사용함에 따라서 개발자로 하여금 메모리 관리에서 부터 좀더 자유롭게 해주었다.
2.GC의 동작 방법은 어떻게 되는가?
1) JVM 메모리 영역
GC의 동작 방법을 이해하기 위해서는 Java의 메모리 구조를 먼저 이해할 필요가 있다.
일반적으로 Application에서 사용되는 객체는 오래 유지 되는 객체보다, 생성되고 얼마안있어서 사용되지 않는 경우가 많다. <그림 1 참조>
<그림 1. 메모리 foot print>
그래서 Java에서는 크게 두가지 영역으로 메모리를 나누는데 Young 영역과 Old 영역이 그것이다.
Young 영역은 생긴지 얼마 안된 객체들을 저장하는 장소이고, Old영역은 생성된지 오래된 객체를 저장하는 장소이다. 각 영역의 성격이 다른 만큼 GC의 방법도 다르다.
먼저 Java의 메모리 구조를 살펴보자.
<그림 2. Java 메모리 구조>
Java의 메모리 영역은 앞에서 이야기한 두 영역 (Young 영역,Old 영역)과 Perm 영역 이렇게 3가지로 영역으로 구성된다.
<표 1. Java 메모리 영역>
2) GC 알고리즘
그러면 이 메모리 영역을 JVM이 어떻게 관리하는지에 대해서 알아보자.
JVM은 New/Young 영역과, Old영역 이 두영역에 대해서만 GC를 수행한다. Perm영역은 앞에서 설명했듯이 Code가 올라가는 부분이기 때문에, GC가 일어날 필요가 없다. Perm영역은 Code가 모두 Load되고 나면 거의 일정한 수치를 유지한다.
○ Minor GC
먼저 New/Young영역의 GC방법을 살펴보자 New/Young 영역의 GC를 Minor GC라고 부르는데, New/Young영역은 Eden과 Survivor라는 두가지 영역으로 또 나뉘어 진다. Eden영역은 Java 객체가 생성되자 마자 저장이 되는곳이다. 이렇게 생성된 객체는 Minor GC가 발생할때 Survivor 영역으로 이동된다.
Survivor 영역은 Survivor 1과 Suvivor2 영역 두 영역으로 나뉘어 지는데, Minor GC가 발생하면 Eden과 Survivor1에 Alive되어 있는 객체를 Suvivor2로 복사한다. 그리고 Alive되어 있지 않는 객체는 자연히 Suvivor1에 남아있게 되고, Survivor1과 Eden영역을 Clear한다. (결과적으로 Alive된 객체만 Survivor2로 이동한것이다.)
다음번 Minor GC가 발생하면 같은 원리로 Eden과 Survivor2영역에서 Alive되어 있는 객체를 Survivor1에 복사한다. 계속 이런 방법을 반복적으로 수행하면서 Minor GC를 수행한다.
이렇게 Minor GC를 수행하다가, Survivor영역에서 오래된 객체는 Old영역으로 옮기게 된다.
이런 방식의 GC 알고리즘을 Copy & Scavenge라고 한다. 이 방법은 매우 속도가 빠르며 작은 크기의 메모리를 Collecting하는데 매우 효과적이다. Minor GC의 경우에는 자주 일어나기 때문에, GC에 소요되는 시간이 짧은 알고리즘이 적합하다.
이 내용을 그림을 보면서 살펴보도록 하자.
<그림 3-1. 1st Minor GC>
Eden에서 Alive된 객체를 Suvivor1으로 이동한다. Eden 영역을 Clear한다.
<그림 3-2. 2nd Minor GC>
Eden영역에 Alive된 객체와 Suvivor1영역에 Alive된 객체를 Survivor 2에 copy한다.
Eden영역과 Suvivor2영역을 clear한다.
<그림 3-3. 3rd Minor GC>
객체가 생성된 시간이 오래지나면 Eden과 Suvivor영역에 있는 오래된 객체들을 Old 영역으로 이동한다.
○ Full GC
Old 영역의 Garbage Collection을 Full GC라고 부르며, Full GC에 사용되는 알고리즘은 Mark & Compact라는 알고리즘을 이용한다. Mark & Compact 알고리즘은 전체 객체들의 reference를 쭉 따라가다면서 reference가 연결되지 않는 객체를 Mark한다. 이 작업이 끝나면 사용되지 않는 객체를 모두 Mark가 되고, 이 mark된 객체를 삭제한다.<그림 4 참고> (실제로는 compact라고 해서, mark된 객체로 생기는 부분을 unmark된 즉 사용하는 객체로 메꾸어 버리는 방법이다.)
Full GC는 매우 속도가 느리며, Full GC가 일어나는 도중에는 순간적으로 Java Application이 멈춰 버리기 때문에, Full GC가 일어나는 정도와 Full GC에 소요되는 시간은 Application의 성능과 안정성에 아주 큰 영향을 준다.
<그림 4. Full GC>
3. GC가 왜 중요한가?
Garbage Collection중에서 Minor GC의 경우 보통 0.5초 이내에 끝나기 때문에 큰문제가 되지 않는다. 그러나 Full GC의 경우 보통 수초가 소요가 되고, Full GC동안에는 Java Application이 멈춰버리기 때문에 문제가 될 수 있다.
예를 들어 게임 서버와 같은 Real Time Server를 구현을 했을때, Full GC가 일어나서 5초동안 시스템이 멈춘다고 생각해보자.
또 일반 WAS에서도 5~10초동안 멈추면, 멈추는동안의 사용자의 Request가 Queue에 저장되었다가 Full GC가 끝난후에 그 요청이 한꺼번에 들어오게 되면 과부하에 의한 여러 장애를 만들 수 있다..
그래서 원할한 서비스를 위해서는 GC를 어떻게 일어나게 하느냐가 시스템의 안정성과 성능에 큰 변수로 작용할 수 있다.
4. 다양한 GC 알고리즘
앞에서 설명한 기본적인 GC방법 (Scavenge 와 Mark and compact)이외에 JVM에서는 좀더 다양한 GC 방법을 제공하고 그 동작방법이나 사용방법도 틀리다. 이번에는 다양한 GC 알고리즘에 대해서 알아보자. 현재 (JDK 1.4)까지 나와 있는 JVM의 GC방법은 크게 아래 4가지를 지원하고 있다.
- Default Collector
- Parallel GC for young generation (from JDK 1.4 )
- Concurrent GC for old generation (from JDK 1.4)
- Incremental GC (Train GC)
1) Default Collector
이 GC 방법은 앞에서 설명한 전통적인 GC방법으로 Minor GC에 Scavenge를, Full GC에 Mark & compact 알고리즘을 사용하는 방법이다. 이 알고리즘에는 이미 앞에서 설명했기 때문에 별도의 설명을 하지는 않는다.
JDK 1.4에서부터 새로 적용되는 GC방법은 Parallel GC와 Concurrent GC 두가지 방법이 있다. Parallel GC는 Minor GC를 좀더 빨리하게 하는 방법이고 (Throughput 위주) Concurrent GC는 Full GC시에 시스템의 멈춤(Pause)현상을 최소화하는 GC방법이다.
2) Parallel GC
JDK1.3까지 GC는 하나의 Thread에서 이루어진다. Java가 Multi Thread환경을 지원함에도 불구하고, 1 CPU에서는 동시에 하나의 Thread만을 수행할 수 밖에 없기때문에, 예전에는 하나의 CPU에서만 GC를 수행했지만, 근래에 들어서 하나의 CPU에서 동시에 여러개의 Thread를 실행할 수 있는 Hyper Threading기술이나, 여러개의 CPU를 동시에 장착한 HW의 보급으로 하나의 HW Box에서 동시에 여러개의 Thread를 수행할 수 있게 되었다.
JDK 1.4부터 지원되는 Parallel GC는 Minor GC를 동시에 여러개의 Thread를 이용해서 GC를 수행하는 방법으로 하나의 Thread를 이용하는것보다 훨씬 빨리 GC를 수행할 수 있다.
<그림 7. Parallel GC 개념도>
<그림 7> 을 보자 왼쪽의 Default GC방법은 GC가 일어날때 Thread들이 작업을 멈추고, GC를 수행하는 thread만 gc를 수행한다. (그림에서 파란영역), Parallel GC에서는 여러 thread들이 gc를 수행이 가능하기 때문에, gc에 소요되는 시간이 낮아진다.
Parallel GC가 언제나 유익한것은 아니다. 앞에서도 말했듯이 1CPU에서는 동시에 여러개의 thread를 실행할 수 없기 때문에 오히혀 Parallel GC가 Default GC에 비해서 느리다. 2 CPU에서도 Multi thread에 대한 지원이나 계산등을 위해서 CPU Power가 사용되기 때문에, 최소한 4CPU의 256M 정도의 메모리를 가지고 있는 HW에서 Parallel GC가 유용하게 사용된다.
Parallel GC는 크게 두가지 종류의 옵션을 가지고 있는데,Low-pause 방식과 Throughput 방식의 GC방식이 있다.
Solaris 기준에서 Low-pause Parallel GC는 ?XX:+UseParNewGC 옵션을 사용한다. 이 모델은 Old 영역을 GC할때 다음에 설명할 Concurrent GC방법과 함께 사용할 수 있다. 이 방법은 GC가 일어날때 빨리 GC하는것이 아니라 GC가 발생할때 Application이 멈춰지는 현상(pause)를 최소화하는데 역점을 뒀다.
Throughput 방식의 Parallel GC는 ?XX:+UseParallelGC (Solaris 기준) 옵션을 이용하며 Old 영역을 GC할때는 Default GC (Mark and compact)방법만을 사용하도록 되어 있다.Minor GC가 발생했을때, 되도록이면 빨리 수행하도록 throughput에 역점을 두었다.
그외에도 ParallelGC를 수행할때 동시에 몇개의 Thread를 이용하여 Minor영역을 Parallel GC할지를 결정할 수 있는데, -XX:ParallelGCThreads=
3) Concurrent GC
앞에서도 설명했듯이, Full GC즉 Old 영역을 GC하는 경우에는 그 시간이 길고 Application이 순간적으로 멈춰버리기 때문에, 시스템 운용에 문제가 된다.
그래서 JDK1.4부터 제공하는 Concurrent GC는 기존의 이런 Full GC의 단점을 보완하기 위해서 Full GC에 의해서 Application이 멈추어 지는 현상을 최소화 하기 위한 GC방법이다.
Full GC에 소요되는 작업을 Application을 멈추고 진행하는것이 아니라, 일부는 Application이 돌아가는 단계에서 수행하고, 최소한의 작업만을 Application이 멈췄을때 수행하는 방법으로 Application이 멈추는 시간을 최소화한다.
<그림 8. Concurrent GC 개념도>
그림 8에서와 같이 Application이 수행중일때(붉은 라인) Full GC를 위한 작업을 수행한다. (Sweep,mark) Application을 멈추고 수행하는 작업은 일부분 (initial-mark, remark 작업)만을 수행하기 때문에, 기존 Default GC의 Mark & Sweep Collector에 비해서 Application이 멈추는 시간이 현저하게 줄어든다.
Solaris JVM에서는 -XX:+UseConcMarkSweepGC Parameter를 이용해 세팅한다.
4) Incremental GC (Train GC)
Incremental GC또는 Train GC라고도 불리는 GC방법은 JDK 1.3에서부터 지원된 GC방법이다. 앞에서 설명한 Concurrent GC와 비슷하게, 의도 자체는 Full GC에 의해서 Application이 멈추는 시간을 줄이고자 하는데 있다.
Incremental GC의 작동방법은 간단하다. Minor GC가 일어날때 마다 Old영역을 조금씩 GC를 해서 Full GC가 발생하는 횟수나 시간을 줄이는 방법이다.
<그림 9. Incremental GC 개념도>
그림 9에서 보듯이. 왼쪽의 Default GC는 FullGC가 일어난후에나 Old 영역이 Clear된다. 그러나, 오른쪽의 Incremental GC를 보면 Minor GC가 일어난후에, Old 영역이 일부 Collect된것을 볼 수 있다.
Incremental GC를 사용하는 방법은 JVM 옵션에 ?Xinc 옵션을 사용하면 된다.
Incremental GC는 많은 자원을 소모하고, Minor GC를 자주일으키고, 그리고 Incremental GC를 사용한다고 Full GC가 없어지거나 그 횟수가 획기적으로 줄어드는 것은 아니다. 오히려 느려지는 경우가 많다. 필히 테스트 후에 사용하도록 하자.
※ Default GC이외의 알고리즘은 Application의 형태나 HW Spec(CPU수, Hyper threading 지원 여부), 그리고 JVM 버전(JDK 1.4.1이냐 1.4.2냐)에 따라서 차이가 매우 크다. 이론상으로는 실제로 성능이 좋아보일 수 있으나, 운영환경에서는 여러 요인으로 인해서 기대했던것만큼의 성능이 안나올 수 있기 때문에, 실환경에서 미리 충분한 테스트를 거쳐서 검증한후에 사용해야 한다.
5. GC 로그는 어떻게 수집과 분석
JVM에서는 GC 상황에 대한 로그를 남기기 위해서 옵션을 제공하고 있다.
Java 옵션에 ?verbosegc 라는 옵션을 주면되고 HP Unix의 경우 ?verbosegc ?Xverbosegc 옵션을 주면 좀더 자세한 GC정보를 얻을 수 있다. GC 정보는 stdout으로 출력이 되기 때문에 “>” redirection등을 이용해서 file에 저장해놓고 분석할 수 있다.
Example ) java ?verbosegc MyApplication
그럼 실제로 나온 GC로그를 어떻게 보는지를 알아보자.
<그림 5. 일반적인 GC 로그, Windows, Solaris>
<그림 5>는 GC로그 결과를 모아논 내용이다. (실제로는 Application의 stdout으로 출력되는 내용과 섞여서 출력된다.)
Minor GC는 ”[GC “로 표기되고, Full GC는 “[Full GC”로 표기된다.
그 다음값은 Heap size before GC인데,GC 전에 Heap 사용량 ( New/Young 영역 + Old 영역 + Perm 영역)의 크기를 나타낸다.
Heap size after GC는 GC가 발생한후에 Heap의 사용량이다. Minor GC가 발생했을때는 Eden과 Survivor 영역으 GC가 됨으로 Heap size after GC는 Old영역의 용량과 유사하다.(Minor GC에서 GC되지 않은 하나의 Survivor영역내의 Object들의 크기도 포함해야한다.)
Total Heap Size는 현재 JVM이 사용하는 Heap Memory양이다. 이 크기는 Java에서 ?ms와 ?mx 옵션으로 조정이 가능한데. 예를 들어 ?ms512m ?mx1024m로 해놓으면 Java Heap은 메모리 사용량에 따라서 512~1024m사이의 크기에서 적절하게 늘었다 줄었다한다. (이 늘어나는 기준과 줄어드는 기준은 (-XX:MaxHeapFreeRatio와 ?XX:MinHeapFreeRation를 이용해서 조정할 수 있으나 JVM vendor에 따라서 차이가 나기때문에 각 vendor별 JVM 메뉴얼을 참고하기 바란다.) Parameter에 대한 이야기는 추후에 좀더 자세히하도록 하자.
그 다음값은 GC에 소요된 시간이다.
<그림 5>의 GC로그를 보면 Minor GC가 일어날때마다 약 20,000K 정도의 Collection이 일어난다. Minor GC는 Eden과 Suvivor영역 하나를 GC하는 것이기 때문에 New/Young 영역을 20,000Kbyte 정도로 생각할 수 있다.
Full GC때를 보면 약44,000Kbyte에서 1,749Kbyte로 GC가 되었음을 볼 수 있다. Old영역에 큰 데이타가 많지 않은 경우이다. Data를 많이 사용하는 Application의 경우 전체 Heap이 512이라고 가정할때, Full GC후에도 480M정도로 유지되는 경우가 있다. 이런 경우에는 실제로 Application에서 Memory를 많이 사용하고 있다고 판단할 수 있기 때문에 전체 Heap Size를 늘려줄 필요가 있다.
이렇게 수집된 GC로그는 다소 보기가 어렵기 때문에, 좀더 쉽게 분석할 수 있게 하기 위해서 GC로그를 awk 스크립트를 이용해서 정제하면 분석이 용이하다.
<표 2. gc.awk 스크립트>
이 스크립트를 작성한후에 Unix의 awk 명령을 이용해서
% awk ?f gc.awk GC로그파일명
을 쳐주면 아래<표 3>와 같이 정리된 형태로 GC 로그만 추출하여 보여준다.
<표 3. gc.awk 스크립트에 의해서 정재된 로그>
Minor와 Major는 각각 Minor GC와 Full GC가 일어날때 소요된 시간을 나타내며, Alive는 GC후에 남아있는 메모리양, 그리고 Freed는 GC에 의해서 collect된 메모리 양이다.
이 로그파일은 excel등을 이용하여 그래프등으로 변환해서 보면 좀더 다각적인 분석이 가능해진다.
※ JDK 1.4에서부터는 ?XX:+PrintGCDetails 옵션이 추가되어서 좀더 자세한 GC정보를 수집할 수 있다.
※ HP JVM의 GC Log 수집
HP JVM은 전체 heap 뿐 아니라 ?Xverbosegc 옵션을 통해서 Perm,Eden,Old등의 모든 영역에 대한 GC정보를 좀더 정확하게 수집할 수 있다.
Example ) java ?verbosegc ?Xverbosegc MyApplication ß (HP JVM Only)
HP JVM의 GC정보는 18개의 필드를 제공하는데 그 내용을 정리해보면 <표 4.>와 같다.
<GC : %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 %17 %18>
<표 4. HP JVM GC 로그 필드별 의미>
이 로그를 직접 보면서 분석하기는 쉽지가 않다. 그래서, HP에서는 좀더 Visual한 환경에서 분석이 가능하도록 HPJtune이라는 툴을 제공한다. 다음 URL에서 다운로드 받을 수 있다.
http://www.hp.com/products1/unix/java/java2/hpjtune/index.html
<그림 6. HP Jtune을 이용해서 GC후 Old영역의 변화 추이를 모니터링하는 화면>
6. GC 관련 Parameter
GC관련 설정값을 보기전에 앞서서 ?X와 ?XX 옵션에 대해서 먼저 언급하자. 이 옵션들은 표준 옵션이 아니라, 벤더별 JVM에서 따로 제공하는 옵션이기 때문에, 예고 없이 변경되거나 없어질 수 있기 때문에, 사용전에 미리 JVM 벤더 홈페이지를 통해서 검증한다음에 사용해야한다.
1) 전체 Heap Size 조정 옵션
전체 Heap size는 ?ms와 ?mx로 Heap 사이즈의 영역을 조정할 수 있다. 예를 들어 ?ms512m ?mx 1024m로 설정하면 JVM은 전체 Heap size를 application의 상황에 따라서 512m~1024m byte 사이에서 사용하게 된다. 그림2의 Total heap size
메모리가 모자를때는 heap을 늘리고, 남을때는 heap을 줄이는 heap growing과 shirinking 작업을 수행하는데, 메모리 변화량이 큰 애플리케이션이 아니라면 이 min heap size와 max heap size는 동일하게 설정하는 것이 좋다. 일반적으로 1GB까지의 Heap을 설정하는데에는 문제가 없으나, 1GB가 넘는 대용량 메모리를 설정하고자 할 경우에는 별도의 JVM 옵션이 필요한 경우가 있기때문에 미리 자료를 참고할 필요가 있다.
※ IBM AIX JVM의 경우
%export LDR_CNTRL=MAXDATA=0x10000000
%java -Xms1500m -Xmx1500m MyApplication
2) Perm size 조정 옵션
Perm Size는 앞에서도 설명했듯이, Java Application 자체(Java class etc..)가 로딩되는 영역이다. J2EE application의 경우에는 application 자체의 크기가 큰 편에 속하기 때문에, Default로 설정된 Perm Size로는 application class가 loading되기에 모자른 경우가 대부분이기 때문에, WAS start초기나, 가동 초기에 Out Of Memory 에러를 유발하는 경우가 많다.
PermSize는 -XX:MaxPermSize=128m 식으로 지정할 수 있다.
일반적으로 WAS에서 PermSize는 64~256m 사이가 적절하다.
3) New 영역과 Old 영역의 조정New 영역은 ?XX:NewRatio=2 에 의해서 조정이 된다.
NewRatio Old/New Size의 값이다. 전체 Heap Size가 768일때, NewRatio=2이면 New영역이 256m, Old 영역이 512m 로 설정이 된다.
JVM 1.4.X에서는 ?XX:NewSize=128m 옵션을 이용해서 직접 New 영역의 크기를 지정하는 것이 가능하다.
4) Survivor 영역 조정 옵션
-XX:SurvivorRatio=64 (eden/survivor 의 비율) :64이면 eden 이 128m일때, survivor영역은 2m가 된다.
5) -server와 ?client 옵션
JVM에는 일반적으로 server와 client 두가지 옵션을 제공한다.
결론만 말하면 server 옵션은 WAS와 같은 Server환경에 최적화된 옵션이고, client옵션은 워드프로세서와 같은 client application에 최적화된 옵션이다. 그냥 언뜻 보기에는 단순한 옵션 하나로보일 수 있지만, 내부에서 돌아가는 hotspot compiler에 대한 최적화 방법과 메모리 구조자체가 아예 틀리다.
○ -server 옵션
server용 application에 최적화된 옵션이다. Server application은 boot up 시간 보다는 user에 대한 response time이 중요하고, 많은 사용자가 동시에 사용하기 때문에 session등의 user data를 다루는게 일반적이다. 그래서 server 옵션으로 제공되는 hotspot compiler는 java application을 최적화 해서 빠른 response time을 내는데 집중되어 있다.
또한 메모리 모델 역시, 서버의 경우에는 특정 사용자가 서버 운영시간동안 계속 서버를 사용하는게 아니기 때문에 (Login하고, 사용한 후에는 Logout되기 때문에..) 사용자에 관련된 객체들이 오래 지속되는 경우가 드물다. 그래서 상대적으로 Old영역이 작고 New 영역이 크게 배정된다. <그림 7. 참조 >
○ -client 옵션
client application은 워드프로세서 처럼 혼자 사용하는 application이다. 그래서 client application은 response time보다는 빨리 기동되는데에 최적화가 되어 있다. 또한대부분의 client application을 구성하는 object는GUI Component와 같이 application이 종료될때까지 남아있는 object의 비중이 높기 때문에 상대적으로 Old 영역의 비율이 높다.
<그림 7. ?server와 ?client 옵션에 따른 JVM Old와 New영역>
이 두옵션은 가장 간단한 옵션이지만, JVM의 최적화에 아주 큰부분을 차지하고 있는 옵션이기 때문에, 반드시 Application의 성격에 맞춰서 적용하기 바란다.
(※ 참고로, SUN JVM은 default가 client, HPJVM는 default가 server로 세팅되어 있다.)
○ GC 방식에 대한 옵션
GC 방식에 대한 옵션은 앞에서도 설명했지만, 일반적인 GC방식이외에, Concurrent GC,Parallel GC,Inceremental GC와 같이 추가적인 GC Algorithm이 존재한다. 옵션과 내용은 앞장에서 설명한 “다양한 GC알고리즘” 을 참고하기 바란다.
7.JVM GC 튜닝
그러면 이제부터 지금까지 설명한 내용을 기반으로 실제로 JVM 튜닝을 어떻게 하는지 알아보도록 하자.
STEP 1. Application의 종류와 튜닝목표값을 결정한다.
JVM 튜닝을 하기위해서 가장 중요한것은 JVM 튜닝의 목표를 설정하는것이다. 메모리를 적게 쓰는것이 목표인지, GC 횟수를 줄이는것이 목표인지, GC에 소요되는시간이 목표인지, Application의 성능(Throughput or response time) 향상인지를 먼저 정의한후에. 그 목표치에 근접하도록 JVM Parameter를 조정하는것이 필요하다.
STEP 2. Heap size와 Perm size를 설정한다.
-ms와 ?mx 옵션을 이용해서 Heap Size를 정한다. 일반적으로 server application인 경우에는 ms와 mx 사이즈를 같게 하는것이 Memory의 growing과 shrinking에 의한 불필요한 로드를 막을 수 있어서 권장할만하다.
ms와mx사이즈를 다르게 하는 경우는 Application의 시간대별 memory 사용량이 급격하게 변화가 있는 Application에 효과적이다.
PermSize는 JVM vendor에 따라 다소 차이가 있으나 일반적으로 16m정도이다. Client application의 경우에는 문제가 없을 수 있지만, J2EE Server Application의 경우 64~128m 사이로 사용이 된다.
Heap Size와 Perm Size는 아래 과정을 통해서 적정 수치를 얻어가야한다.
STEP 3. 테스트 & 로그 분석.
JVM Option에 GC 로그를 수집하기 위한 ?verbosegc 옵션을 적용한다. (HP의 경우 ?Xverbosegc 옵션을 적용한다.)
LoadRunner나 MS Strest(무료로 MS社의 홈페이지에서 다운로드 받을 수 있다.)와 같은 Strest Test툴을 통해서 Application에 Strest를 줘서. 그 log를 수집한다. 튜닝에서 있어서 가장 중요한것은 목표산정이지만, 그만큼이나 중요한것은 실제 Tuning한 Parameter가 Application에 어떤 영향을 주는지를 테스트하는 방법이 매우 중요하다. 그런 의미에서 적절한 Strest Tool의 선정과, Strest Test 시나리오는 정확한 Tuning을 위해서 매우 중요한 요인이다.
○ Perm size 조정
아래 그림8.은 HP JVM에서 ?Xverbosegc 옵션으로 수집한 GC log를 HP Jtune을 통해서 graph로 나타낸 그래프이다. 그림을 보면 Application이 startup되었을때 Perm 영역이 40m에서. 시간이 지난후에도 50m 이하로 유지되는것을 볼 수 있다. 특별하게 동적 classloading등이 수십m byte가 일어나지 않는등의 큰 변화요인이 없을때, 이 application의 적정 Perm 영역은 64m로 판단할 수 있다.
<그림 8. GC 결과중 Perm 영역 그래프>
○ GC Time 수행 시간 분석
다음은 GC에 걸린 시간을 분석해보자. 앞에 강좌 내용에서도 설명햇듯이. GC Tuning에서 중요한 부분중 하나가 GC에 소요되는 시간 특히 Full GC 시간이다.
지금부터 볼 Log는 모社의 물류 시스템의 WAS 시스템 GC Log이다. HP JVM을 사용하며, -server ?ms512m ?mx512m 옵션으로 기동되는 시스템이다.
그림 9를 보면 Peak 시간 (첫번째 동그라미) 14시간동안에 Full GC(동그란점)가 7번일어난것을 볼 수 있다. 각각에 걸린 시간은2.5~6sec 사이이다.
여기서 STEP 1.에서 설정한 AP Tuning의 목표치를 참고해야하는데.
Full GC가 길게 일어나서 Full GC에 수행되는 시간을 줄이고자 한다면 Old 영역을 줄이면 Full GC가 일어나는 횟수는 늘어나고, 반대로 Full GC가 일어나는 시간을 줄어들것이다.
반대로 Full GC가 일어나는 횟수가 많다면, Old 영역을 늘려주면 Full GC가 일어나는 횟수는 상대적으로 줄어들것이고 반대로 Full GC 수행시간이 늘어날 것이다.
특히 Server Application의 경우Full GC가 일어날때는 JVM자체가 멈춰버리기 때문에, 그림 9의 instance는 14시간동안 총 7번 시스템이 멈추고, 그때마다 2.5~6sec가량 시스템이 response를 못하는 상태가 된것이다. 그래서 멈춘 시간이 고객이 납득할만한 시간인지를 판단해야 하고, 거기에 적절한 Tuning을 해야한다.
Server Application에서 Full GC를 적게일어나게하고, Full GC 시간을 양쪽다 줄이기 위해서는 Old영역을 적게한후에, 여러개의 Instance를 동시에 뛰어서 Load Balancing을 해주면, Load가 분산되기 때문에 Full GC가 일어나는 횟수가 줄어들테고, Old 영역을 줄였기 때문에, Full GC에 드는 시간도 줄어들것이다. 또한 각각의 FullGC가 일어나는동안 하나의 서버 instance가 멈춰져 있어도, Load Balancing이 되는 다른 서버가 response를 하고 있기때문에, Full GC로 인한 Application이 멈추는것에 의한 영향을 최소화할 수 있다.
<그림 9. GC 소요시간>
데이타에 따라서 GC Tuning을 진행한후에는 다시 Strest Test를 진행해서 응답시간과 TPS(Throughput Per Second)를 체크해서 어떤 변화를 주었는지를 반드시 체크해봐야한다.
<그림 10. GC후의 Old 영역>
그림 10은 GC후에 Old 영역의 메모리 변화량을 나타낸다.
금요일 업무시간에 메모리 사용량이 올라가다가. 주말에가서 완만한 곡선을 그리는것을 볼 수 있다. 월요일 근무시간에 메모리 사용량이 매우 많고, 화요일에도 어느정도 메모리 사용량이 있는것을 볼 수 있다. 월요일에 메모리 사용량이 많은것을 볼때, 이 시스템의 사용자들이 월요일에 시스템 사용량이 많을 수 있다고 생각할 수 있고, 또는 다른 주의 로그를 분석해봤을때 이 주만 월요일 사용량이 많았다면, 특별한 요인이나 Application 변경등이 있었는지를 고려해봐야할것이다.
이 그래프만을 봤을때 Full GC가 일어난후에도 월요일 근무시간을 보면 Old 영역이 180M를 유지하고 있는것을 볼 수 있다. 이 시스템의 Full GC후의 Old영역은 80M~180M를 유지하는것을 볼 수 있다. 그래서 이 시스템은 최소 180M이상의 Old 영역을 필요로하는것으로 판단할 수 있다.
STEP 4. Parameter 변경.
STEP 3에서 구한 각 영역의 허용 범위를 기준으로 Old영역과 New 영역을 적절하게 조절한다.
PermSize와 New영역의 배분 (Eden,Survivor)영역등을 조정한다.
PermSize는 대부분 Log에서 명확하게 나타나기 때문에, 크게 조정이 필요가 없고 New영역내의 Eden과 Survivor는 거의 조정하지 않는다. 가장 중요한것은 Old영역과 New 영역의 비율을 어떻게 조정하는가가 관건이다.
이 비율을 결정하면서, STEP1에서 세운 튜닝 목표에 따라서 JVM의 GC Algorithm을 적용한다. GC Algorithm을 결정하는 기본적인 판단 내용은 아래와 같다.
이렇게 Parameter를 변경하면서 테스트를 진행하고, 다시 변경하고 테스트를 진행하는 과정을 거쳐서 최적의 Parameter와 GC Algorithm을 찾아내는것이 JVM의 메모리 튜닝의 이상적인 절차이다.
지금까지 JVM의 메모리 구조와 GC 모델 그리고 GC 튜닝에 대해서 알아보았다.
정리하자면 GC 튜닝은 Application의 구조나 성격 그리고, 사용자의 이용 Pattern에 따라서 크게 좌우 되기때문에, 얼마만큼의 Parameter를 많이 아느냐 보다는 얼마만큼의 테스트와 로그를 통해서 목표 값에 접근하느냐가 가장 중요하다.
미리 보는 미래 개발환경「자바SE 6
<그림 1> 숫자로 보는 자바 |
자바SE(Java Standard Edition)? |
자바 플랫폼 스탠다드 에디션에는 두 가지 주요 제품이 있다. Java SE Runtime Environment(이하 JRE)와 Java SE Development Kit(이하 JDK)가 그것이다. JRE는 자바 API, 자바 버츄얼 머신, 그리고 자바 프로그래밍 언어상에서 구동되는 애플릿과 애플리케이션에 필요한 컴포넌트이다. 자바SE는 또한 엔터프라이즈 소프트웨어 개발 및 디플로이를 위한 자바엔터프라이즈 에디션(Java EE)의 근간이기도 하다. JDK는 JRE상에 있는 모든 구성요소 외에도 애플릿과 애플리케이션을 개발하는 데에 필요한 컴파일러와 디버거 등의 툴도 포함한다.
<그림2> 자바 플랫폼 스탠다드 에디션 (Java SE) |
<그림 2>는 이러한 자바SE의 플랫폼상의 모든 컴포넌트 기술을 보여준다.
<그림 3> 자바SE의 로드맵 |
<그림 3>에서도 알 수 있듯이 자바플랫폼 스탠다드 에디션은 새로운 특장점이 소개될 때마다 약 18개월의 주기로 업데이트 된다. 그 외에도 매 8주에서 16주를 주기로 버그 수정이 업데이트 된다.
썬은 지난 2005년 자바원에서 J2SE의 이름을 자바SE로 변경했다. 이후 5.1과 6.1이라는 추가 버전 없이 오는 2006년 10월 발표 예정인 자바SE 6 이후에는 버그 수정에서부터 특장점까지 커뮤니티 상에서의 기여 및 참여를 통해 업데이트 되며, 자바SE 7(코드명: 돌핀)은 2008년 하반기에 발표할 예정이다.
자바SE 6(코드명: 머스탱)는 지난 2004년 발표한 자바SE 5.0(코드명: 타이거)의 버그를 수정하고, 기존 프로그램을 운영할 수 있도록 했다. 또 질적 향상을 위해 소스와 바이너리를 활용하여 개발자들이 보다 오픈된 환경에서 개발할 수 있도록 개선되었다. 자바SE 6는 호환성, 안정성, 질적 향상에 중점을 두어 개발되었다.
<표 1> JDK |
<표 2> 서버 벤치 마크:SPECjbb2000(기존 버전과 비교시 서버 벤치마크상 성능향상을 보여준다.) |
자바SE 6는 지속적으로 자바 성능 향상에 중점을 두고, 클라이언트, 서버 양쪽의 성능 향상, 코어 JVM (Java Virtual Machine, 자바 버츄얼 머신)으로의 업그레이드, GC 스케일링과 패럴리즘, 라이브러리 튜닝, 자바2D그래픽 렌더링으로의 업그레이드와 구동 속도를 높이는 등의 기능이 강화되었다(<표 1>과 <표 2> 참조). 그 외에도 모니터링과 관리기능을 중점으로 보다 나은 JVM레벨의 테스팅, 메모리 핸들링 향상, JMX업그레이드,솔라리스 Dtrac와의 연계 기능 향상과 J콘솔 업그레이드 등 모니터링 기능이 한층 강화되었다. (<화면 1> 참조)
<화면 1> J컨솔 업그레이드 |
이렇듯 자바SE 6는 고객들의 자바SE 의존도가 높은 만큼 호환성, 안정성, 질적 향상을 중점으로 최신 기술과 개발자들의 니즈를 반영하여 다양한 특장점이 업데이트 되고 있다. J2SE 1.4 버전이후에 자바 스탠다드 에디션의 중심에 있는 XML은 주요 데이터 교환 기술로 웹서비스의 근간이 되고 있다. 자바SE 6는 클라이언트 중심뿐만 아니라 경량의 서버에까지 적용되는 클라이언트 스택으로(JSR 105, 173,181, 222,224) 업데이트된 코어XML 스택을 포함한다.
또한, 개발 용이성을 주제로 개발자들이 보다 생산적으로 작업을 단순화할 수 있도록 스크립트 언어 지원 (JSR-223), XML데이터 지원을 포함한 JDBC 4.0 (JSR-221), 기타 API 등이 향상
되었다. 이외에도 데스크톱 자바는 모든 자바 성공에 있어 중요한 만큼 Java SE 6 또한 이러한 기능 향상을 포함하고 있다. 아발론 룩앤필을 포함한 윈도우 비스타 지원과 그동안의 자바 기술의 단점으로 지적되어 온 GUI를 개선하기 위해 윈도우 시스템의 트레이 기능 지원, 스플래시 스크린 지원, 그래픽 파이프라인 부스트 등 많은 GUI기능을 업그레이드했다.
자바SE 6는‘보다 공개된 (Open)개발 환경’(소스와 바이너리면에서)을 목적으로 많은 개발자들의 참여와 기여를 기다리고 있다. 이 같은 자바SE 6 (머스탱)의 성공적인 런칭과 구현을 위해서는 개발자들의 적극적인 커뮤니티 참여가 절실히 필요하다.
이러한 공동 참여와 기여를 통해 현 개발환경에서 필요한 개발자들의 니즈를 반영하여 새로운 특장점을 업데이트하고 버그를 수정하여 자바SE 6가 완성된다. 이러한 시도는 기존의 베타 버전과는 다른 새로운 경험 및 발상의 전환이 될 것이다. 참여 URL은‘mustang.dev.java.net’이다.
자바SE 6의 장점 |
자바SE 로드맵 상에서 볼 수 있는 자바SE 7(코드명: 돌핀)은 기존 자바SE 6(머스탱) 버전보다 더 개방된 환경에서 다이나믹한 언어를 지원할 뿐 아니라 확대된 XML 지원 기능과 보다 확대된 XML지원 등을 포함할 예정이다. 자바SE 7의 새로운 주요 특장점들은 10월 Java SE 6 출시이후에 보다 자세한 내용이 공개될 예정이다.
<그림 4>Mustang Features |
야생마 자바SE6 길들이기 |
이번에는 자바SE 6의 새로운 기능 중의 하나인 트레이(Tray) API를 이용한 예제를 살펴보자. 여기에서 트레이란 윈도우 GUI에서 태스크바(Taskbar) 오른쪽에 자리 잡는 작은 기능성 아이콘들이 들어가는 자리를 말한다. 보통 늘 떠 있어야 하는 애플리케이션들이 화면에 작게나마 현재 상태를 나타내고자 할 때 쓰인다. 예를 들어 메신저 창을 닫아도 메신저의 상태와 새 메시지 도착 등을 알리는 창구가 된다.
트레이에 아이콘을 두는 것은 윈도우 애플리케이션에 있어 사용자의 주목을 쉽게 끌 수 있고, 태스크바를 감추지 않는 이상 늘 떠 있어 자주 쓰는 기능의 호출에 대한 접근성을 향상시키는 장점이 있다. 따라서 자바 애플리케이션도 이런 트레이 아이콘을 가질 수 있다면 더욱 풍부한 사용자 경험을 제공할 수 있음은 두말할 나위도 없다. 원래 트레이 API는 JDIC(JDesktopI ntegration Components)라는 프로젝트의 일환으로, J2SE 1.4.2 이상이면 쓸 수 있는 부가 라이브러리로 시작했지만, 자바SE 6에는 기본 탑재되었다. 따라서 다음과 같이 패키지 이름만 다를 뿐 API 자체는 동일하므로 이제 소개할 예제를 간단히 포팅 할 수 있다.
JDIC Mustang
org.jdesktop.jdic.tray.SystemTray => java.awt.SystemTray
org.jdesktop.jdic.tray.TrayIcon => java.awt.TrayIcon
<리스트 1>은 본래 제우스 5를 부트.다운할 때 사용하려고 만든 것을 제우스 6 용으로 재구성한 것이다. 이 달의 디스켓 파일을 다운로드 받아서 압축을 푼 뒤에 핵심이 되는 코드를 살펴보자.
우선 이렇게 짧은 코드로 트레이를 사용하는 애플리케이션을 만들 수 있다는 점이 놀랍다. 자바가 플랫폼에 독립적이기 때문이 트레이가 지원되는 OS(현재는 윈도우와 유닉스 일부)인지를 확인한 다음, 보통의 스윙(Swing) 애플리케이션처럼 아이콘용 이미지를 읽어 들이고 동작에 필요한 액션 리스너를 만다. 마지막으로 시스템 트레이에 트레이 아이콘을 추가하면 끝난다(아이콘 이미지는 예제 프로젝트 파일에 포함되어 있다). 이 애플리케이션을 실행시키는데 필요한 스크립트인 jeus-tray.bat은 다음과 같다.
%MUSTANG_HOME%\bin\java -cp bin ias.tray.JeusTray%JEUS_HOME% %*
이 배치 파일을 실행하려면 MUSTANG_HOME 환경 변수를 자바SE 6 설치 디렉토리로 잡아 줘야 한다. 예를 들어 다음과 같이 하면 된다.
set MUSTANG_HOME=c:\java\sdk\jdk6
JEUS_HOME은 제우스를 설치하면 자동으로 잡히므로 추가적으로 설정할 필요는 없다. jeus-tray.bat를 실행할 때에는 세 개의 인수를 넘겨주어야 한다.
jeus-tray xias jeus jeus
첫 번째 인수는 제우스가 설치된 노드 이름(보통은 컴퓨터 이름이다), 나머지 인수는 제우스 관리를 위한 어드민의 사용자 이름과 암호이다. 이렇게 제우스 제어를 위한 정보를 알려줘야 부트.다운이 가능하다. 실행시키면 다음과 같은 아이콘이 트레이에 표시된다.
<화면 2> 제우스 트레이가 뜬 상태 |
에서 마우스 오른쪽 버턴을 누르면 아래와 같은 메뉴가 나온다.
<화면 3> 제우스 트레이 명령 선택 |
<화면 4> 제우스가 부팅된 상태를 가리키는트레이 아이콘 |
앞서는 빨간색으로 X가 되던 부분이 부트가 되고 나면 녹색 진행 표시로 바뀐다. 물론 down을 선택하면 다시 X가 표시된다.
down 기능을 쓰기 위해서는 예제 프로젝트 파일에 동봉된 jeusdown. bat를 JEUS_HOME/bin에 넣어두어야 한다.
아주 간단한 예제지만, 그 활용처는 무궁무진하고 리눅스와 솔라리스에서도 쓸 수 있어 윈도뿐만 아니라 다양한 GUI 환경에서 트레이의 편리함을 누릴 수 있다는 점이 매력적이다. 앞으로 자바 메신저나 RSS 리더에서 멋지게 사용되기를 기대해본다.
자바 브랜드 강화 및 미래 |
2005년으로 탄생 10주년을 맞은 자바는 이를 기념하기 위해 자바 브랜드를 새롭게 단장했다. 더욱 쉽고 심플한 디자인의 자바브랜드는‘한번 쓰면 어디에든 적용된다’는 주제 하에 전 세계적으로 PC와 휴대폰을 포함해 약 80%이상의 무선 애플리케이션 상에 적용되고 있다는 점이 많은 제조사와 컨슈머 고객사들이 자바 브랜드를 선호하는 이유다.
8세부터 80세까지, 200여개의 언어의 모든 사람들이 사용하는 자바 브랜드(로고)는 이러한 자바의 역사를 대변하고 있다. 보다 단순화된 자바 로고와 이름은 약 180여개의 자바 라이센서들의 샘플 집단에서 인터뷰를 거쳐 완성되었다.
| ||||||||
| ||||||||
|
이렇듯 자바는 브랜드에서부터 기술의 발전에 이르기까지 개발자들의 참여와 기여를 통해 하나의 생태계로서 발전하고 있다.
<그림5> 자바 플랫폼의 성장과 미래 |
마지막으로 현재 개발환경이 스탠다드 에디션이든 엔터프라이즈 에디션이든 더욱더 단순하면서도 풍부한 자바 기술의 향상을 위해서는 자바 개발자라는 공동체내에서 개발자들의 커뮤니티 참여가 무엇보다도 중요하다(<그림 5> 내용 참조). @
* 이 기사는 ZDNet Korea의 제휴매체인 마이크로소프트웨어에 게재된 내용입니다.
JDK 5.0 에서의 새로운 변화
JDK 5.0 에서의 새로운 변화
JDK 5.0에서는 프로그래밍의 유연함을 좀더 향상시키기 위해서 여러 가지 기능들이 개선되고 추가되었다. 이번 절에서는 JDK 5.0 에 오면서 변화된 여러 기능을 알아보자. 그렇지만 자바를 처음접하는 이들에게는 전혀 이해가 안 되는 얘기들일 것이다. 따라서 모든 내용을 이해할 생각을 하지 말고 그냥 "이런 것이 있구나!"하고 참고적으로 알아두길 바란다. 그렇다고 그냥 넘어가지 말자. 이전 버전과 비교해서 달라진 부분을 알고 있다면 향후 프로그래밍을 할 때 크게 도움을 받을 수 있기 때문이다.
less..
예전부터 자바 커뮤니티의 기대를 받아왔던 제네릭 타입(Generic Type)이 드디어 JDK 5.0 버전의 일부로 포함되었다. 제네릭 타입이 적용된 것을 Collection API에서 가장 먼저 찾아볼 수 있다. Collection API 는 Linked List, ArrayList, 그리고 HashMap과 같이 하나 이상의 클래스가 공통으로 사용할 수 있는 기능들을 제공한다.
JDK 5.0 버전 이전의 Collection API 에서는 COllection 객체를 Onject 클래스에 저장하기 때문에 컴파일 타임에 발생하는 타입 오류(Type Mismatch)을 확인할 수 없다. 이러한 문제는 런타임할 때 ClassCastException이 발생하는 형태로 확인해야 하므로 Collection에 대입된 자료의 확인 여부를 어쩔 수 없이 런타임할 때까지 유도해야만 확인할 수 있었다.
하지만 JDK 5.0에서는 이러한 번거로움을 탈피하기 위해서 일반화된 API를 사용하려면 컴파일 할 때 단지 <> 사이에 사용할 자료 타입을 선언해주기만 하면 캐스팅은 더 이상 할 필요가 없다. 나아가서 사용된 Collection에 삽입되는 객체의 자료타입이 잘못 대입될 경우, 이젠 런타임 때가 아닌 컴파일 때에 확인할 수 있다. 예를 들어, 옷을 직접 입지 않고 옷의 사이즈를 확인하는 것만으로 내게 맞는 옷인지 확인할 수 있게 된 것이다.
2. 메타데이터
JDK 5.0에 포함된 ‘메타데이터(Metadata)' 기능을 통해 자바 클래스, 인터페이스, 메서드, 그리고 필드(변수나 상수) 등에 추가적인 정보들을 부과할 수 있게 되었다. 이 추가적인 정보는 javac 컴파일러 외에도 여러 툴로부터 읽어 들일 수 있으며 설정하기에 따라 클래스 파일에 저장할 수도 있고 Java Reflection API를 통해 런타임할 때에 접근할 수도 있다.
아무래도 메타데이터가 JDK 5.0에 추가된 주된 이유는 여러 개발 툴과 런타임 툴간의 공통된 인프라를 구축함으로써 프로그래밍과 개발에 소요되는 수고를 덜고자 하기 위함이라 볼 수 있다.
3. 개선된 루프
Collection API의 iterator는 상당히 자주 사용되는 객체다. 이는 Collection 내에서 이동하는 기능을 제공하는데, 개발을 하다보면 이런 Collection 들과 배열들을 반복적으로 사용할 때가 많다. 하지만 iterator와 인덱스 변수들로 인해 복잡함과 다소 불편함을 느낄 때가 많다. ‘개선된 루프(Enhanced for Loop)'는 그런 불편함에서 나올 수 있는 오류 발생 가능성을 줄여준다. 컴파일러는 필요한 루프 코드를 생성하게 되고, Generic Type을 함께 사용하게 되면 더 이상 일일이 자동 형 변환(casting)을 해주지 않아도 되므로 프로그래밍을 하는 데 더욱 더 편해진다.
예를 들어, 기차를 탈 때와 비슷하다. 기차를 이루는 각각의 호차들마다 번호표가 있게 마련인데, 호차마다 이 번호표가 없다고 가정해보자. 그렇다면 모든 승객들이 맨 앞의 기차부터 일일이 숫자로 세어 자신이 배정받은 호차에 타게 되는 불편함이 있게 된다. 그리고 숫자로 호차들을 세다가 중간에서 잘못 세게 되면 다른 사람 자리로 모든 호차들을 미리 나열화하고 그 호차들에게 번호표를 미리 붙여놓음으로써 불편함을 줄여놓은 것이다. JDK 5.0에서 얘기하는 ‘개선된 루프’가 바로 이와 비슷한 반복적 비교문을 강화한 것이다.
[이전버전]
for(int i=0 ; i<10 ; i++)
System.out.println(ar[i]);
[JDK 5.0]
for(string n : ar)
System.out.println(n);
위 예문과 같이 [이전버전]에서는 int형 변수 i와 같은 index값을 사용하여 배열의 요소들을 참조하는 데 사용한다. 하지만 배열의 길이가 만약 9개라면 6장에서 배우게 되는 예외 중 하나인 ArrayIndexOutBoundsException이 발생하게 된다. 하지만 [JDK 5.0]에서 제공되는 개선된 루프를 사용하게 되면 내부적으로 나열화 작업이 자동적으로 이루어지므로 [이전버전]의 예문과 같이 예외에 대한 우려는 하지 않아도 된다.
4. 오토박싱 / 언박싱
int 또는 bollean 과 같은 기본 자료형(primitive Type)과 이에 상응하는, 즉 Integer 또는 Boolean과 같은 Wrapper 클래스 타입간의 자료 변환 작업이 EO로는 불필요할 정도의 많은 코딩을 요구하는 경우 있다. 특히 Collection API 중 메서드의 인자로서 사용하기 위한 경우라면 더더욱 골치 아픈 일이 될 수 있었는데, JDK 5.0 에서는 int와 Integer같의 변환 작업을 컴파일러가 맡아서 처리하므로 불필요함을 크게 줄이게 되었다.
간단하게 예를 들자면 어느 날 집으로 새로운 컴퓨터가 배달되었다. 기분이야 두말하면 잔소리지만 포장을 뜯는 것이 여간 신격 쓰이는 것이 아니다. 물론, “기분이 날아갈 듯한데 그게 무슨 대수냐?”라는 생각이 들지도 모른다. 하지만 고객이 원한다면 이런 “포장까지 깔끔하게 서비스 해주는 택배회사가 있다면...”이라는 생각을 한 번쯤은 해봤다(아마 대박이 날지도 모를 일이다.) JDK 5.0 에서는 이런 귀찮은 변환 작업을 자동적으로 제공하는데, 이를 ‘오토박싱/언박싱(Autoboxing/Unboxing)'이라 하는 것이다.
이전 버전에서는 Ingeter 클래스의 내부값을 int로 가져오려면 그러한 일을 해주는 특정 메서드를 호출해야만 하는데, JDK 5.0으러 오면서 그런 수고를 덜었다.
[이전버전]
Integer iTest = new Integer(500);
int i = iTest.intValue();
[JDK 5.0]
Integer iTest = new Integer(500);
int i = iTest;
간단히 정리하면, 위 예문의 핵심은 마치 객체가 기본 자료형에 대입되는 것처럼 보이지만 이때 변환작업을 컴파일러가 알아서 해준다는 것이다.
5. static import
static import 기능은 ‘import static'의 형태로 사용되는데, 이를 통해 클래스로부터 상속받지 않고 또는 해당 클래스를 일일이 명시하지 않고도 static 상수들에 접근할 수 있다. 다시 말해 기존과 같이 BorderLayout.CENTER라고 사용할 필요 없이 JDK 5.0에서 ’import static'을 적용한 이제부터는 단순히 CENTER라고만 해도 사용할 수 있다는 것이다.
[이전버전]
JPanel p1 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
[JDK 5.0]
import static java.awt.FlowLayout.*;
...
JPanel p1 = new JPanel(new FlowLayout(RIGHT));
위의 [이전버전]과 [JDK 5.0]의 예문이 너무 간단하여 [JDK 5.0]에서 크게 유익한 점을 못 느낄 수도 있다. 하지만 실제 예제를 다루게 되면 그렇지가 않다. 하지만 실제 예제를 다루게 되면 그렇지가 않다. 또는 System.out.println("..."); 이라는 문장이 많이 사용될 경우 out까지를 static import로 미리 적용해두면 코드의 내용이 상당히 편리해질 것이다.
6. Formatter과 Scanner
이제 JDK 5.0 버전에서는 Formatter 클래스가 제공되는데, 이를 C style format imput / output 이라 하여 C 언어에서 사용되었던 printf 형태의 기능이 추가되어 정형화된 출력을 할 수 있게 되었다. 더 나아가 이로써 같은 텍스트 형태를 유지하면서 큰 수정 작업 없이 C 언어의 응용프로그램으로부터 소스를 물려받아 자바로의 변환(migration)도 쉽게 할 수 있다. 다음은 예문이다.
System.out.printf("%s %5d%n", "총점:“, 500);
이 예문처럼 %로 시작하는 포맷 형식을 설정하고 그 형식에 맞도록 정형화된 출력을 목적으로 하는 것이 Formatter다.
Scanner 클래스는 기존에 사용되었던 Stream들에 없었던 파싱(parsing) 기능을 부여하여 효율적으로 자료를 유입하기 위한 클래스다. 기존의 Stream들은 Character 기반의 Stream인 BufferedReader를 쓴다하더라도 한 번에 한 줄씩 읽어 들이는 수 밖에 없었다. 하지만 Scanner 클래스를 사용하면 한 번에 전체를 읽어 들일 수도 있으며, 때에 따라서는 한 줄 단위로 읽을 수도 있다. 이러한 것들은 Pattern 클래스 또는 문자열로 되어 dLT는 구분자의 패턴을 useDelimiter()라는 메서드로 간단하게 변경하여 유연성을 높이고 있다.
7. Varargs(Variable Arguments)
JDK 5.0 이전의 버전에서는 특정 메서드를 정의할 때 인자(argument)의 타빙과 수를 정해두고 호출할 때 전달되는 인자의 수가 일치하지 않을 경우에는 메서드를 호출할 수 없었다. 이런 문제로 인해 많은 개발자들이 오버로딩법 또는 메서드에 배열객체로 인자를 지정하고 배열 객체를 사용하여 이 문제를 해결했지만 매번 호출할 때의 배열화 작업이 너무 불편했던 것이 사실이다.
이제 varargs 기능을 사용하여 여러 개의 인자를 매개변수(parameter)의 형태로 전달할 수 있다. 인자로 받는 메서드에서 ‘...’이라고 명시를 해주면 이를 통해 메서드를 수행하는데 필요한 인자의 수를 유연하게 구현할 수 있다.
[이전버전]
class VaraTest {
public static void test(Object args){
System.out.println(args);
}
public static void main(String args[]){
test("Java5");
test("Java5", " Varargs", " Test!"); // 인자 전달에 대한 오류!
}
}
[JDK 5.0]
class HelloWorld {
public static void test(Object ... args){
for(int i = 0 ; i < args.length ; i++) {
System.out.print(args[i]+",");
}
System.out.println();
}
public static void main(String args[]){
test("Java5");
test("Java5", " Varargs", " Test!");
test(new Integer(1000), new Float(3.14));
}
}
[출력결과]
Java5,
Java5, Varargs, Test!,
1000,3.14,
이전 버전에서는 인자의 수만 달라도 컴파일 오류가 발생했다. 하지만 JDK 5.0 에서는위처럼 Varargs 법을 사용하게 되면 보는 것과 같이 인자가 한 개이든, 세 개이든 인자의 수를 유연하게 받아주는 특징이 있어 작업의 효율을 높일 수 있다.
8. Simpler RMI interface generation 기법
원격 인터페이스에 대한 stub를 생성하는 데 있어서 더 이상 rmi 컴파일러인 rmic를 사용할 필요가 없으므로 RMI 기법을 더욱 더 간편하게 사용할 수 있게 되었다. Dynamic Proxy가 소개됨에 따라 stub가 제공하는 정보는 이제 런타임할 때 찾을 수 있게 되었기 때문이다.
이외에도 JVM 관련 기능들과 프로토콜을 감시하는 모니터링 기능 그리고 JDBC RowSets 등 여러 기능이 추가되고 개선되었다. 하지만 이 책의 수준에 맞춰 이 정도의 소개로 마무리하며 JDBC Rowstes 과 같이 꼭 알아야 하는 것들은 해당되는 장에서 소개한다.
대충의 JBoss-4.2.3 GA 릴리즈 노트 정리
Notes:
JBoss AS 4.2.3.GA Release Notes
이번 릴리즈는 JBoss Application Server v4.2 시리즈의 세번째 버그 픽스 릴리즈이다. 이 릴리즈는 커뮤니티에서 보고된
JBossAS v4.2.x릴리즈에 대한 버그를 수정한 것이다. 이전 버전인 4.2.0/4.2.1/4.2.2에 대한 하위버전 호환성이 있으므로
그냥 업그레이드 해도 된다. 자세한 내용은 상세 릴리즈 노트 섹션을 참고하십시오.
이 릴리즈의 두번째 목정은 Java6에 대한 지원이 향상되었다는 것이다. JBossAS 4.2.3.GA는 JDK5와 JDK6을 이용하여 빌드가
가능하다. JDK5 컴파일된 바이너리는 엄격한 테스트를 거쳐서 안정성을 보장할 수 있고, Java 5&6 VM에서 동작한다.( JDK6에 대해서
약간의 설정 변경이 필요하다. 아래를 참조 ) JDK6으로 컴파일된 버전은 JDBC 4 API를 지원한다. 그러나 지금 시점에서는 실험적이라고
생각한다.
JBoss AS 4.2 는 5.대 버전으로 넘어가는 과정에 있고, 5.대의 좋은 기능들을 (4.대 커널에 맞추어) 일부 적용하고 있다.
JBoss AS 4.2는 또한 JBoss Enterprise Application Platform의 중심축이다. JBoss AS와 JBoss Seam이 패키징되어 제공되는 상용 Application
플랫폼은 JBoss/Red Hat에 의해 제공된다. 자세한 정보는 Sacha의 블로그를 읽어보시라.
Java EE 1.4 를 구현한 API에 대한 내용은 Java EE v1.4 문서에 있다. Java EE 1.4에 대한 깊은 이해가 필요하면,Java EE™ 1.4 Tutorial를 읽어보라.
jboss-4.2.x 시작하기 안내 문서는 JBoss Application Server 문서 목록에 포함되어 있다.
Note: 4.2.x 릴리즈에서는 EJB3같은, 일부 JavaEE5 기능을 제공한다. 그러나 이는 Java EE5 인증을 받지 않았다.
Overview
* Highlights
* Known Compatibility Issues
* Known Configuration Issues
* JBoss/Thirdparty Library Updates
* Detailed Release Notes
* Additional Docs and Help
* Licenses
* About JBoss
Highlights of JBoss AS 4.2 series
* JBoss EJB3는 기본적으로 JBossAS 4.2.x에 포함되어 배포된다. JDK5에 기반하고 있기 때문에, 좀더 편리한 점이 있다. 더 이상
jdk1.4 런타임용 소스를 관리하지 않아도 된다. 기본적으로 jdk5에서 실행된다고, 가정한다.
* JBoss Web v2.x는 JBossAS 4.2에 포함되는 웹 컨테이너이고, Apache Tomcat에 기반하여 구현되었다. Tomcat에는 Apache Portable Runtime(APR)이 포함되고,
Apache Http 서버에 필적하거나 능가하는 tomcat의 native 대용량 처리와 성능 관련 특징들이 포함되어 있다.
이 native 라이브러리가 없으면 JBoss Web은 표준 non-native connector mode로 동작한다. native library는 별개로 다운로드하여 JBOSS_HOME/bin/native에 설치해야한다.
* Jboss Transactions v4.2는 JBossAS 4.2의 기본 트랜잭션 관리자이다. Jboss 트랜잭션은 18년간 산업현장에서 분산 트랜잭션분야의 선두로 이요되었고 검증되었다.
JBoss 트랜잭션의 JTA버전은 완전히 복구 가능한 트랜잭션을 제공한다. 분산 트랜잭션 지원을 위해서 JBoss 트랜잭션의 JTS버전이 필요하다.
또한, 언제나 과거의 JBossTM fast in-memory transaction manager 로 되돌릴 수도 있다. (단,구버전은 더이상 지원이 없을 것이다.)
* JBoss WS는 JBoss 4.2와 함께 제공되는 웹 서비스 스택이다.
* JGroups/JBossCache는 필요한경우 이용할 수 있는, 채널 다중화 를 제공한다.
* JBoss Remoting는 최신 2.2.x버전으로 업그레이드 되었다. 이는 새로운 JBoss Messaging을 필요로 하는 써드파트 라이브러리에 대한
의존성을 해결하기 위한 것이다. 즉, 특별한 개발 없이 JBossMQ 메시징 프로바이더를 JBoss Messaging으로 바꿀수 있다는 의미이다.
Compatibility Issues
This lists the changes that could affect compatibility.
우리의 제품 버전 원칙에 의해 JBossAS 4.2.3는 4.2.x 버전과 완벽히 일치한다. 그러나, 개별적인 JBoss나 써드파티 라이브러리 역시 그런지
확인하고 싶을것이다. 이전 버전의 JBoss 릴리즈와 관련된 이슈에 대해 다음에 대해 체크할 필요가 있다. :
(신버전 설치와 무관하므로 패스함)
JBossAS 4.2.2.GA
* JBossWS 1.2.1 supported JAX-WS only as a technology preview while JBossWS 2.0.1 used in AS 4.2.2 provides full
JAX-WS support. If you have used in your code the annotation org.jboss.ws.annotation.WebContext this must be
replaced by org.jboss.wsf.spi.annotation.WebContext.
* JBoss WS 1.0.x due to a deployer limitation used a proprietary .jse extension for deploying WS endpoints
nested in .sar files. This was deprecated with JBoss WS 1.2.x. and with JBoss WS 2.x this proprietary extension is
not supported anymore as it is possible to use the standard .war extension for deploying nested WS endpoints. If you
see: INIT_WAITING_DEPLOYER error messages for .jse files, re-package them using a .war extension, JBWS-1854.
* Another known limitation is that EJB3 web service endpoints can only be specified using annotations and not
metadata in jboss.xml. This is something that will be addressed in a future release, JBAS-4852, JBWS-1813.
* Finding the default local business interface on a ejb3 bean may not work in certain inheritance scenarios.
You may workaround this known problem by annotating the local business interface. Read more about this at EJBTHREE-1062.
* EJB Timer related fixes, JBAS-3379, JBAS-4053.
* JBossMQ related fixes, JBAS-4525, JBAS-4555, JBAS-4559, JBAS-4607, JBAS-4625, JBAS-4699
* JSP compiler now set to compile JDK 1.5 source code by default, JBAS-4605.
* The mail-ra.rar resource adapter was missing from the distro, JBAS-4659.
* HSQLDB (which shouldn't be used in production) v1.8.0.8 has a known bug when used in server mode,
JBAS-4694. This doesn't affect the default jboss installation where HSQLDB is used in in-process mode.
* Serialization of HomeHandleImplIIOP has changed. In the unlikely case of a compatibility problem, define the
system property
-Dorg.jboss.proxy.ejb.old.homehandle.serialization=true
to fall back to the legacy serialization mode, JBAS-4801.
JBossAS 4.2.1.GA
* JBoss TS, the new default transaction manager will not let you enlist multiple 1-phase participants in the
same transaction. This was *not* the default behavior with the legacy JBoss TM that would log a warning and continue.
There are good reasons for this change, mainly to avoid heuristic outcomes in the case of system crashes, which is
the primary reason of using a transaction manager anyway! If your come across this problem you should try to fix it
by switching to XA resources or implementing some form of compensating transactions. However, if this is not option
and you are fully aware of the consequences you can override this behavior by setting com.arjuna.ats.jta.allowMultipleLastResources
to true in conf/jbossjta-properties.xml. For more details read the wiki on Multiple1PC, or consult the JBoss
Transactions documentation.
* A major problem related to the cleaning up of threads after user transaction timeouts was corrected in JBAS-4481.
If you happen to be using User Transactions make sure you follow the correct pattern for committing or rolling them back.
* Another serious classloading issue that could lead to a hanging JBoss with a 100% CPU utilization was fixed with JBAS-4441.
JBossAS 4.2.0.GA
* A JavaSE 5 runtime is required to run JBossAS 4.2. A full JDK with tools.jar support is no longer needed by
jboss, since JBoss Web packages the eclipse JDT compiler for compiling JSP pages and javassist has its own internal
compiler. JAVA_HOME can point to a JRE, JBAS-4161.
* When compared to previous 4.0.x releases, the various JBoss APIs should be stable but backwards compatibility for
individual component implementations may not be guaranteed, e.g. interoperating with another JBoss instance that uses
an older version of JGroups.
* Tomcat 6 is now bundled as part of JBoss Web. deploy/jbossweb-tomcat55.sar has been replaced by deploy/jboss-web.deployer.
* conf/log4j.xml has been renamed to conf/jboss-log4j.xml, to allow log4j.properties override from scoped
deployments, JBAS-1853.
* log4j and commons-logging have both been upgraded. commons-logging is patched in addition, JBAS-2823.
* Since the latest log4j includes a trace level, there is no need to reference the custom jboss TRACE level in
conf/jboss-log4j.xml configs, JBAS-4163.
Instead of: <category name="org.jboss.system"><priority value="TRACE" class="org.jboss.logging.XLevel"/></category>
you can use: <category name="org.jboss.system"><priority value="TRACE"/></category>
* Better integration with WebSphere MQ 5.x, JBAS-3183.
* The MyFaces JSF implementation has been replaced by the Glassfish JSF 1.2 one, JBAS-3897.
* Hibernate, hibernate-annotations and hibernate-entity-manager have all been upgraded. to v3.2.1.
* The default invoker for EJBs has been changed from the rmi-invoker to the unified-invoker, provided by JBoss
Remoting, JBAS-3950.
* Apache commons http-client and apache-codec were removed from jbossall-client.jar, JBAS-4365.
* The address that is stored in the host portion of the RMI codebase URL can now be set correctly, JBAS-3325.
* The java2ClassLoadingCompliance setting in jboss-web.xml was ignored; this has been fixed, JBAS-3047.
* In JBoss 4.2 the unified invokers based on JBoss Remoting are the default transport for accessing EJBs.
Using the unified invokers JBoss 4.2 can interoperate safely with JBoss AS 4.0.4.GA/4.0.5.GA, using the flag
-Djboss.remoting.pre_2_0_compatible=true on the JBoss 4.2.x side. For interoperating with older JBoss AS versions
(3.2.8.SP1 to 4.0.3.SP1) the legacy rmi or pooled invokers need to be used. See JBAS-4407 and the wiki page on JBoss
Version Compatibility.
Configuration Issues
This lists the changes that could affect configuration.
JBossAS 4.2.3.GA
* JBossAS 4.2.3.GA 는 Java5,Java6과 모두 사용될 수 있다. Java5로 컴파일된 바이너리가 메인 배포본이다. 이는 Java5&6환경에서
철저한 테스트를 거쳤다. Java6에서 실행할때는 다음 라이브러리를 JBOSS_HOME/client 에서 JBOSS_HOME/lib/endorsed directory로
복사해야한다. 그래야 JBossWS에서 JAX-WS 2.0을 사용할 수 있다.:
o jboss-jaxrpc.jar
o jboss-jaxws.jar
o jboss-jaxws-ext.jar
o jboss-saaj.jar
o jaxb-api.jar
* Sun Java 6과 이용할때, 문제가 발생하면 -Dsun.lang.ClassLoader.allowArraySyntax=true 를 사용하라.
Java6에서는 다른 몇가지 잠재적인 문제가 있다.:
o ORB getting prematurely destroyed when using Sun JDK 6 (see Sun Bug ID: 6520484)
o Unimplemented methods in Hibernate for JDK6 interfaces.
* Java6으로 컴파일된 JBossAS 4.2.3 에서는 확장 JDBC 4 API를 사용할 수 있다. 이는 Java6 환경에서만 사용가능하다.
수동으로 설정해야 하는 것은 없다. 단, 실험적인 상태라는 것을 명심해야한다.
JBossAS 4.2.2.GA
* Extensions to LdapExtLoginModule, JBAS-4619.
* Escape syntax for mysql and postgresql in jboss CMP, JBAS-4463.
* Introduced a new system property org.jboss.mx.loading.UnifiedLoaderRepository.notifyMode to
provide fine-grained control over the emission of notifications whenever Unified Classloaders are created.
Classloader leaks can appear if those notifications are send to remote jmx agents, so the usage of the flag can
avoid this problem, JBAS-4953.
JBossAS 4.2.1.GA
* %PATH% is not removed from java.library.path in the presence of JAVA_HOME/bin/native, so e.g. native jdbc
drivers can be loaded, JBAS-4418.
JBossAS 4.2.0.GA
* JBossAS now binds its services to localhost (127.0.0.1) *by default*, instead of binding to all
available interfaces (0.0.0.0). This was primarily done for security reasons because of concerns of users going to
production without having secured their servers properly. To enable remote access by binding JBoss services to a
particular interface, simply run jboss with the -b option. To bind to all available interfaces and re-enable the
legacy behaviour use -b 0.0.0.0. In any case, be aware you still need to secure you server properly.
* There now distinct properties to configure the various mcast ports, JBAS-4021.
* When running under Linux, run.sh forces the use of IPv4, due to a jdk bug, JBAS-4332.
* JBoss EJB3 is now included by default. If you don't need/want EJB3 support, simply remove deploy/ejb3.deployer.
* When using native libraries for JBoss Web store them in JBOSS_HOME/bin/native, which is automatically included
in the classpath, JBAS-4162.
* JBoss Transactions is the new default transaction manager in JBoss. It is configured in
conf/jboss-service.xml and has additional properties defined in conf/jbossjta-properties.xml. The transaction
log is stored by default at server/default/data/tx-object-store.
* If you are on Red Hat Linux, check out the changes in bin/jboss_init_redhat.sh, JBAS-4041.
* The JBossAS distributions usually include the installer (.jar), the sources (.tar.gz) and the canonical
binary release (.zip). Unzipping the binary distribution (.zip) with a native unzip utility will restore correctly
the executable permission in the /bin/*.sh files. However, unzipping using the JDK jar utility ignores the executable
bit, so this need to be set manually.
* bin/shutdown.sh no longer sources run.conf, JBAS-4155.
Library Updates
For a full list of the JBoss and thirdparty libraries used with JBoss AS 4.2.3 see build-thirdparty.xml.
JBossAS 4.2.3.GA
JBoss Library Updates
* javassist upgraded to v3.8.0.GA (from v3.6.0.GA)
* jboss cache upgraded to v1.4.1.SP9 (from v1.4.1.SP5)
* jboss jaxr upgraded to v1.2.0.SP1 (from v1.2.0.GA)
* jboss transactions upgraded to v4.2.3.SP7 (from v4.2.3.SP6)
* jboss ws upgraded to v3.0.1 / native v2.0.4 (from v2.0.1.SP2)
* jboss xb upgraded to v1.0.0.SP3 (from v1.0.0.SP1)
* jboss remoting upgraded to v2.2.2.SP8 (from v2.2.2.SP1)
Thirdparty Library Updates
* jfreechart upgraded to v1.0.2 (from v0.9.20)
* oswego-concurrent upgraded to v1.3.4-jboss-update1 (from v1.3.4-jboss)
* sun-jsf upgraded to v1.2_09-b01 (from v1.2_04_P02)
* codehaus-jettison was introduced at v1.0-RC2
JBossAS 4.2.2.GA
JBoss Library Updates
* javassist upgraded to v3.6.0.GA (from v3.5.0.GA)
* jboss aop upgraded to v1.5.6.GA (from 1.5.5.GA)
* jboss cache upgraded to v1.4.1.SP5 (from 1.4.1.SP3)
* jboss common upgraded to v1.2.1.GA (from v1.2.0.GA)
* jboss remoting upgraded to v2.2.2.SP1 (from v2.2.1.GA)
* jboss ts upgraded to v4.2.3.SP6 (from v4.2.3.SP5)
* jboss web upgraded to v2.0.1.GA (from v2.0.0.GA)
* jboss ws upgraded to v2.0.1.SP2 (from v1.2.1.GA)
* jboss xb upgraded to v1.0.0.SP1 (from v1.0.0.GA)
* jgroups upgraded to v2.4.1.SP4 (from v2.4.1.SP3)
Thirdparty Library Updates
* hsqldb upgraded to v1.8.0.8 (from v1.8.0.2)
* jacorb upgraded to v2.3.0jboss.patch5 (from v2.3.0jboss.patch4)
* oswego-concurrent upgraded to v1.3.4-jboss (from v1.3.4)
JBossAS 4.2.1.GA
JBoss Library Updates
* hibernate, upgraded to v3.2.4.SP1_CP01 (from v3.2.3.GA)
* jboss-ts14, upgraded to v4.2.3.SP5 (from v4.2.3.SP3)
* jboss-remoting, upgraded to v2.2.1.GA (from v2.2.0.SP4)
Thirdparty Library Updates
* jacorb, upgraded to v2.3.0jboss.patch4 (from v2.2.4jboss.patch1)
* sun-jsf, upgraded to v1.2_04_P02 (from v1.2_04_P01)
Changes:
Detailed Release Notes
JBossAS-4.2.3.GA
Feature Request
* [ JBAS-3051 ] change jmx console title to display the name of the jboss server configuration with the machine name
* [ JBAS-4156 ] [jmx-console] Add additional informatin to page header
* [ JBAS-4455 ] LoadBalancePolicy that tries to pin all requests associated with a tx to one server
* [ JBAS-4501 ] JBoss AS 4.2 won't build with JDK 1.6
* [ JBAS-4804 ] GenericHeaderAuthenticator injection of ssoid, sessioncookie name
* [ JBAS-4986 ] Remove compile-time dependency on Debugger from ClusterPartition
* [ JBAS-5035 ] MySQLValidConnectionChecker has driver name com.mysql.jdbc.Driver hard coded
* [ JBAS-5139 ] Support injection-target properties within service-ref declarations
* [ JBAS-5704 ] Provide JAAS credentials in org.jboss.ant.JMX task so that calls can be made to security protected MBeans
Bug
* [ JBAS-1901 ] web-console shows dead archives after redeploy
* [ JBAS-2477 ] Exception in web-console j2ee domain after undeploy of application
* [ JBAS-3402 ] Web Console and Firefox
* [ JBAS-3406 ] JMX Console throws 500 exception on regular expressions
* [ JBAS-3637 ] twiddle ignores environment properties when creating its InitialContext
* [ JBAS-4246 ] JBoss logo not displayed for web status when accessed from web console
* [ JBAS-4287 ] run.sh can consume 100% single CPU resources on Solaris
* [ JBAS-4343 ] NullPointerException causing bad password exception in LdapLoginModule when the role attribute is not set for a given entry
* [ JBAS-4453 ] SerializableResultSetMetaData did not have the classname for the column set.
* [ JBAS-4662 ] XADatasource property names are not using the javabean convention
* [ JBAS-4673 ] SARDeployer should throw an error if there is more than one loader repository
* [ JBAS-4753 ] ExternalContext can pass duplicate interfaces to Proxy.newProxyInstance(loader, interfaces, handler)
* [ JBAS-4766 ] HTTP session replication failover failures with async buddy replication
* [ JBAS-4805 ] InitialContextFactory.getHAContext() should not use hardcoded localhost for lookup
* [ JBAS-4815 ] UnifiedInvokerProxyHA - Client instance check and assignment should be atomic
* [ JBAS-4870 ] Redelivery flags not updated in case of JBossMQ node failure
* [ JBAS-4892 ] WebService ignores java.rmi.server.codebase system property
* [ JBAS-4897 ] CVE-2007-5461: Information Leak in Tomcat Webdav Servlet
* [ JBAS-4911 ] MSSQLValidConnectionChecker throws exception with MS SQL Server 2005 JDBC driver
* [ JBAS-4921 ] Web service deployment: web.xml modified to web.xml.org - Subsequent runs fail
* [ JBAS-4927 ] Code added in 4.2.1 breaks web app that works in 4.2.0
* [ JBAS-4934 ] JBossCacheWrapper should not re-use data gravitation option
* [ JBAS-4938 ] source tarball contains non free code
* [ JBAS-4943 ] jboss-ds_1_5.dtd is wrong
* [ JBAS-4945 ] Messages transfered from DLQ to working queue will never be resent to DLQ
* [ JBAS-4950 ] Transaction failover authorisation is broken within UnifiedInvokerHAProxy
* [ JBAS-4964 ] txFailoverAuthorizations should be keyed on transaction propagation context
* [ JBAS-4969 ] Security-domain name entry in options map causing exception in custom login modules
* [ JBAS-4975 ] Usage of read-ahead on-find with entity beans containing binary attributes (mapped to BLOB, VARBINAR, ...) breaks eager loading.
* [ JBAS-4994 ] ReplyHeaderFilter reports old versions: Servlet 2.4, Tomcat-5.5
* [ JBAS-5014 ] EJBMethodPermission implies should check for null methodname and methodSig==""
* [ JBAS-5015 ] Deploy entity beans in Oracle 11g on JBoss 4.2.1 and JBoss 4.2.1
* [ JBAS-5020 ] Incorrect system property usage in JMX console clustering service
* [ JBAS-5026 ] NPE in JvmRouteValve.handleJvmRoute
* [ JBAS-5049 ] NoInitialContextException on deployment of EAR that contains MDB and persistence.xml
* [ JBAS-5063 ] JBoss 4.2.2 doesn't work with JSF RI 1.2_07
* [ JBAS-5068 ] Possible NullPointerException in DistributedReplicantManager#_add()
* [ JBAS-5072 ] Fix null pointer exception when getting keys, values, or entry's in the ConcurrentHashmap
* [ JBAS-5080 ] Need to check transaction status on SQL operations
* [ JBAS-5091 ] BuddyCommunicationTimeout is too low
* [ JBAS-5105 ] PostgreSQL Entity Command for jdbc2pm is Not Working Properly
* [ JBAS-5108 ] Twiddle should print out 'invoke' results, even when no propertyeditor for the returned object is found
* [ JBAS-5109 ] Web context and servlet paramters not available in WebMetaData
* [ JBAS-5112 ] WebXMLRewriter leaks input stream
* [ JBAS-5127 ] Hardcoded partition name in cluster-examples-service.xml
* [ JBAS-5142 ] cmp2.x jdbc2 pm: missing a join in a collection path translating "member of"
* [ JBAS-5149 ] 'webservices' meta data (jboss.xml) not available for ejb3 web service endpoints
* [ JBAS-5189 ] Txn-Manager arjuna commits data after timeout in long transactions
* [ JBAS-5206 ] Can't start JBoss 5 with a pure JRE installation
* [ JBAS-5220 ] twiddle not displaying info regarding java.lang:* beans when
-Djavax.management.builder.initial=org.jboss.system.server.jmx.MBeanServerBuilderImpl is used .
* [ JBAS-5228 ] Race condition maintaining acknowledgements when pushing messages to the client
* [ JBAS-5275 ] org.jboss.test.security.test.XMLLoginModulesUnitTestCase failing on Z-servers
* [ JBAS-5317 ] org.jboss.test.security.test.HttpsUnitTestCase failing with the IBM jvm
* [ JBAS-5354 ] Need to improve error handling around thread pool errors
* [ JBAS-5364 ] UnifiedInvokerHAProxy can throw NullPointerException under load
* [ JBAS-5428 ] Addition of undocumented feature has caused a bug in normal behaviour
* [ JBAS-5431 ] PooledInvokerProxy is not using the TPC factory setup by the UserTransaction client
* [ JBAS-5444 ] remove twiddle.bat/shutdown.bat %ARGS% processing in favour of %*
* [ JBAS-5459 ] JDBCStartCommand fails with index already exists
* [ JBAS-5475 ] NullPointerException when no invoker proxy bindings configured
* [ JBAS-5479 ] SSLSessionInterceptor has a copy/paste error in invokeHome method
* [ JBAS-5492 ] ClusteredSingleSignOn dead member cleaner throws NPE
* [ JBAS-5502 ] Enabling JBossMQ XA recovery fails
* [ JBAS-5526 ] DB Connections established which fail check-valid-connection-sql do not immediatly close their connection
* [ JBAS-5528 ] If SingletonStatelessSessionInstancePool is used for a SLSB, container MBean state is reported incorrectly
* [ JBAS-5568 ] sample-binding.xml does not work for jboss-messaging-1.4
* [ JBAS-5571 ] When JBossMQ does XA recovery it should always write the XID to the log
* [ JBAS-5574 ] Don't log an error for BMT Stateful not completing their transactions
* [ JBAS-5608 ] Removing a session from a clustered sso entry removes all sessions
* [ JBAS-5612 ] MySQLValidConnectionChecker is not serializable
* [ JBAS-5613 ] OracleValidConnectionChecker is not serializable
* [ JBAS-5623 ] JMS ActivationSpec 'acknowledgeMode' does not follow spec recommendation
* [ JBAS-5639 ] org.jboss.test.util.test.PropertyEditorsUnitTestCase failing on Z-systems
* [ JBAS-5644 ] Incorrect containerName attribute setting in valves
* [ JBAS-5657 ] JSP source code exposure in jmx-console
* [ JBAS-5670 ] Using MessageConsumers with Message Selector make messages stuck in queue
* [ JBAS-5678 ] closed jdbc connection before transaction rollback is called
* [ JBAS-5696 ] removal of entity with self-referencing CMR and fk-constraint
* [ JBAS-5706 ] Default session metadata replication too infrequent
* [ JBAS-5735 ] Session not reliably bound to SessionReplicationContext if SecurityAssocationValve not present
Task
* [ JBAS-4148 ] Replace Gjt code used in the ejb 2.x validation phase
* [ JBAS-4424 ] WebAuthentication:Generate a SSOID
* [ JBAS-4811 ] Integrate the JBossWS core testsuite in the release QA
* [ JBAS-4874 ] Track JBoss and thirdparty dependencies for JBossAS 4.2.3
* [ JBAS-4876 ] Re-enable JGroups message bundling
* [ JBAS-4918 ] replace ${jboss.server.home.dir}/log references with ${jboss.server.log.dir}
* [ JBAS-5057 ] testsuite regression org.jboss.test.security.test.EJBPermissionUnitTestCase
* [ JBAS-5059 ] Update Service Binding configuration for JBossMessaging
* [ JBAS-5060 ] Upgrade jfreechart to v1.0.2
* [ JBAS-5088 ] Failing org.jboss.test.jbossmq.test.ConnectionConsumerErrorFiredUnitTestCase.testExceptionListenerFiredOnError (jrockit)
* [ JBAS-5094 ] org.jboss.test.jaxr.scout failures
* [ JBAS-5101 ] Re-enable JGroups message bundling
* [ JBAS-5210 ] Expose sub-pool statistics for Improved Management.
* [ JBAS-5226 ] ClientUserTransaction should be configured with Unified invoker
* [ JBAS-5331 ] AOP deployer should include pluggable instrumentor jar(s)
* [ JBAS-5402 ] Keep JBoss Cache jars out of default
* [ JBAS-5485 ] Add mdbsessionpoolclear testcase from EJB3
* [ JBAS-5648 ] Upgrade to jboss-jaxr-1.0.2.SP1
* [ JBAS-5650 ] Merge clustering fixes from EAP branch
* [ JBAS-5677 ] Add discussion of usage of FC to Clustering Guide
* [ JBAS-5702 ] Add JDBC4 support to DataSourceInterceptor
* [ JBAS-5710 ] Get the JBoss-AS-4.2.x-TestSuite-sun15 passing
* [ JBAS-5711 ] Get the JBoss-AS-4.2.x-TestSuite-jrockit15 passing
* [ JBAS-5712 ] Add JDBC4 support to Branch_4_2
* [ JBAS-5720 ] Get a JBoss-AS-4.2.x-TestSuite-sun15-sun16 going
* [ JBAS-5721 ] Get a JBoss-AS-4.2.x-TestSuite-sun16-sun16 going
* [ JBAS-5722 ] Get all the testsuites passing
* [ JBAS-5723 ] Verify JBoss-AS-4.2.x-CompatibilityMatrix
* [ JBAS-5724 ] Verify TCK1.4 tests are passing
* [ JBAS-5725 ] Verify EJB3 tests are passing
* [ JBAS-5726 ] Verify JBossWS testsuite
* [ JBAS-5731 ] JaxWS 2.0 / JaxWS 2.1 support for Branch_4_2
* [ JBAS-5748 ] Update links in ROOT.war/index.html
* [ JBAS-5750 ] Update the interoperability tests matrix with 4.2.2.GA client libs
* [ JBAS-5765 ] Make release notes for 4.2.3.GA
Sub-task
* [ JBAS-4875 ] Upgrade jboss transactions to 4.2.3.SP7 (from 4.2.3.SP6)
* [ JBAS-4877 ] Upgrade JSF to 1.2_08
* [ JBAS-4925 ] Upgrade jboss cache to 1.4.1.SP7 (from 1.4.1.SP5)
* [ JBAS-4933 ] Upgrade to jbossxb 1.0.0.SP3 (from 1.0.0.SP1)
* [ JBAS-4955 ] All the known bind address properties should be set to the default bind address
* [ JBAS-4962 ] Upgrade jboss remoting to v2.2.2.SP5 (from v2.2.2.SP1)
* [ JBAS-4981 ] Transaction variable is not reset in ejb2 inflow interceptor
* [ JBAS-4996 ] Upgrade jbossws to 2.0.4.GA (from 2.0.1.SP2)
* [ JBAS-5082 ] Add a transaction status interface for the connection manager and implement it in TxConnectionManager
* [ JBAS-5083 ] Add the transaction active check to the jdbc resource adapter
* [ JBAS-5084 ] Add the transaction active check to the jms resource adapter
* [ JBAS-5170 ] 4.2.x fix to get HA Singleton election policies working in heterogeneous topologies
* [ JBAS-5498 ] JDK6: org.jboss.test.security.test.LoginModulesUnitTestCase
* [ JBAS-5727 ] Upgrade javassist to 3.8.0.GA
* [ JBAS-5729 ] Upgrade jboss remoting to v2.2.2.SP8 (from v2.2.2.SP5)
* [ JBAS-5753 ] fix org.jboss.test.jbossmx.compliance.objectname.MalformedTestCase
* [ JBAS-5754 ] Get tests-webservice passing
* [ JBAS-5755 ] org.jboss.test.jca.test.StatisticsFormatterUnitTestCase.testXmlFormatterStatistics
* [ JBAS-5758 ] fix iiop tests
* [ JBAS-5764 ] Upgrade to the latest JSF implementation 1.2_09 (from 1.2_08)
* [ JBAS-5768 ] Upgrade JBoss Cache to 1.4.1.SP9
* [ JBAS-5769 ] Fix org.jboss.test.jca.test.BackgroundValidationUnitTestCase.testDeployedBackgroundValidationFailure
* [ JBAS-5770 ] fix 3 org.jboss.test.jca.test.JDBCStatementTestsConnectionUnitTestCase failures
* [ JBAS-5772 ] org.jboss.test.cluster.test/FamilyClusterInfoUnitTestCase(Default-TCP)/testSynchronization
Patch
* [ JBAS-4478 ] ignore local ant options when building
* [ JBAS-5073 ] fix build authenticated proxy (there seems to have been a cut and paste error at some point)
* [ JBAS-5527 ] jboss_4_0.dtd should include support for SingletonStatelessSessionInstancePool