추가 : Java 6부터 properties 파일에 대해 다양한 문자셋의 일반 텍스트 파일을 사용할 수 있는 load(Reader reader)가 추가되었고 Spring Framework도 Encoding명시를 통해 이를 지원함.
단,
-- 이후 원문
Eclipse의 파일 Lock 문제를 찾으면서 처음에는 Properties Editor Plugin을 원망했다. 게다가 대체품으로 선택한 Eclipse-RBE는 다소 불편한 인터페이스에 자꾸 NullPointerException을 떨궈서 사람 짜증나게 만들기 까지.
하지만 그러다가 곧 생각이 바뀌어 버렸다.
진짜 문제는 우리가 설정 파일로 시대착오적인 *.properties를 사용하고 있다는 그 사실이다.
자바의 *.proerties 파일은 텍스트 파일을 가장한 바이너리 파일이라고 보면 된다. 특수한 편집기나 변환기가 없으면 비영문권 사용자에게는 결코 텍스트 파일로써 다뤄질 수 없는 설정 파일 형식이다. 이런 것을 사용하면서 이를 편집하게 도와주는 플러그인을 탓한 것이다.
지금은 XML이나 YML 같은 잘 정형화되어있고 어느 편집기에서나 열어서 볼 수 있는 훌륭한 설정 파일 포맷이 나온지 이미 몇 년이 지난 시점이다. 그런 와중에 properties를 사용하는 나 자신을 탓하지 않고 플러그인을 탓하다니. 습관이 무섭다.
Java도 또한 이 문제점을 인지하고 Properties 객체를 XML 파일을 통해서 생성할 수 있게 만든지 이미 오래전이다. Properties XML은 형식도 매우 직관적이다. http://wiki.kwonnam.pe.kr/java/properties 를 참조하자.
게다가 더욱 훌륭한 것은 Spring Framework를 사용할 경우 <context:property-placeholder/>, <util:properties/>, 그리고 메시지 Resource Bundle 등이 모두 다 이 XML 형식의 프라퍼티를 완벽하게 지원한다는 것이다.
추가(2013/02/06) : XML 프라퍼티 형식을 사용하면 국제화지원이 안된다는 댓글이 있는데, Spring의 Resource번들은 이를 잘 지원하며 JDK 6 기본 ResourceBundle의 경우 Using Java 6 to Access Translatable Text in XML Files를 참고해보시기 바랍니다.
그래서 오늘은 특정 디렉토리의 모든 *.properties를 XML Properties로 변환해주는 간단한 툴을 만들고, Spring Bean 설정 파일에서 properties를 사용하는 부분들을 모두 XML 파일을 가리키도록 고쳐서 팀 프로젝트의 모든 *.properties 파일을 없애버렸다. 생각보다 오래걸리지도 않았다. 그리고 log4j.properties도 삭제해 버리고 log4j.xml로 전면 교체해 버렸다.
다른 Java 개발자들에게도 꼭 권한다. 프로젝트에서 *.properties를 삭제해 버리자. 어렵고 복잡한 일도 아니면서 설정 파일 읽기와 편집 효율성이 훨씬 더 증대된다.
그리고 하면서 느끼게 된 사실이 또 있는데, Spring의 <context:property-placeholder/> 사용하지 말자. 이일민씨의 블로그 글에도 보면 되도록 <util:properties/>와 SpEL을 사용하자는 것이 있는데. 이번에 수정하면서 약간은 다른 이유로 매우 동감하게 되었다.
properties-placeholder는 부모 자식 관계에 있는 Application Context XML 설정파일들의 경우에도 동일한 properties 파일임에도 모든 Bean 설정 파일에 property-placeholder를 명시해줘야 하는 문제가 있다.
하지만 <util:properties/>를 사용하게 되면 부모 컨텍스트에 딱 한번만 설정하고 그 외에는 SpEL로 명시해주면 된다. 그 외에도 SpEL을 쓰게 되면 어노테이션 기반 객체 주입시에도 사용이 가능하지만 properties-placeholder는 억지로 String 등의 Bean 객체로 생성하지 않는 이상 어노테이션에서 직접 읽을 방법이 없다(내가 아는한. 있다면 좀 댓글로 알려주세요).
따라서 나는 <context:property-placeholder/>를 버리고 <util:properties/>와 SpEL 사용을 강력하게 권한다.
단,
@PropertySource
는 이를 지원하지 않는 것으로 보임.public static void main(String [] args) throws Exception {
Properties props = new Properties();
InputStream is = new FileInputStream("a.properties");
props.load(new InputStreamReader(is, "UTF-8"));
props.list(System.out);
}
-- 이후 원문
Eclipse의 파일 Lock 문제를 찾으면서 처음에는 Properties Editor Plugin을 원망했다. 게다가 대체품으로 선택한 Eclipse-RBE는 다소 불편한 인터페이스에 자꾸 NullPointerException을 떨궈서 사람 짜증나게 만들기 까지.
하지만 그러다가 곧 생각이 바뀌어 버렸다.
진짜 문제는 우리가 설정 파일로 시대착오적인 *.properties를 사용하고 있다는 그 사실이다.
자바의 *.proerties 파일은 텍스트 파일을 가장한 바이너리 파일이라고 보면 된다. 특수한 편집기나 변환기가 없으면 비영문권 사용자에게는 결코 텍스트 파일로써 다뤄질 수 없는 설정 파일 형식이다. 이런 것을 사용하면서 이를 편집하게 도와주는 플러그인을 탓한 것이다.
지금은 XML이나 YML 같은 잘 정형화되어있고 어느 편집기에서나 열어서 볼 수 있는 훌륭한 설정 파일 포맷이 나온지 이미 몇 년이 지난 시점이다. 그런 와중에 properties를 사용하는 나 자신을 탓하지 않고 플러그인을 탓하다니. 습관이 무섭다.
Java도 또한 이 문제점을 인지하고 Properties 객체를 XML 파일을 통해서 생성할 수 있게 만든지 이미 오래전이다. Properties XML은 형식도 매우 직관적이다. http://wiki.kwonnam.pe.kr/java/properties 를 참조하자.
게다가 더욱 훌륭한 것은 Spring Framework를 사용할 경우 <context:property-placeholder/>, <util:properties/>, 그리고 메시지 Resource Bundle 등이 모두 다 이 XML 형식의 프라퍼티를 완벽하게 지원한다는 것이다.
추가(2013/02/06) : XML 프라퍼티 형식을 사용하면 국제화지원이 안된다는 댓글이 있는데, Spring의 Resource번들은 이를 잘 지원하며 JDK 6 기본 ResourceBundle의 경우 Using Java 6 to Access Translatable Text in XML Files를 참고해보시기 바랍니다.
그래서 오늘은 특정 디렉토리의 모든 *.properties를 XML Properties로 변환해주는 간단한 툴을 만들고, Spring Bean 설정 파일에서 properties를 사용하는 부분들을 모두 XML 파일을 가리키도록 고쳐서 팀 프로젝트의 모든 *.properties 파일을 없애버렸다. 생각보다 오래걸리지도 않았다. 그리고 log4j.properties도 삭제해 버리고 log4j.xml로 전면 교체해 버렸다.
다른 Java 개발자들에게도 꼭 권한다. 프로젝트에서 *.properties를 삭제해 버리자. 어렵고 복잡한 일도 아니면서 설정 파일 읽기와 편집 효율성이 훨씬 더 증대된다.
그리고 하면서 느끼게 된 사실이 또 있는데, Spring의 <context:property-placeholder/> 사용하지 말자. 이일민씨의 블로그 글에도 보면 되도록 <util:properties/>와 SpEL을 사용하자는 것이 있는데. 이번에 수정하면서 약간은 다른 이유로 매우 동감하게 되었다.
properties-placeholder는 부모 자식 관계에 있는 Application Context XML 설정파일들의 경우에도 동일한 properties 파일임에도 모든 Bean 설정 파일에 property-placeholder를 명시해줘야 하는 문제가 있다.
하지만 <util:properties/>를 사용하게 되면 부모 컨텍스트에 딱 한번만 설정하고 그 외에는 SpEL로 명시해주면 된다. 그 외에도 SpEL을 쓰게 되면 어노테이션 기반 객체 주입시에도 사용이 가능하지만 properties-placeholder는 억지로 String 등의 Bean 객체로 생성하지 않는 이상 어노테이션에서 직접 읽을 방법이 없다(내가 아는한. 있다면 좀 댓글로 알려주세요).
따라서 나는 <context:property-placeholder/>를 버리고 <util:properties/>와 SpEL 사용을 강력하게 권한다.
덧글
http://blog.springsource.org/2011/02/15/spring-3-1-m1-unified-property-management/
그거 말고 뚜렷한 이유는 없어 보이네요..
그러나 저는 사용하고 싶고 사용해야 합니다.
사용자에게 보여주는 메시지를 프라퍼리로 관리하니까요.
그리고 두가지 솔루션이 있는데, 한 솔루션은 제약이 있고 한 솔루션은 제약이 없는 상황에서, 그리고 제약이 없는 솔루션에 딱히 다른 단점도 없는 상황에서, 굳이 제약이 있는 솔루션을 선택할 이유가 없지요.
그래서 XML을 사용합니다.
가령 아래와 같은 값이 있을 때 개발자 실수로 인하여 도메인 끝에 공백이 한 개 들어가 있다고 가정하고 뒤에 파라미터를 붙일 때
http.url=http://test.co.kr
http://test.co.kr ?test=111&tet2=12121 와 같이 되어 연동 문제가 발생했던 적이 있습니다.
이런 현상으로 인하여 삽질 좀 했죠..;;
ResourceBundleMessageSource 같은 경우 xml 타입 프러퍼티를 지원하지 않는 것으로 보입니다.
jdk의 ResourceBundel 자체도 따로 control를 구현하지 않고, 바로 xml 번들을 읽어 들이지는 못하는듯...
저희는 org.springframework.context.support.ReloadableResourceBundleMessageSource를 사용하고 있습니다.
@Service("applicationConfig")
public class ApplicationConfig
{
//util:properties 변수 읽을때
@Value("#{commonapp['app.CLASS_DEBUG']}")
String classDeBug;
//properties-placeholder 변수 읽을때
@Value("${config.application.title}")
String configApplicationTitle;
//환경변수 읽을때
@Value("#{systemProperties['os.name']}")
String osName;
}
제가 시대착오적이라고 까는 것은 *.properties 파일 형식이지 국제화 등에 사용되는 Properties 클래스가 아닙니다.
그리고 제가 위에 분명히 썼습니다. Spring의 ResourceBundle이 지원한다고요.
충고는 감사합니다만 그 전에 먼저 글은 똑바로 읽어 주시기 부탁드립니다.
맨 첫 댓글부터 '후배님인 거 같아', '편협한 생각이다'......
참 같은 개발자로서 느끼는 건데 정말 꽉막혔네요.
저는 나그네님 글 읽으면서 친절한 반론이라 생각되었거든요.
권남님이 시대착오적인 발상이라고 너무 과격(?)한 단어를 사용하셔서, 초보 개발자들이 "아..properties는 무조건 쓰면 안되는거구나"라고 생각할까봐 염려해서 쓴 글 같았는데 오히려 그 댓글에 권남님이 "자기 글을 똑바로 읽고나 댓글 달아라(이건 제가 글 읽으면서 받은 주관적인 느낌임)" 라는 뉘앙스로 글을 쓰셔서 그 뒤에서 서로 공격적이 된 것 같습니다. 오히려 전 말줄임표님의 말투가 거슬린다.. 편협한 생각이다.. 꽉막혔다.. 이런 식의 글이 더 눈쌀을 찌푸리게 만드네요. 시대착오적이라는 단어 선택에 반론을 제기하는 문장으로 "편협한 생각이다"가 적절한 선택이지 않은가요?
하고계신 프로젝트의 팀원들에게만 하시면 되겠어요^^
개발자들 특유의 편협한 마인드들 보이는 댓글들이 보여서 보기 안좋네요..
쫌 지난후에 바라다보면 이런 갑론을박이 참으로 부질없어 보일겁니다.ㅉ
개발자들 중에는 친절을 배푸는 듯 하지만 공격적으로 말하며 상대방 바보만들고 올라서고 싶어하는 분들이 있습니다
별개 아니면 그저 가르쳐주면 그만입니다
얼마든지 평범하게 말하고 알려줄 수 있습니다
편협한 생각, 후배님인것 같아 한마디? 충고가 정말 감사하다고 느끼나요??
이건 일단 상대방 흥분시키고 시작하는 토론을 위장한 싸움 거는거죠
도대체 뭐가 꼴사나와서 그런표현을 하나요?
그런문장 절대 멋있거나 카리스마, 말 잘하는 사람으로 보이지 않습니다
프로퍼티에 대해 조금더 케이스를 안다고 하여 개발자 선배라니 이건 왠 편협하고 뚱딴지 같은 말인지 모르겠군요
일할때 이런분들 정말 진저리가 납니다
좀 아는 거 인정해줄테니깐 제발 말 좀 곱게합시다..
그런데 그 분 이야기에서 공감가는게 저도 Properties가 바이너리 파일이라는 부분은 조금 문제가 있다고 생각되네요.
기본적으로 Properties 는 notepad로도 open할 수 있는 텍스트 파일입니다. 텍스트 파일이기 때문에 encoding이 맞지 않으면 editor에서 깨져서 나오는게 당연할겁니다. 그래서 한 파일에 여러 encoding을 담을 수가 없으니깐 u prefix를 붙여서 unicode 입력이 가능하도록 하는 것은 아마 java의 properties의 약속일겁니다. (Oracle의 Properties 파일에 관한 문서: http://docs.oracle.com/cd/E23095_01/Platform.93/ATGProgGuide/html/s0204propertiesfileformat01.html) properties라는 개념은 C에서도 사용되었었고 STL에 properties class도 있습니다. 다만 이 모든 곳에서 저런 unicode 입력방식이 통용되는가는 조금 의문이고 제가 확인하긴 어려우니 일단 확실하게 알고있는 java쪽의 약속이라고 하겠습니다.
그리고 제 생각에는 블로그 주인장께서 개발하는 환경에서는 파일의 encoding이 고정되고 unicode 문자는 이런 표현 방식을 따르도록 도와주는 editor를 사용하셨다고 생각되구요 아마 위에 나그네라는 분은 encoding이 다른 파일은 별도의 파일로 저장을 해서 언어별로 properties encoding에 맞게 읽어서 사용하는 환경이었다고 추측되네요. bean 정의할때 encoding 혹은 fileEncoding이라는 property 하나만 추가로 넣어주면 spring에서도 잘 지원되거든요.
뭐 각자의 상황(프로젝트, 취향, 개발팀, ...)에 맞게 취사선택된 결정사항이겠죠. 그러니 "시대착오적...", "선배로서...", "편협한... " 이런 극단적 표현은 모두 부적합하지 않을까요?
그리고 그것을 Spring이 연계해서 지원하구요.
이제 XML을 안써도 많이 편해질 듯 하네요.
jsp를 시작만 몇번째하고 있는 학생인데요..
이곳저곳 소스를 따라하다 문득.. 왜하필 .properties 를 쓰고 있는거지? 라는 의문에 검색 하여 오게 되었습니다.
댓글 까지 전~부 다 읽었는데.. 정말이지 오랫동안 쌓아둘 지식하나를 얻어가는거 같아 좋네요 ㅎㅎ
각자 편한 방법을 사용하면 될거 같은데 흠...
개인적으로 프로퍼티는 xml과 properties 두개 모두 용도에 따라 사용하지만
보편적으로 보자면 properties 가 나을 겁니다.
여러가지 이유에서요.
이거 보통 자신이 있는 분야나 개발 방법에 따라 갈릴듯하네요.
XML도 상당히 단점이 많은 방식입니다.
일단 쓸데없이 태그가 공간을 너무 많이 잡아먹고 그에 따라 가독성이 properties 파일에 비해 떨어진다는 점과
반복이나 배열 형식인 경우에는 불필요한 태그가 너무 많이 쓰이게 된다 정도겠네요
파싱도 느린편입니다.
YAML이나 JSON처럼 XML의 단점을 보완한 방식도 많지만..
XML 구조의 견고함과 확장성을 따라가기는 힘들지요.. ㅎㅎ 결론은 XML의 장점도 많습니다.
가장 최선의 방식은 적절한곳에 XML, Properties등의 방식을 배치해서 사용하는거겠지요. 한가지 방식만 고집하는건 아닌것 같습니다.
요즘 메이븐이 뒤안길로 사라지고 그래들이 부상하고 있는것도 사람들이 메이븐의 XML을 싫어하는 이유가 꽤 크더군요.. ㅜ.ㅜ
개발에 정답이 이거다라고 딱 정해져 있는건 없자나요. 그냥 그때그때 상황에 맞추어가면서 자신의 방법으로 개발해가면서 조금더 효율적으로, 조금더 편한 방법으로 할 뿐이지요.
쨋든 저는 그렇습니다. ㅎㅎ
지금까지의 댓글을 보면 결국 본인 주관적인 이야기일 뿐인 것을
저같은 초보자들이 보면 properties를 절대 사용하지 말아야 할 무언가로 보게 만드는군요..
https://jira.spring.io/browse/SPR-8963
Java9부터는 .properties 파일을 디폴트로 UTF-8로 로딩합니다.
http://openjdk.java.net/jeps/226 , https://docs.oracle.com/javase/9/intl/internationalization-enhancements-jdk-9.htm#JSINT-GUID-974CF488-23E8-4963-A322-82006A7A14C7
따라서 이전처럼 .properites 파일을 쓸때 인코딩을 변환해야하는 불편함은 없어지긴합니다.
다만 국제화 메시지를 만들 때에는 줄바꿈의 편리함등 때문에 properites XML이 상대적인 장점이 있다고 생각합니다.