달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
2007. 4. 27. 16:54

MVC 기반 게시판 만들기 그거/Java2007. 4. 27. 16:54

3년인가 4년만에 다시 웹질하면서

만들어 본 게시판이닷!

푸하하하.

소스파일은... 안 올린다. 내 맘이니까~ 캬캬

:
Posted by 뽀기
2007. 2. 23. 10:24

자바서비스넷의 기술자료 링크 그거/Tech2007. 2. 23. 10:24

안녕하십니까? 자바서비스넷 이원영입니다.
자바서비스넷(
http://www.javaservice.net) 커뮤너티에 올라온 글들 중 의미있는 기술자료
링크를 모아 보내드립니다.

또한 자바서비스넷이 (주)자바서비스컨설팅(
http://www.javaservice.com)으로 거듭나면서
저희들이 직접 개발한 국산 WAS성능관리툴 제니퍼 2.5를 소개드리고자 합니다. 주위에 알려주시고,
직접 사용해 보신 후 신랄한 피드백을 부탁드립니다.

[WAS 장애진단/통합성능관리툴 제니퍼 2.5 의 핵심기능]
http://www.javaservice.net/~java/bbs/read.cgi?m=resource&b=jscnews&c=r_p&n=1127241452

[자바서비스 성능진단 컨설팅 자료모음]
20  모사이트_메모리장애분석.doc
19  성능테스트단계에서의 제니퍼 활용.doc
18 [인터넷, 빈번한 Full GC로 인한 성능저하 사례]
17 [인터넷, 전반적으로 서비스 성능이 우수한 사례]
16 [인트라넷업무, 서비스 큐잉장애에 대한 병목구간 분석 사례]
15 XX사 OO시스템 개발단계에서의 장애요소분석
14 HH사 OOO시스템 성능진단 보고서
13 모모 사이트 성능진단보고서
12 모사이트 모시스템 성능 장애진단 결과보고서
11 OOO사 XXX 시스템 성능진단 결과보고서
10 BB사 XXX 시스템 성능장애진단 컨설팅 보고서
6 다운사이징 벤치마크테스트 및 플렛폼 이관 검증 컨설팅
4 성능테스트를 통한 한계 동시단말사용자 수 측정

[자바서비스넷 최근 IT 소식]
915 2010년의 기술과 산업
1071 선 "모든 SW 무료 제공" 선언
1022 CodeHaus releases Mule 1.0, an open-source ESB
953 차세대 데이터 베이스 프로그래밍 - SDO
987 티맥스, 국내 WAS 시장서 1위 차지
776 참여정부의 전자정부 로드맵

[프로젝트 실무 컨설팅]
1478 S/W아키텍트에 대한 권고
1363 긴급! 리소스 누수 현상 ㅜ.ㅜ
1341 바람직한 작명규칙법을 알고 싶습니다.
1316 [EJB]Stateless Session Bean의 갯수와 WAS 성능에 관하여
1309 EIP솔루션 선택에 대하여
1286 대용량 파일의 Sort관련
1263 웹 애플리케이션의 성능 분석
1230 웹사이트 개발시 필요한 문서 목록
1209 "MVC개발자 분리", "JUnit이용한 테스트"
1206 웹서비스(Web Service)가 뭔가요???
1174 오라클 cursor가 계속 쌓여만 갑니다. --;
1150 Unique number생성 문제점(WAS 3대 사용시)
1123 동시접속자 문제
1106 [질문] 코드성데이터의 클래스생성..
1062 OR Mapping 사례
1039 [질문] struts 프레임워크에 대해서...
997 LoadRunner 성능 테스트 방법론 자료
960 웹에서의 프레임웍 추천부탁드려요~ ^_^
933 자바의 이해하지못하는 프레임웤에 대하여
920 prepareStatement. 사용시 문제점...?
873 Hibernate?
845 리포팅툴에 관련된 질문입니다. 추천좀 해주세요.
786 인트라넷 환경 시스템 구축관련
688 여러 쇼핑몰들과의 Data교환
677 비동기 메시징과 동기 메시징에서의 queue처리방식?
644 J2EE 개발 툴, 방법론 최상의 조합은??

[성능관련 기술자 커뮤니티]
54 김균홍 대리님의 Mixed Throughput EQ.

[기술적 이슈에 대한 토론공간]
440 AJAX의 미래..
404 SOA 의 실증적인 모습이 무엇인지 궁금합니다.
397 ibatis를 대규모 프로젝트에 사용할때 문제점이 있을까요?
392 "차세대시스템"에 걸맞는 Application Architecture
342 이미 구성되어 있는 Server간(종류에 상관없이) file을 교환하게 만들기
332 Framework과 Architecture의 차이점을 설명해주세요
290 코드 인스펙션을 하시나요?
277 지능형 프로젝트 관리 시스템을 도입하려고 하는데요
218 Don't use StringBuffer!! Use String!!
199 비즈니스 컴포넌트에 대한 개인적의견
187 Re: 대량 데이타 온라인 배치성 업무
142 .NET J2EE 환경에 비하여 최대 331% 성능 입증
123 채팅서버구현 -쓰레드 동기화문제

[General Java Programming Tips]
683 실시간 접속 회원 현황 구현에 대해서...
673 이유를 모르겠습니다. (묵시적 캐스팅)
574 자바로 구현된 QuickSort 소스구합니다.
531 이런 알고리즘 아시는 분 ...
506 Generics in C#, Java and C++
503 자바 프로그램의 메모리 사용량 확인방법
496 [Book] J2EE™ Development without EJB™
495 [Book] Thinking in Java, 3rd ed. Revision 4.0
490 Functional programming in the Java language
467 자바 소스 내에서 다른 자바 소스를 컴파일 하는 방법이 궁금합니다.
453 아래 JAVA Non-blocking I/O에 관련된 자료입니다.
447 혹시 NIO에 대한 입문자료(?) 있을까요?
422 Thread Pool에 도전기
420 쉬프트 연산자 사용시의 암시적 형변환
413 길이가 2인 byte[] 에 {0x8E,0xF0} 를 담으려면?
349 시간안에 응답하지 않는함수는 에러로 뺄려면
340 new String(byte[]) 생성자의 위험성
328 TCP/IP Socket ObjectOutputStream.reset()
297 JUnit 테스트의 작성요령과 간단한 작성례
296 Design Patterns for Java
292 자바 어플리케이션 최적화
289 Effective Java Programming Language Guide -Joshua Bloch
280 OutOfMemory Error 해결방법...
276 DateFormat for Performance
269 이메일주소의 정확성 여부를 확인하는 자바 코드
260 Java Performance tip입니다.
259 Bitter Java - 안티패턴과리팩토링
248 IT Expert 자바 디자인 패턴& 리팩토링 샘플
245 DB 입출력 자동화 툴 - 피넛 0.9 공개
236 Double-checked locking과 Singleton 패턴
233 양력 <-> 음력 변환.
232 자바 소켓 및 쓰레드 정리
210 int 형 정수의 자리수 체크는???
209 *쓰레드에 안전한 싱글톤 클래스를 만드는 세가지 방법

[Java Servlet & JSP API 개발/코딩]
656 통합 게시판 Unicorn v0.9를 배포합니다
655 struts action mappings
570 Java beans에 대해...
502 JSF BOOK 1.0
494 Java Server Faces
407 이미지 섬네일(Thumbnail) 만들기
332 커넥션풀의 커넥션 갯수.
321 커넥션 객체는 사용이 완전히 끝난 후에 해제시켜라.
300 JSP/JSF와 XML/XSLT의 통합
297 OpenSymphony WebWork를 사용한 게시판
296 자카르타 Velocity를 이용한 게시판
293 JSP코드 작성요령 Code Conventions 한글판
270 EmotionalBrain.Protocol.Group1.V1 (Source v0.8)
250 [Tip] 브라우저/확장한글 인코딩(MS949, 샾햏잌)
240 HTTP POST Reqeust Java Socket Client

[EJB(Enterprise Java Beans)]
257 DDL2iBatis(Code Generator For iBatis) 프로그램 및 사용법
195 Core J2EE Patterns 컬러버젼 약간의 설명[이미지]
194 Bitter EJB
109 EJBean의 인스턴스 변수의 정보는 공유되는가?
102 CMP냐 BMP냐?

[WebService/SOAP/UDDI/WSDL/AXIS/XML]
321 SOAP 개발자를 위한 TCP Monitor
213 Tmocat Server와 XML-RPC연동 방법
111 WebService 아키텍쳐에 대해서
87 ebXML MSH 아키텍처 입니다.
77 2003년도 XML 예측 시장
66 웹서비스 적용 국책과제를 수행하려합니다.

[JDBC(Java Database Connectivity)]
400 PreparedStatement 로 실행하면 너무 느린데/분포도 (히스토그램) 문제입니다.
381 DB2/ JDBC/ PreparedStatement/ SQLCODE=-301
345 Oracle에서 executeBatch/return -2/ Re: AS400 JDBC 드라이버의 경우
339 varchar(4000) * 4 사용시 이상한점..
329 Sybase JDBC Driver PreparedStatement 메모리 증가
322 jdk1.4.2와 Microsoft SQL Server 2000 Driver for JDBC와의 문제
204 PreparedStatement 와 Statement 에 대한 고견을...
137 Oracle CLOB 긴글 입력
121 Bitmechanic 커넥션 풀 소개 문서

[Applet, SWING, AWT, SWT]
153 AIX 5.2, X-Window 상에서 Swing 컴포넌트 한글 깨짐 문제
145 Fw: 윈도우XP SP2, Applet Sign 이슈
131 자바 기술을 사용하여 사인드 애플릿 구현하기
128 Eclipse SWT GUI, 브라우져에서 구동하기
120 파일 업로드 애플릿(with Swing)
116 일본판 Windows에서 한글 문제
96 8 비트 BMP 이미지 만들기
82 import시 모든것(*) 는 어떤 의미를 가지는가?

[HTML/HTC/CSS/JavaScript]
192 Grid Control,Tree Control(JSP구현)소스공개
180 테이블 고정 어떻게 해야하나요?
155 브라우저에서 타이틀바 없애기 ..
141 자바스크립으로 디렉토리구조 트리구조 만들수있나요
130 input FileUpload시 "찾아보기.."버튼 대체 방법
125 모달 대화 상자(modalDialog) 예제
113 JavaScript로 구현한 HTML에디터...
102 Binary Behavior에 관하여..
71 HTTP QueryString의 SpecialCharacters Auto Fix
63 한글 또는 영문만이 존재하는지 체크하는 자바스크립트
56 버튼 죽여서 재전송 방지

[World Wide Web Information]
39 URLConnection에서 타임아웃을 세팅할수 있나요?
28 www.abc_def.com & Cookie/httpsession

[서블렛엔진(Tomcat, Resin, JServ, 환경설정, etc..)]
885 apache+resin jsp소스가 보여지는 현상
882 [Tomcat] 최대한 편하게 DBCP 사용해 보기
791 resin, AIX 5.2 64bit 컴파일/설치하기
787 Tomcat에서 MSSQL 2000 에 연동할때...
777 톰켓 4.1.xx 의 JSP include 한글문제 fix
784 NT Service로 기동할때 톰캣메모리설정이 안됩니다.
734 Apache2+JK2+Tomcat5 2개 로드밸런싱시키기
730 AIX 4.3.3 에서 Tomcat 자주 다운되는 현상 발생
721 Re: 톰캣 5.0 이상에서 get의 한글 문제는..
705 tomcat5 monitoring page
661 Heap Memory 늘리려면 catalina.bat의 어디를 수정해야 하나여?
652 Re: apache2.0.48 + tomcat5.0.18 + mod_jk2 완성!!!
612 tomcat4130버전 server.xml하고 web.xml파일 설정법 정리
519 JBoss 3.2.3 및 오라클 9.2연동법/다국어 코딩법

[elipse Project/Plugin]
105 [?] eclipse: 리모트 디버깅, 디플로잉...
78 이클립스에서 롬보즈(Lomboz)사용에 질문드립니다.
50 Eclipse 기능과 단축키들 정리해 보았습니다.
42 "토탈 이클립스" 미리 보기 원고(이클립스,SWT,PDE)

[Apache Struts Framework]
2 struts 프레임웍 사용의 효율성

[BEA/WebLogic Application Server]
1156 웹로직 8.1 모니터링 툴 WLMonitor 2.5 beta 입니다.

[Borland Enterprise Server]
28 J2EE/CORBA 상호 운용 Simplified IDL를 이용한 클라이언트 확장
24 [BES] BES 5.1 에서의 Clustering 관련 문서입니다

[Fujitsu Interstage Application Server]
105 [Interstage6]여러개의 머신에 EJB환경구축개요
104 Redhat 3.0 AS/ES 와 Java Thread에 관해 생각해야 할 문제
97 [ Interstage 6 ] 운영 가이드 및 TroubleShooting 가이드 자료
92 Re: Interstage V6 운영법 간단 정리 매뉴얼

[IBM WebSphere Application Server]
1537 Session Affinity,Session Persistence 와의 차이
1535 Re: Memory-to-memory 관련 문서입니다.
1516 WAS ND상에서 OS환경변수를 설정하기
1500 WSAD 5.1.2 문서 편집기 한글 문제 질문입니다.
1428 블루 스크린 뜹니다. was5.1 문의 드립니다.
1420 AS400에서 File in Use Error
1414 AIX에서 1G 이상의 힙사이즈 할당하기
1412 J2EE 어플리케이션에서 bottleneck을 검출하는 기법에 관한 문서입니다.
1406 DB Fail시 Connection Pool Failover 방안 문의
1567 Re: 웹스피어 : DB Fail-Over & Fail Back
1371 WebSphere3.5 -> 5.1 Upgrade 및 Migration 관련
1347 WAS5.0x: Function sequence error 해결
1313 WebSphere WebServices Gateway 설치 및 Deploy 동영상
1251 L4와 다수의 웹서버, 이미지 캐시 이슈
1247 "kca" for IBM JVM "core" analizing on AIX
1171 WebSphere App Server V5.1 초급 강의 자료 - 실습자료 포함
1149 Debugging WebSphere Application Server Version 5
1146 DB2 64bit Instance에대한 JDBC Driver 사용
1120 ReloadingEnabled(..ext.xmi) & Reload Enabled(console)
1092 WAS 5.x "분산가능" 옵션의 역할
1020 Re: WAS5.0 Base Edition에서 하나이상 서버만들기
969 웹스피어5.0 JNDI 캐싱 해제 옵션
934 WAS 5.0 Customized Error Reporter : error.jsp
932 JSP Re compile 설정은 어떻게 해야하는지 질문..
921 AppClient모듈에서 DataSource 사용기
890 WSAD/WAS 5.0 JSP 한글 깨짐 문제 정리
888 웹스피어 5.0 데이타베이스 연결 설정법
881 WAS5.0 관리콘솔 사용자암호 지정하기
874 WebSphere5.0 서버셋팅과 CMP Deploy방법(wsda5.0 이용하여)
122 WSAD에서의 개발 및 WAS로 deploy

[Marc Fleury's JBoss Application Server]
68 JBoss Admnin Guide 번역본
30 JBoss Guide 번역
25 Apache2.0과 Jboss3.2.x의 JK2 연동방법 및 DataSource 설정방법

[Unix/Linux/Network]
237 AIX, DNS우선순위 local->dns 설정
215 사용자별/프로세스별 시스템 자원 사용율 모니터링 쉘
202 AIX 시간 동기화
178 솔라리스 전원 자동 꺼짐 방지하기 (Solaris)
176 screen utility
174 솔라리스에서 자바 프로세스 띄우기 문의

[DataBase Management Systems]
267 oracle 10에서 정규식 사용하기
242 ORACLE RAC구성과 JDBC설정법에관한 질문

[JVM/JDK Issue]
142 Re: 요청하신 javacore분석결과 올립니다.
104 java.lang.OutOfMemoryError 의 case별 원인 파악및 해결방안 정리
102 IBM JDK HEAPDUMP가 solaris에도?
101 IBM JDK JIT 옵션
82 Re: Zip한글 해결방법
75 AIX IBM JDK 1.4.X reflection 반영시 나타나는 현상
67 IBM JAVA JDK 와 SUN JDK와의 비교되어있는거 없나요?
65 AIX JDK JNI 컴파일 옵션

[기타 자료실]
120 [AutoQuery 2005]다양한 기능을 제공하는 개발자 지원 Tool
116 SWT를 이용한 인터넷 영한사전 프로그램 JDic 0.7
109 [이클립스] 원격 또는 로컬의 로그파일 모니터링 플러그인
107 간단한 디카 사진 정리 프로그램...
98 Alzip보다 최대 2배 가까이 빠른 zip program.
95 [이클립스 플러그인] 원격 자동 업로드 FTP
64 조회,입력, 수정, 삭제 가 매우 쉬운 Grid & Sample

[자바서비스컨설팅/제니퍼 FAQ]
23 리퀘스트몬(requestmon) for Jennifer

[기타]
998 한국의 SI 수준은 이제 세계에서 경쟁력을 잃고 있다.
1050 어느 자바 개발자의 꿈...이원영 자바서비스컨설팅 대표
958 IT노동자 실태조사 자료 및 인터뷰 동영상
860 30대 은행원, 업무 스트레스 못 이겨 자살

[비기술적 이슈에 대한 토론공간]
611 돈 되는 개발이란?
350 [희승사화]여러분이 저라면 어떻게 하시겠습니까?
337 SI에서 개발자라는 것은.
328 아키텍터가 되기 위해서는 어떻게 해야 할까요?..
244 프리랜서 개발 단가..
188 용역단가에 대해서
114 IT(정보기술) 개발자들이 공무원들의 노예인가?(펌)
30 [KT목동사화] 경쟁업체 성능시험 방해 삼성SDS직원 둘 구속기소
1 프리랜서의 한계

[의견 나눔터/잡담]
1792 Object 관련 질문드립니다...(수정본)
1709 okjsp 에서 퍼온글...
1701 잡담
1690 Re: 컨설턴트가 되기 위해서는
1638 인생의, 선택의 문제앞에서. (조언을 부탁드립니다.)
1451 잠적하기 직전 개발자의 변(辨)
1446 [의중사화] Expert One-on-one J2EE 설계와 개발을 읽고 차의중씨에게...
1356 나이를 먹어가며...
1314 티맥스 소프트
1286 미국 환경은 어떤가요?.
1138 개발자의 정년
1109 [그냥 잡담]파견나간 일본회사
1093 50만원이 생긴다면 무엇을 하시겠습니까?
1002 노동자 대단결
944 고인의 명복을 빕니다.
796 추억의 놀이...
716 감동플러스..~~ㅡ_ㅜ
:
Posted by 뽀기
2007. 1. 30. 14:57

웹역량 Innovation 실습 (Java) 그거/Seminar2007. 1. 30. 14:57



| 웹역량 Innovation 실습 (Java)

채규태
2007-01-01 ~ 2007-01-31 (1 개월 20 시간 )
60,000 원 ( 고용보험적용 )
대 기 업 : 48,642원 / 우선지원 : 48,642원


※ 본 과정은 참고도서가 제공되는 과정입니다.(죄송하지만 해외 배송은 불가합니다)
※ 과정 취소시 받으신 도서는 e-Campus로 반송해 주셔야 합니다.


웹로직과 EJB(알기쉽게 풀어 쓴) : 한빛미디어


:
Posted by 뽀기
2007. 1. 29. 15:43

Java 5의 새로운 기능 그거/Java2007. 1. 29. 15:43

관련글
http://kwon37xi.egloos.com/2510988
http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html

by Jess Garms and Tim Hanson
2005/12/06

개요

Java 5.0은 이미 나와 있고, 많은 사용자들이 이번 릴리스의 JDK에 추가된 새로운 기능을 사용하기 시작할 것입니다. 이제 향상된 for loop 기능에서부터 generics와 같은 좀 더 복잡한 기능에 이르는 모든 기능이 코드 작성에 사용될 것입니다. 우리는 대규모의 Java 5.0 기반 작업을 방금 완료했으며, 이 문서에서는 이러한 여러 기능을 사용한 경험에 대해 이야기하고자 합니다. 이 문서에서는 단순한 소개를 넘어 기능에 대해 좀 더 깊이 있게 살펴보고 이 기능들이 실제 프로젝트에 미칠 영향과 이러한 기능들을 효과적으로 사용하기 위한 몇 가지 팁에 대해 알아보도록 하겠습니다.

소개

JDK 1.5의 베타 시험 기간 동안 우리는 BEA의 Java IDE용 Java 5 컴파일러를 사용해 보았습니다. 우리가 다양한 새 기능을 구현했던 것처럼 다른 사람들도 이 기능들을 새로운 방식으로 이용하기 시작했습니다. 일부는 훌륭하게 사용하였고 일부는 그렇지 못 했습니다. 컴파일러 자체가 새로운 기능을 사용하므로 우리는 이러한 기능을 사용하여 코드를 유지 관리하는 직접적인 경험을 얻을 수 있었습니다. 이 문서에서 이러한 여러 가지 기능과 이에 관련된 경험을 살펴보겠습니다.

이미 새로운 기능에 익숙하리라 생각되므로 각 기능에 대한 포괄적인 소개 대신, 흥미롭고 명확하게 표현되지 않은 함축적 내용 및 사용에 대해 살펴보겠습니다. 이러한 팁은 실행해 본 것 중에서 임의로 선택하여 언어 기능별로 대략적으로 분류한 것입니다.

가장 단순한 기능부터 시작해서 가장 고급 기능의 순서로 다룰 계획이며 Generics는 특히 이야기거리가 많은 주제이므로 이 문서의 반 정도를 할애할 것입니다.


Enhanced for Loop

향상된 새로운 for 루프는 컬렉션 및 배열에서 반복적으로 사용하기 위한 간단하면서도 일관된 구문을 제공합니다. 몇 가지 항목을 소개하면 다음과 같습니다.

Init 표현식

초기화 표현식은 루프 내에서 한 번만 값을 구하게 됩니다. 이것은 변수 선언을 삭제할 수 있음을 의미합니다. 이 예제에서 우리는 각 메서드가 루프를 통과할 때 해당 메서드의 값을 다시 구하지 않도록 하기 위해 Integer 배열을 만들어 computeNumbers()의 결과를 유지하도록 했습니다. 아래쪽 코드가 위쪽 코드에 비해 좀 더 명확하고 numbers 변수의 손실이 없습니다.

향상된 For가 없는 경우:

int sum = 0;
Integer[] numbers = computeNumbers();
for (int i=0; i < numbers.length ; i++)
    sum += numbers[i];

있는 경우:

int sum = 0;
for ( int number: computeNumbers() )
    sum += number;

제한

반복하는 동안 반복자 또는 인덱스에 액세스해야 하는 경우가 있습니다. 언뜻 보기에는 향상된 for 루프에서 이것을 허용되는 것처럼 보이지만 사실은 그렇지 않습니다. 다음 예제를 보겠습니다.

for (int i=0; i < numbers.length ; i++) {
    if (i != 0) System.out.print(",");
    System.out.print(numbers[i]);
}

배열에서 쉼표로 구분된 값 리스트을 출력하려고 합니다. 쉼표를 인쇄해야 할지 알아보려면 현재 첫 번째 항목에 있는지 여부를 알아야 합니다. 그러나 향상된 for를 사용하여 이런 정보를 얻을 방법이 없습니다. 인덱스를 유지하거나 첫 번째 항목을 이미 지나쳤는지 알려주는 boolean을 유지해야 합니다.

다음은 다른 예제입니다.

for (Iterator<integer> it = n.iterator() ; it.hasNext() ; )
    if (it.next() < 0)
        it.remove();

이 경우에는 Integers 컬렉션에서 음수 항목을 삭제하려고 합니다. 그렇게 하려면 반복자에서 메서드를 호출해야 하지만 향상된 for 루프를 사용할 경우 이러한 반복자는 숨겨집니다. 그러므로 Java 5 이전의 반복 메서드를 사용해야 합니다.

어쨌든 주의할 점은 Iterator는 Generic이므로 선언은 Iterator<Integer>이라는 것입니다. 많은 사람들은 이 사실을 놓치고 Iterator를 원시 형태로 사용합니다.


주석

주석 처리는 광범위한 주제입니다. 이 문서는 핵심적인 언어 기능에 대해 제한적으로 다루기 때문에 주석의 모든 가능성과 위험 요인에 대해서는 설명하지 않습니다.

그러나 내장된 주석(SuppressWarnings, Deprecated 및 Override) 및 일반적인 주석 처리의 제한 사항에 대해서 설명하도록 하겠습니다.

Suppress Warnings

이 주석은 클래스 또는 메서드 수준에서 컴파일러 경고 표시를 끕니다. 코드에서 더 이상 사용하지 않는(Deprecated) 메서드를 사용해야 하거나 정적으로는 typesafe인지 확인할 수 없지만 사실은 typesafe인 액션을 수행해야 한다는 것을 사용자가 컴파일러 보다 더 잘 알 수도 있습니다.

@SuppressWarnings("deprecation")
public static void selfDestruct() {
    Thread.currentThread().stop();
}

이것은 아마 가장 유용한 내장된 주석일 것입니다. 그러나 불행히도 javac는 1.5.0_04에서 이것을 지원하지 않습니다. 하지만 1.6에서는 지원되며, Sun은 이것을 1.5로 백포팅하는 중입니다.

이 주석은 Eclipse 3.1 및 다른 IDE에서도 지원됩니다. 이 주석을 사용하여 코드에 대한 경고가 발생하지 않도록 할 수 있습니다. 컴파일 시 경고가 표시된 경우, 이미 이 코드를 추가했으므로 다른 잘못된 코드가 있음을 알 수 있습니다. Generics를 추가하면 훨씬 더 좋습니다.

Deprecated

Deprecated는 아쉽게도 그다지 유용하지는 않습니다. 이것은 원래 @deprecated javadoc 태그를 대체하기 위한 것이지만 필드를 가지고 있지 않기 때문에 deprecated 클래스 또는 메서드 사용자에게 대안으로 사용하라고 알려줄 방법이 없습니다. 대부분 사용자는 javadoc 태그와 이 주석을 모두 필요로 합니다.

Override

Override는 이 주석이 달린 메서드가 슈퍼클래스에서 동일한 서명을 가진 메서드를 무시한다는 것을 나타냅니다.

@Override
public int hashCode() {
    ...
}

위의 경우를 예로 들면, hashCode에서 "C" 를 대문자로 쓰지 않은 경우 컴파일 시에는 오류가 표시되지 않지만 런타임 시에는 메서드가 예상했던 대로 호출되지 않습니다. Override 태그를 추가하면 실제로 override가 수행되지 않을 경우 컴파일러가 문제를 표시합니다.

또한 슈퍼클래스를 변경하는 경우 이것이 도움이 됩니다. 말하자면 이 메서드에 새 파라미터를 추가하고 메서드 자체의 이름을 바꾸면 하위 클래스가 슈퍼 클래스에서 더 이상 아무것도 무시하지 않기 때문에 컴파일에 실패하게 됩니다.

주석의 기타 정보

주석은 다른 상황에서 매우 유용할 수 있습니다. 주석은 동작을 직접 수정하지 않고 강화시킨 경우, 특히 보일러플레이트 코드를 추가하는 경우 EJB 및 웹 서비스 같은 프레임워크에서 가장 잘 작동합니다.

주석은 전처리기로 사용할 수 없습니다. 특히 Sun의 설계는 주석 때문에 클래스의 바이트 코드를 직접 수정하지 못하도록 했습니다. 이로써 언어의 결과를 제대로 이해할 수 있고 IDE같은 툴이 코드 심층 분석 및 refactoring 같은 기능을 수행할 수 있습니다.

주석은 완전한 해결책이 아닙니다. 처음 주석이 나타나면 사람들은 온갖 종류의 기술을 시도해 보려고 합니다. 다음을 살펴보겠습니다.

public class Foo {

    @Property
    private int bar;

}

여기서는 전용 필드 bar에 대해 getter 및 setter 메서드를 자동으로 생성하려고 합니다. 하지만 불행히도 이 생각은 다음과 같은 두 가지 이유에서 좋지 못합니다. 1) 이것은 작동하지 않으며, 2) 이 코드를 읽고 처리하기가 더욱 어려워집니다.

앞서 말한 바와 같이 Sun이 특별히 주석이 표시되는 클래스를 수정하지 못하도록 했기 때문에 이것은 실현될 수 없습니다.

가능하더라도 이 코드를 이해하기 더욱 어렵게 만들기 때문에 좋은 생각이 아닙니다. 이 코드를 처음 본 사람은 이 주석이 메서드를 생성한다는 생각을 하지 못할 것입니다. 또한 향후 이러한 메서드 중 하나에서 무언가를 해야 한다면 이 주석은 쓸모가 없습니다.

요약하자면 정규 코드로 할 수 있는 것에 주석을 사용하려고 하지 말라는 것입니다.


Enumerations

Enum은 수 년간 enum 값으로 사용되어온 public static final int 선언과 많이 유사합니다. int에서 가장 크고 확실하게 개선된 점은 type safe입니다. int와는 달리 enum 타입 중 한 가지를 다른 타입의 위치에 사용할 수 없습니다. 왜냐하면 컴파일러에게는 모든 것이 똑같아 보이기 때문입니다. 아주 드물게 예외가 있긴 하지만 이 경우에도 enum과 유사한 모든 int 구성을 enum 인스턴스로 교체해야 합니다.

Enum은 여러 가지 추가 기능을 제공합니다. 유틸리티 클래스인 EnumMap 및 EnumSet은 특히 enum에 최적화된 표준 컬렉션 구현입니다. 컬렉션에 enum만 포함되는 것을 알고 있다면 HashMap 또는 HashSet 대신 이러한 특정 컬렉션을 사용해야 합니다.

대부분의 경우 코드에서 모든 public static final ints를 enums으로 교체할 수 있습니다. enum은 비슷(Comparable)하고, 내부 클래스(또는 내부 enum)일지라도 이에 대한 참조가 똑같아 보이므로 정적으로 가져올 수 있습니다. enum을 비교할 때 선언되는 순서가 서수 값을 나타낸다는 사실에 유의하십시오.

"Hidden" 정적 메서드

작성한 모든 enum 선언에는 두 가지 정적 메서드가 표시됩니다. 이 두 가지 메서드는 Enum 자체가 아니라 enum 하위 클래스에 대한 정적 메서드이기 때문에 java.lang.Enum에 대한 javadoc에는 표시되지 않습니다.

첫 번째 values()는 enum에 가능한 모든 값의 배열을 리턴합니다.

두 번째 valueOf()는 제공된 문자열에 대한 enum을 리턴하는데, 원본 코드 선언과 똑같이 일치해야 합니다.

메서드

enums의 좋은 점 중의 하나는 메서드를 가질 수 있다는 것입니다. 과거에는 데이터베이스 타입을 JDBC URL로 번역하기 위해 public static final int에서 스위치를 수행한 코드가 필요했을 수 있습니다. 이제는 enum 자체에 직접 코드를 정리할 수 있는 메서드를 가질 수 있습니다. 다음은 DatabaseType enum에서 추상 메서드와 각 enum 인스턴스에 제공된 구현을 사용하여 이것을 어떻게 수행하는 지 보여주는 예제입니다.

public enum DatabaseType {
    ORACLE {
        public String getJdbcUrl() {...}
    },
    MYSQL {
        public String getJdbcUrl() {...}
    };
    public abstract String getJdbcUrl();
}

이제 enum에서 유틸리티 메서드를 직접 제공할 수 있습니다. 예를 들면 다음과 같습니다.

DatabaseType dbType = ...;
String jdbcURL = dbType.getJdbcUrl();

이전에는 URL을 얻기 위해 유틸리티 메서드가 있는 장소를 알려주어야 했습니다.


Varargs

varargs를 올바로 사용하면 정말로 거추장스러운 코드를 일부 정리할 수 있습니다. 다음과 같은 기본 예제는 String 인수를 다양하게 가진 로그 메서드입니다.

Log.log(String code)
Log.log(String code, String arg)
Log.log(String code, String arg1, String arg2)
Log.log(String code, String[] args)

varargs에 관한 설명에서 흥미로운 사실은 처음 4개의 예제를 새로운 vararged 예제로 교체하는 경우 얻어지는 호환성입니다.

Log.log(String code, String... args)

모든 varargs는 소스 호환적이어서 log() 메서드의 모든 호출자를 재컴파일하는 경우 4개의 모든 메서드를 바로 교체할 수 있습니다. 그러나 이전 버전과의 이진 호환성이 필요한 경우 처음 세 개는 그대로 두어야 합니다. 마지막 메서드에서만 Strings 배열을 가져오면 같은 값이 되므로 vararged 버전을 교체할 수 있습니다.

Casting

항목은 String이고 두 번째는 Exception일 것으로 예상할 수 있습니다.

Log.log(Object... objects) {
    String message = (String)objects[0];
    if (objects.length > 1) {
        Exception e = (Exception)objects[1];
        // Do something with the exception
    }
}

그 대신 메서드 서명은 vararg 파라미터에서 별도로 선언된 String 및 Exception 을 사용하여 다음과 같아야 합니다.

Log.log(String message, Exception e, Object... objects) {...}

지나치게 사용하려고 하지 마십시오. varargs를 사용하여 타입 시스템을 망가뜨릴 수 있습니다. 강력한 타입 지정(strong typing) 이 필요한 경우 사용하십시오. PrintStream.printf()은 이러한 규칙에 대한 예외입니다. 이것은 타입 정보를 나중에도 수용할 수 있도록 첫 번째 인수로 제공합니다.


Covariant Returns

공변(covariant) 리턴은 주로 구현의 리턴 타입이 API보다 일반적이지 않은 경우 캐스트를 방지하기 위해 사용됩니다. 다음 예제에서는 Animal 객체를 리턴하는 Zoo 인터페이스를 사용합니다. 이 구현은 AnimalImpl 객체를 리턴합니다. 그러나 JDK 1.5 이전에서는 Animal 객체를 리턴하도록 선언해야 했습니다.

public interface Zoo {
    public Animal getAnimal();
}

public class ZooImpl implements Zoo {
    public Animal getAnimal(){
        return new AnimalImpl();
    }
}

공변 리턴을 사용하면 다음 세 가지 anti-pattern을 바꿀 수 있습니다.

  1. 직접 필드에 액세스합니다. API 제한을 피하기 위해 일부 구현은 하위 클래스를 직접 필드로 제공합니다.
    ZooImpl._animal
  2. 추가 양식이 호출자에서 다운캐스트를 수행하므로 이 구현이 실제로 이러한 특정 하위 클래스임을 알 수 있습니다.
    ((AnimalImpl)ZooImpl.getAnimal()).implMethod();
  3. 마지막 양식은 완전히 다른 서명을 제안함으로써 이러한 문제를 피해가는 특수 메서드입니다.
    ZooImpl._getAnimal();

이러한 패턴은 모두 문제점과 제한이 있습니다. 보기에 안 좋거나 아니면 필요하지도 않은 구현 세부 정보를 제공합니다.

With covariance

공변(covariant) 리턴 패턴은 유지 관리가 더욱 간편하고 안전하고 편리합니다. 캐스트 또는 특수 메서드나 필드가 필요하지 않습니다.

public AnimalImpl getAnimal(){
    return new AnimalImpl();
}

결과 사용:

ZooImpl.getAnimal().implMethod();

Generics 사용

Generics 사용 및 Generics 구성이라는 두 가지 각도에서 Generics를 살펴보겠습니다. List, Set 및 Map의 사용에 관해서는 이야기하지 않겠습니다. 지금은 Generic 컬렉션에 대해서만 언급하도록 하겠습니다.

Generic 메서드 사용 및 컴파일러가 타입을 추론하는 방법에 대해 다룰 것입니다. 일반적으로는 이 정도의 내용만으로도 충분할 것입니다. 그러나 오류 메시지의 뜻을 이해할 수 있도록 문제의 해결 방법도 알아야 합니다.

Generic 메서드

generic 타입 이외에 Java 5에서는 generic 메서드를 도입했습니다. java.util.Collections의 예제에서는 싱글톤(singleton) 리스트을 구성합니다. 새로운 List의 엘리먼트 타입은 메서드에 전달된 객체의 타입에 기반하여 추론됩니다.

static <T> List<T> Collections.singletonList(T o)

이용 예제:

public List<Integer> getListOfOne() {
    return Collections.singletonList(1);
}

위 이용 예제에 int를 전달하면 메서드의 리턴 타입이 List가 됩니다. 컴파일러는 T에 대한 Integer를 추론합니다. 일반적으로 인수 타입를 명시적으로 지정해야 할 필요가 없기 때문에 이것은 Generic 타입과 다릅니다.

또한 이것은 autoboxing과 generics의 상호 작용도 보여줍니다. 인수 타입은 레퍼런스 타입이어야 합니다. 그것이 바로 List<Integer>가 아니라 List<int>를 얻게 되는 이유입니다.

파라미터가 없는 Generic 메서드

emptyList() 메서드는 java.util.Collections의 EMPTY_LIST 필드에 대한 type safe 대안으로서 Generics과 함께 도입되었습니다.

static <T> List<T> Collections.emptyList()

이용 예제:

public List<Integer> getNoIntegers() {
    return Collections.emptyList();
}

이전 예제와 달리 이것은 파라미터가 없으므로 T에 대한 타입을 컴파일러에서 어떻게 추론해야 할까요? 기본적으로 파라미터를 사용하여 한 번만 시도합니다. 실행된 것이 없을 경우 리턴 또는 할당 타입을 사용하여 다시 시도합니다. 이 경우 List<Integer>를 리턴하므로 T는 Integer로 추론됩니다.

리턴 문 또는 할당 문 이외의 위치에서 generic 메서드를 호출하면 어떻게 될까요? 그러면 컴파일러는 타입 추론의 두 번째 단계를 수행할 수 없습니다. 다음 예제에서 emptyList()가 조건부 연산자 내에서 호출됩니다.

public List<Integer> getNoIntegers() {
    return x ? Collections.emptyList() : null;
}

컴파일러는 리턴 컨텍스트를 볼 수 없고 T를 추론할 수 없으므로 포기하고 Object로 가정합니다. "cannot convert List<Object> to List<Integer>." 같은 오류 메시지가 표시됩니다.

이것을 수정하려면 메서드 호출에 인수 타입를 명시적으로 전달해야 합니다. 그러면 컴파일러는 인수 타입를 추론하려고 시도하지 않으므로 올바른 결과를 얻을 수 있습니다.

return x ? Collections.<Integer>emptyList() : null;

이런 상황이 자주 발생하는 또 다른 위치는 메서드 호출입니다. 메서드에 List을 사용하고 해당 파라미터에 대한 emptyList()를 전달하여 이것을 호출하려고 시도하는 경우에도 이 구문을 사용해야 합니다.

그 밖의 컬렉션

다음은 컬렉션이 아니라 새로운 방식으로 generics를 사용하는 세 가지 Generic 타입 예제입니다. 이 예제는 모두 표준 Java 라이브러리에 있는 것입니다.

  • Class<T>
    Class는 클래스의 타입에 파라미터화됩니다. 그러면 캐스팅 없이 newInstance를 구성할 수 있게 됩니다.

  • Comparable<T>
    Comparable 은 실제 비교 타입별로 파라미터화됩니다. 이것은 compareTo() 호출에 더욱 강력한 타입 지정을 제공합니다. 예를 들어, String은 Comparable<String>을 구현합니다. String 이외에서 compareTo()를 호출하면 컴파일 시 실패합니다.

  • Enum은 enum 타입별로 파라미터화됩니다. Color라는 enum은 Enum<Color>를 확장합니다. getDeclaringClass() 메서드는 enum 타입에 대한 클래스 객체를 리턴하는데, 이 경우에는 Color가 리턴됩니다. 이것은 익명의 클래스를 리턴할 수 있는 getClass()와는 다릅니다.

와일드카드

generics에서 가장 난해한 부분은 와일드카드를 이해하는 것입니다. 여기서는 세 가지 와일드카드의 타입 및 사용 목적에 대해 설명합니다.

먼저 배열 사용 방법을 살펴보겠습니다. Integer[]에서 Number[]를 할당할 수 있습니다. Float를 Number[]에 쓰려고 시도하면 컴파일은 되지만 런타임 시 ArrayStoreException에서 실패하게 됩니다.

Integer[] ia = new Integer[5];
Number[] na = ia;
na[0] = 0.5; // compiles, but fails at runtime

이 예제를 직접 generics으로 번역하려고 시도하면 할당이 허용되지 않기 때문에 컴파일 시 실패합니다.

List<Integer> iList = new ArrayList<Integer>();
List<Number> nList = iList; // not allowed
nList.add(0.5);

Generics을 사용하는 경우 경고 없이 컴파일하는 코드가 있으면 런타임 ClassCastException을 절대로 얻을 수 없습니다.

상한선 와일드카드

배열와 달리, 여기서 필요한 것은 정확한 엘리먼트 타입이 알려지지 않은 리스트입니다.

List<Number>는 엘리먼트 타입이 명확한 Number인 리스트입니다.

List<? extends Number>는 정확한 엘리먼트 타입이 알려지지 않은 리스트입니다. 이것은 Number 또는 하위 타입입니다.

상한선

원래 예제를 업데이트하고 List<? extends Number>에 할당하면 이 할당은 성공합니다.

List<Integer> iList = new ArrayList<Integer>();
List<? extends Number> nList = iList;
Number n = nList.get(0);
nList.add(0.5); // Not allowed

리스트의 정확한 엘리먼트 타입(Float, Integer 또는 Number)에 상관없이 Number를 할당할 수 있기 때문에 이 리스트에서 Number를 얻을 수 있습니다.

floats를 리스트에 삽입할 수는 없습니다. 그럴 경우 안전하다는 것을 입증할 수 없기 때문에 컴파일 시 실패합니다. 리스트에 float를 추가하면 Integer만 저장하는 iList의 원래 type safety를 위반하게 됩니다.

와일드카드는 배열을 사용하는 것보다 강한 표현력을 제공합니다.

와일드카드 사용 이유

다음 예제에서 와일드카드는 API의 사용자에게 타입 정보를 숨기는 데 사용됩니다. 내부적으로 Set은 CustomerImpl로 저장됩니다. API 사용자가 알고있는 전부는 Customers를 읽을 수 있는 Set을 얻게 될 것이라는 사실입니다.

여기서는 Set<CustomerImpl>에서 Set<Customer>로 할당할 수 없기 때문에 와일드카드가 필요합니다.

public class CustomerFactory {

    private Set<CustomerImpl> _customers;

    public Set<? extends Customer> getCustomers() {
        return _customers;
    }

}

와일드카드 및 공변(covariant) 리턴

와일드카드를 일상적으로 사용하는 또 다른 경우는 공변(covariant) 리턴입니다. 동일한 규칙이 할당되어 공변 리턴에 적용됩니다. overridden 메서드에서 더 특정한 generic 타입을 리턴하도록 하려면 선언하는 메서드에 반드시 와일드카드를 사용해야 합니다.

public interface NumberGenerator {
    public List<? extends Number> generate();
}

public class FibonacciGenerator extends NumberGenerator {
    public List<Integer> generate() {
        ...
    }
}

여기서 배열을 사용하면 인터페이스는 Number[]를 리턴하고 구현은 Integer[]를 리턴할 수 있습니다.

하한선

상한선 와일드카드에 대해 이미 설명했습니다. 하한선 와일드카드도 있습니다. List<? super Number>는 정확한 "엘리먼트 타입"이 알려지지 않은 리스트이지만 이것은 MNumber이거나 또는 Number의 수퍼 타입입니다. 그러므로 이것은 List<Number> 또는 List<Object>일 수 있습니다.

하한선 와일드카드는 상한선 와일드카드 만큼 일반적이지 않지만 필요한 경우 반드시 사용되어야 합니다.

하한선과 상한선 비교

List<? extends Number> readList = new ArrayList<Integer>();
Number n = readList.get(0);

List<? super Number> writeList = new ArrayList<Object>();
writeList.add(new Integer(5));

첫 번째 리스트은 숫자를 읽을 수 있는 리스트입니다.

두 번째 리스트은 숫자를 쓸 수 있는 리스트입니다.

제한 없는 와일드카드

마지막으로, List<?>는 모든 것의 리스트이며 List와 거의 동일합니다. 항상 Objects를 읽을 수 있지만 리스트에 쓸 수는 없습니다.

공용 API의 와일드카드

요약하자면 와일드카드는 몇 단원 전에 살펴본 바와 같이 호출자에게 구현 세부 정보를 숨기는 데는 아주 유용합니다. 그러나 읽기 전용 액세스를 제공하기 위해 하한선 와일드카드가 표시되더라도 remove(int position)같은 비-generic 메서드로 인해 그렇게 하지 못합니다. 정말로 불변하는 컬렉션을 원한다면 unmodifiableList()처럼 java.util.Collections에서 이 메서드를 사용하십시오.

API를 작성할 경우 와일드카드를 알아야 합니다. 일반적으로 generic 타입을 전달할 때 와일드카드를 사용해야 합니다. 그러면 API가 더 광범위한 호출자에게 액세스할 수 있습니다.

다음 예제는 List<Number> 대신 List<? extends Number>를 사용하여 아래의 메서드가 여러 가지 다양한 타입의 Lists를 사용하여 호출되도록 합니다.

void removeNegatives(List<? extends Number> list);

Generic 타입 구성

이제 generic 타입 구성에 대해 살펴보겠습니다. generic 타입 구현 시 발생하는 일반적인 문제 뿐만 아니라 generic을 사용하여 type safety를 향상시킬 수 있는 예제를 보여줄 것입니다.

컬렉션과 유사한 함수

generic 클래스의 첫 번째 예제는 컬렉션과 유사한 예제입니다. Pair는 두 개의 파라미터를 가지며 필드는 타입의 인스턴스입니다.

public final class Pair<A,B> {
    public final A first;
    public final B second;

    public Pair(A first, B second) {
        this.first = first;
        this.second = second;
    }
}

이것은 두 가지 타입으로 된 각각의 콤보에 대해 특수 목적의 클래스를 작성하지 않고 메서드에서 두 개의 항목을 리턴하도록 합니다. Object[]를 리턴하는 것도 할 수 있지만 그것은 타입이 안전하지 않거나 깔끔하지 않습니다.

아래 이용 예제는 메서드에서 File 및 Boolean을 리턴합니다. 메서드의 클라이언트는 캐스팅하지 않고 직접 이 필드를 사용할 수 있습니다.

public Pair<File,Boolean> getFileAndWriteStatus(String path){
    // create file and status
    return new Pair<File,Boolean>(file, status);
}

Pair<File,Boolean> result = getFileAndWriteStatus("...");
File f = result.first;
boolean writeable = result.second;

그 밖의 컬렉션

다음 예제에서 generic은 추가 컴파일 시 안전을 위해 사용되었습니다. 생성되는 Peer 타입별로 DBFactory 클래스를 파라미터화하면 Factory 하위 클래스가 Peer의 특정 하위 타입을 리턴하도록 할 수 있습니다.

public abstract class DBFactory<T extends DBPeer> {
    protected abstract T createEmptyPeer();

    public List<T> get(String constraint) {
        List<T> peers = new ArrayList<T>();
        // database magic
        return peers;
    }
}

DBFactory<Customer>를 구현하면 CustomerFactory는 createEmptyPeer()에서 Customer를 리턴하게 됩니다.

public class CustomerFactory extends DBFactory<Customer>{

    public Customer createEmptyPeer() {
        return new Customer();
    }
}

Generic 메서드

파라미터 간에 또는 파라미터와 리턴 타입 간의 generic 타입에 대한 제한을 두기 위해 generic 메서드를 사용할 수 있습니다.

예를 들어, 제자리에서 역행하는 리버스 함수를 작성하면 generic 메서드가 필요 없습니다. 그러나 리버스 함수가 새로운 List를 리턴하도록 하려면 새로운 List 의 엘리먼트 타입이 전달된 List와 동일해야 합니다. 그럴 경우 generic 메서드가 필요합니다.

<T> List<T> reverse(List<T> list)

Reification

generic 클래스를 구현할 때 배열 T[]를 구성할 수 없습니다. generics은 데이터 삭제에 의해 구현되기 때문에 배열 T[]를 구성할 수 없습니다.

또한 Object[]를 T[]로 캐스트하려고 시도하지 마십시오. 이것은 안전하지 않습니다.

Reification 솔루션

generics 자습서에 따르면, 이 솔루션은 "Type 토큰"을 사용합니다. 생성자에 Class<T> 파라미터를 추가하면 클라이언트가 클래스의 타입 파라미터에 대해 올바른 클래스 객체를 제공하도록 할 수 있습니다.

public class ArrayExample<T> {
    private Class<T> clazz;

    public ArrayExample(Class<T> clazz) {
        this.clazz = clazz;
    }

    public T[] getArray(int size) {
        return (T[])Array.newInstance(clazz, size);
    }
}

ArrayExample<String>을 구성하려면, String.class의 타입이 Class<String>이기 때문에 클라이언트는 String.class를 생성자에게 전달해야 합니다.

클래스 객체가 있으면 올바른 엘리먼트 타입을 사용하는 배열을 구성할 수 있습니다.

결론

한마디로 요약하면 이 새로운 기능은 Java에 근본적 변화를 가져왔습니다. 이러한 기능을 언제 어떻게 사용하는지를 이해하면 더 나은 코드를 작성할 수 있을 것입니다.

추가자료

Jess Garms은 BEA Systems의 Javelin 컴파일러 팀의 리더입니다. 그 이전에 Jess는 BEA의 Java IDE, WebLogic Workshop에 관여했습니다. 또한 그는 암호화 관련 경험이 상당히 풍부하며 Wrox Press에서 출판한 "Professional Java Security"를 공동 저술하기도 했습니다.

Tim Hanson은 BEA Systems의 Javelin 컴파일러 설계자입니다. Tim은 BEA의 Java 컴파일러(가장 초기1.5 호환 구현 중 하나)를 상당 부분 개발했습니다. 이외에도 그는 CORBA/IDL 컴파일러(IBM 재직 시) 및 XQuery 컴파일러를 비롯한 수많은 컴파일러를 작성했습니다.


Return to dev2dev.

:
Posted by 뽀기
2007. 1. 29. 15:33

오픈 소스 자바 심층 탐구 그거/Java2007. 1. 29. 15:33

Sun Software CTO이자 Distinguished Engineer인 Bob Brewin이 썬과 개발자, 그리고 고객에게 오픈 소스 자바 기술의 의미에 대한 자신의 견해를 들려드립니다

Bob Worrall, CIO, Sun Microsystems, Inc.Sun Inner Circle 독자 여러분 반갑습니다. 지난 달에 저는 썬의 CIO로서 가장 관심이 가는 문제 중 하나인 보안에 관해 얘기했습니다. 이번 달에는 자바 플랫폼을 오픈 소스 개발자 커뮤니티에 공개하기로 한 썬의 기념비적 결정을 평가하는 데 도움이 될 수 있도록 최근에 썬이 발표한 빅 뉴스 몇 가지에 대해 다루어볼까 합니다.

썬은 이미 자사의 소프트웨어 포트폴리오 전체를 오픈 소싱하겠다는 최종 약속을 천명한 바 있으며, 과거에도 썬은 OpenSolaris OS, NetBeans 소프트웨어, OpenOffice, GlassFish Project Looking Glass 등을 비롯한 수많은 오픈 소스 프로젝트를 통해 이러한 목표의 달성을 향한 확고한 결의를 분명하게 보여준 바 있습니다. 자바 기술을 오픈 소싱하기로 결정함으로써 이제 썬은 최대의 오픈 소스 소프트웨어 공급업체이자 프리 소프트웨어와 GPL 커뮤니티에 대한 최대 기여자가 되었습니다.

이는 의심할 바 없이 기념비적인 사건인 동시에 또 마땅히 해야 할 일이라고 할 수 있지만, 또 한편으로는 주변으로부터 수많은 궁금증을 불러일으키고 있는 것도 사실입니다. 왜 썬은 지금이 자바를 오픈 소싱하기에 알맞은 시기라고 판단했을까? 시기 판단의 근거는 무엇일까? 이 결정은 오픈 소스 커뮤니티에 어떤 영향을 미치는가? 이런 발표가 나온 이상 자바 기술의 미래는 앞으로 어떻게 될 것인가? 또, 이 발표는 현대 CXO와 개발자들에게 있어서 어떤 실질적 의미를 지니는가?

이런 궁금증들을 풀어주기 위해 썬의 Distinguished Engineer이자 Sun Software의 CTO인 Bob Brewin을 이번 호 레터의 게스트 라이터로 초빙했습니다. Bob은 오픈 소스의 역할, 개발의 우선순위 지정, 자바 기술 그룹의 감독 등을 비롯한 소프트웨어 개발의 모든 측면에 항시 관여하고 있습니다. 다시 말해서, 결정의 배후에 어떤 동기가 작용했는지, 썬이 정확히 무엇을 발표했는지, 소프트웨어 고객과 개발자 및 썬에 대한 그 함의는 무엇인지 등의 문제를 논하는 데 그보다 더 적합한 인물은 없을 것입니다.

그러면 시작해볼까요, Bob —

Bob Worrall
CIO, Sun Microsystems

고맙습니다, Bob. 자바 플랫폼을 오픈 소싱하기로 한 썬의 결정에 관한 저의 생각을 들려드릴 기회를 갖게 되어 매우 기쁩니다. 이제 썬은 자사의 소프트웨어 폴리오 전체를 오픈 소싱한다는 목표를 향해 큰 걸음을 내딛게 되었으며, 그것이 썬과 개발자, 고객, 그리고 파트너에게 주는 함의는 가히 엄청나다고 할 수 있겠습니다. Bob Worrall이 제기한 질문에 대한 답변으로, 잠시 짬을 내어 썬이 자바 구현의 주요 구성요소를 공개하는 데 왜 지금 시점을 선택했는지에 대해 먼저 설명해드리는 것이 좋을 것 같습니다.

시기 문제에 관해 간단히 설명 드리자면, 고객들이 오픈 소스 제품을 요구하고 있다는 것, 그리고 자바 기술이 이제 업계에서 확고하게 자리를 잡았고 플랫폼을 지속적으로 유지?발전시킬 수 있는 활기찬 커뮤니티를 보유할 정도로 성숙해졌다는 것입니다. 오픈 소스에 관심을 가지는 이유는 다양합니다(예컨대, 오픈 소스 소프트웨어는 특정 벤더 고정화를 방지하고, 애플리케이션의 유연성을 증대시킬 뿐 아니라 궁극적으로는 개발 및 데이터센터 비용 절감 효과를 제공합니다). 그러나 고객들이 오픈 소스를 선호하게 된 진정한 이유는 개발자들이 오픈 소스를 애플리케이션 개발 라이프스타일의 한 부분으로 수용했다는 사실입니다. 오픈 소스 플랫폼에서 실행되는 소프트웨어를 구축하는 개발자가 점점 늘고 있고, 고객은 오픈 스탠더드를 통해 촉진되는 유연성과 상호운용성으로부터 가치를 끌어낼 수 있습니다.

썬의 경우, 이러한 사이클은 “볼륨이 기회를 창출한다”는 문구로 요약됩니다. 다시 말해, 오픈 소스 자바는 개발자들에 대한 자바 기술의 매력을 강화함으로써 새로운 이들이 자바 플랫폼에서 혁신적인 디바이스와 서비스를 창출할 수 있는 가능성을 높이게 되는 것이고, 이런 식으로 볼륨이 커지면 썬과 그 파트너들을 위한 기회도 따라서 증가하게 되는 것입니다.

자바와 오픈 소스는 함께 성장합니다
물론, 오픈 소스 소프트웨어가 애플리케이션 개발을 위한 주류 패러다임으로 자리잡을 시기에 즈음하여 자바 기술은 네트워크 기술 혁신을 위한 소프트웨어 언어로 각광받을 만큼 성숙해졌습니다. 생각해 보십시오. 자바는 Windows, Linux, Solaris 등의 운영체제를 합한 것보다 더 많은 디바이스와 애플리케이션에서 실행되고 있습니다. 또한 지난 11년 동안 썬과 늘어난 자바 기술 커뮤니티는 모바일, 데스크탑, 엔터프라이즈 애플리케이션을 위해 매우 인기 있고 규모가 큰 역동적인 시장과 플랫폼을 구축하기에 이르렀습니다.

오픈 소스의 이점을 감안할 때, 많은 이들이 썬이 왜 자바 플랫폼을 좀더 일찍 오픈 소싱하지 않았는지 궁금해하는데, 그것은 플랫폼의 진화와 관련된 성숙도의 문제이자, 한편으로는 이제까지 썬이 보장해 온 자바 기술의 호환성 구현을 유지할 수 있을 만큼 건전한 커뮤니티를 보유하는 문제와 관련이 있다고 할 수 있겠습니다.

그리고 자바 기술을 오픈 소싱하기로 한 이 결정은 자바 플랫폼이 더 성숙해지고 자바에 의존하는 설치 베이스 규모가 더 커질 때까지 기다림으로써 분기(forked) 또는 비호환 자바 버전을 위한 잠재력을 창출하는 효과가 있으며, 동시에 우리는 오픈 소스 커뮤니티가 향후 버전의 호환성을 유지할 가능성이 높은 오픈 소스 구현을 제공할 수 있게 된 것입니다.

썬은 무슨 일을 했는가?
2006년에 개최된 JavaOne 컨퍼런스에서 이미 썬은 자바 플랫폼 전체를 점차적으로 오픈 소싱하겠다고 약속한 바 있으며, 11월 13일에 썬은 자사의 핵심 구현에 포함된 구성요소들을 최초로 공개했습니다.

이 공개는 각각 GNU GPL(General Public License) v2 하에 이루어졌으며, 특히 썬은 Java SE(HotSpot 가상 머신, javac 컴파일러, JavaHelp 문서 시스템 포함)와 Java ME(썬의 최적화된 CLDC/CDL 코드 포함)의 핵심 부분들을 오픈 소싱했습니다. 아울러, 썬은 2007년 전반기까지 오픈 소스 라이선스 하에 Java JDK 전체를 공개하겠다는 서약을 재천명했습니다.

이들 구현의 공개와 관련하여 라이선싱 모델을 선택하는 일은 의사결정 과정에서 가장 심사 숙고한 측면 중 하나였습니다. Java SE JDK는 Classpath 예외가 첨부된 GPLv2를 통해 오픈 소싱되었고 Java ME는 수정 없는 GPLv2 하에 공개되었습니다. 또한 썬은 GNU/Linux 커뮤니티의 핵심이 되는 라이선싱 방식을 채택함으로써 예전 같으면 자바를 솔루션으로 선뜻 선택하지 않았을지도 모르는 개발자들에게 더욱 다가갈 수 있었습니다. GPL의 선택은 이미 오픈 소스를 사용하고 있는 이들, 특히 Linux 커뮤니티의 멤버들을 위해서도 가치를 극대화시켜 주는 효과가 있습니다.

 
썬은 이제 프리 소프트웨어와 GPL 커뮤니티의 최대 기여자가 되었습니다.

자바 기술을 오픈 소싱하기로 한 썬의 결정이 자바 플랫폼의 구현 경쟁을 촉진할 가능성이 있다는 사실은 누구나 인정하는 바입니다. 한편, 썬은 신규 오픈 소스 자바 부문에 고유한 가치를 부여하고 있을 뿐 아니라 여전히 골드 스탠더드 Java SE 및 Java ME 구현을 보유하고 있으며, 자바 기술과 JDK의 중추적 아키텍트로서 광범위한 개발자 리소스와 복잡한 자바 에코시스템의 니즈를 조화시켜 온 다년간의 경험까지 지니고 있습니다. 바로 이 두 가지 요소가 썬으로 하여금 자바 플랫폼의 호환성에 대해 지속적으로 주도적 역할을 수행할 수 있도록 해줄 것입니다.

오픈 소스 자바는 어떤 기회를 창출하는가?
썬이 이런 결정을 내리게 된 이유에 대해 알아보았으니, 이제 그것이 고객, 개발자, 그리고 썬 자신에 대해 지니는 함의를 살펴보기로 하겠습니다. 말할 것도 없이, 오픈 소스 자바 기술은 엄청난 반향을 불러일으키고 있습니다.

오픈 소스 자바 기술은 고객에게 풍부한 보상을 약속합니다. 즉, 고객은 주요 웹 플랫폼을 오픈 소싱함으로써 특정 기술이나 구현으로부터 자유로워질 수 있다는 확신을 가지고 자바 기술을 채택할 수 있을 뿐 아니라, 자바 기술을 자유로이 이용할 수 있게 되면 경쟁을 촉진하고 가격을 낮추는 시장 원리를 따를 수 있게 될 것입니다. 게다가, 썬과 JCP(Java Community Process)JSR(Java Specification Request) 커뮤니티가 개발의 방향을 주도하게 될 경우 특정 자바 구현에서 다른 자바 구현으로 전환하는데 드는 비용 또한 낮아지게 됩니다.

뿐만 아니라 오픈 소스 자바 기술은 기술혁신을 가속화함으로써 오픈 소스의 세계에서는 성능이 더 뛰어나고 기능이 더 풍부한 애플리케이션을 구축하려는 개발자들의 경쟁이 뜨거워질 것이고, 이는 궁극적으로 제품 품질 향상, 가격 하락, 총 소유비용 절감 등의 결과를 낳을 것입니다. 더욱이, 이러한 변화는 특히 최고 품질의 서비스를 최저의 가격으로 제공하는 것을 모토로 하는 데이터센터 영역에서 가장 실감할 수 있을 것입니다. 왜냐하면 개발자들은 자바 기술의 오픈 소스 구현을 이용함으로써 아주 저렴한 비용으로 대규모의 컴포지트 엔터프라이즈 애플리케이션을 구축할 수 있기 때문입니다.

개발자들에게 오픈 소스 자바 기술은 유연성을 높여주고 전혀 새로운 방식으로 썬 기술을 활용할 수 있게 해주는데, 주목할 만한 사례로 Web 2.0 환경과 관련하여 썬 외부에서 여러 가지 새로운 동적 언어(“Ruby on Rails”가 떠오르는군요)가 개발되고 있는 경우를 들 수 있습니다. 이들 언어는 대부분 자체적인 인터프리터 또는 가상 머신에서 실행됩니다.

오픈 소스 자바 가상 머신이 제공되고 썬과 커뮤니티가 이런 동적 언어를 지원하기 위해 협력하게 된다면, 자바 언어가 더 이상 자바 가상 머신의 유일한 수혜자가 아닌 상황이 발생하는 경우도 배제할 수 없습니다. 다시 말해서, 자바 가상 머신은 다양한 언어에 걸쳐 활용될 수 있는 재사용 가능한(reusable) 기술이 될 수 있다는 말입니다. 결국 개발자들은 자바 가상 머신의 안정성과 성능을 물론이고, 이를 각자의 자바 계열 외의 애플리케이션들에 사용할 수 있는 능력을 얻게 될 것입니다.

궁극적으로, 오픈 소스는 자바 기술 커뮤니티에 더 많은 개발자들을 끌어들일 것이며, 이는 고객을 위한 경쟁 강화, 기술혁신 증진 및 비용 절감 효과를 가져오게 될 것입니다. 다시 한번 말씀 드리지만, 볼륨은 기회와 가치를 창출합니다.

Bob Brewin
Sun Software CTO 겸임 Sun Distinguished Engineer
Sun Microsystems, Inc.

:
Posted by 뽀기