JVM TimeZone

개발/JAVA/JSP 2007/11/06 12:56 posted by zekill

어느날 문득 자바에서 내 로컬시간과 상관없이 시간이 나오는걸 확인했다.
자세히 보니 9시간이 빠진 표준시로 나오는거다. GMT시간이.....
거참 로컬시간에 맞춰서 나와야 하는거 아닌가...고민을 하다가 보니 locale이 잘못 설정되어있나 하고
내 PC걸 확인해봐도 제대로 되어있고..-0-;;;;
그래서 자바의 타임존을 보았더니 빈칸으로 되어있다.
옆의 PC에서도 나와 같이 빈칸으로 되어있는데 정상적으로 한국시간을 표시하는데
어째 내 PC에서는 옆 PC와 다르게 GMT로 표시하는지....ㅡㅡ;;;
찾아보니 기본이 내 PC의 locale을 감지해서 자동으로 출력한다고 하는데...
아무래도 JVM 버그의 일종인듯 하다. 비스타에서는 이런 버그가 있다고 sun에 나와있긴하던데..-0-;;;

그래서 확인해보았다. 현재 내 자바의 버전은 1.5.0_10
간단하게 시간출력하는 걸 만들어서 자바시간 찍고 OS시간을 찍도록 실행을 시켰다.


사용자 삽입 이미지

우선 기본은 GMT로 출력이 되어 9시간의 차이가 나온다.
timezone을 Asia/Seoul 또는 GMT+09:00 으로 지정해주니 정상적으로 나온다.
에거... 이거 몰라 한참 해맸다...말그대로 삽질...ㅜㅜ
이클립스에서 WAS 실행시켜주는 부분에 VMargv 넘겨주는 곳에 -Duser.timezone=GMT+09:00 옵션을 추가하니 잘 된다...-0-;;;;;
이거 왜 자동으로 못잡고 사람 애먹이니...ㅜㅜ
2007/11/06 12:56 2007/11/06 12:56

이클립스 화면분할하기

개발/JAVA/JSP 2007/10/10 11:11 posted by zekill
이클립스에서 따로 화면분할 기능이 없어 답답할때가 많았었다.
꼭 필요할 땐 다른 에디터를 잠깐 사용해보기도 했고....
이클립스를 두개뛰워 같은 효과를 보기도 했었는데....

이러나 저러나 통합툴에서 안된다는건 참 불편한일이다.

그래서 안되겠다 싶어 생각을 좀 해보니...의외로 간단히 해결되더라.
확실히 지원되는 기능이라거나 뭐 더 좋은 방법 있으신분은 좀 얘기해주세요...^^;;;
뭐 근데 이것도 나쁘지 않다.
이미 알고 있거나 그건 원래 그렇게 쓰는거다 이노맛~~ 하시는분 패쓰~~ㅋ


1. 우선 이클립스를 뛰우고 소스를 암거나 하나 열자.

사용자 삽입 이미지


2. 열린 소스의 탭에서 오른쪽 버튼을 클릭하면 팝업메뉴의 하단에 new editor 라는 메뉴가 있다. 클릭 ㄱㄱ!!
사용자 삽입 이미지



3. 그럼 같은 소스가 다른 탭으로 하나 더 열리게 된다.
사용자 삽입 이미지



4. 새로 열린 탭을 마우스로 드래그 하여 아래로 쭈욱 당기다 보면 아래 그림처럼 줄이생긴다. 이때 마우스 드랍!!
사용자 삽입 이미지


5. 창 두개를 뛰운거긴 하지만 바로 화면 분할로 해서 사용하는거랑 같은 기능으로 그대로 사용가능하다.
사용자 삽입 이미지


뭐 그림이 있어서 그렇지 실제로 해보면 간단하다...-0-// (클릭하고 드래그 한번 한것밖에.......)

그럼 좋은 하루 되세요^^//
2007/10/10 11:11 2007/10/10 11:11

[스크랩] JSP에서의 include

개발/JAVA/JSP 2007/09/28 10:26 posted by zekill



JSP에서 인클루딩 방식 2가지와 함께 인클루드 파일을 수정하였을때 적용되지 않는 부분이 소개되어 있어 예전에 이것을 몰라 헤매던게 생각나 포스트합니다...^^;;;
인클루딩 파일을 수정하였을때 적용되지 않는 문제에 대한 해결방법은 글 본문 중 붉은 색으로 처리해놓았습니다.


--------------------------------------------------------------------



[원문] http://aboutjsp.com/lec/include.jsp
저자 : 이선재(hsboy)


JSP 에서는 두가지 방법으로 다른 문서를 현재의 문서에 포함 시킬수 있습니다. 이번 강좌에서는 이러한 두가지 include 문에 대해서 알아 봅니다.

* include 란?

다른 웹 언어(PHP or ASP등)를 프로그래밍 해본 경험이 있으신 분들은 include 가 무었인지 잘 알고 있을 것입니다.
include 란 현재의 문서에 다른 문서, 즉 다른 파일의 내용을 포함시켜 출력하는 것을 말합니다. 예를 들어 doc1.jsp 라는 문서의 내용이 아래와 같다고 합시다.

doc1.jsp
<%@ page contentType="text/html;charset=euc-kr"%>
<%
    out.print("<h2>이것은 doc1.jsp의 내용입니다.</h2>");
%>

그리고 doc2.jsp 의 내용이 아래와 같을때

doc2.jsp
<%
    out.print("<h2>이것은 doc2.jsp의 내용입니다.</h2>"); 
%>

위의 두개 문서의 출력을 한번에 보고자 할 때 include를 사용합니다.

doc3.jsp
<%@ page contentType="text/html;charset=euc-kr"%>

<jsp:include page="doc1.jsp" flush="true" />

<%@include file="doc2.jsp" %>

위의 doc3.jsp 를 출력하면 아래와 같은 화면이 출력됩니다.

doc3.jsp 실행화면

사용자 삽입 이미지

위의 소스에서 눈여겨 볼 부분이 doc2.jsp 의 상단 부분인데, doc2.jsp에는 page Directive가 생략 되어 있습니다. 이것은 두가지 include 방식의 차이 때문인데, 자세한 설명은 아래에서 하도록 하겠습니다.
또한 이러한 기능을 SSI(Server Side Include)를 이용해서 구현할수도 있는데 이것은 apache웹서버에서 지원하는 내용 이므로 여기에서는 다루지 않도록 하겠습니다. 자세한 내용이 궁금하신분은 여기를 참고 하시기 바랍니다.


* JSP Action - <jsp:include page="URI" flush="true" />

[syntax]
1). body 구문이 없는 경우
<jsp:include page="URI" flush="true" />

2). body 구문이 있는 경우
<jsp:include page="URI" flush="true">
<jsp:param name="파라메터이름" value="파라메터값" /> 
/* xxx.jsp?파라메터이름=파라메터값 */ </jsp:include>

위와 같이 두가지 사용 용법이 있으며, 두번째 방법을 사용하면 해당 jsp파일에 파라메터값도 넘겨 줄수가 있습니다.
JSP Action 구문의 include 는 include되는 파일과 include 시키는 파일(doc1.jsp와 doc3.jsp)를 각각 컴파일 한후 두 파일의 실행 결과를 한곳에 합쳐서 출력을 하게 됩니다. 즉, 완전히 "별도로" 동작하게 됩니다.
여기에서 flush="true" 문장은 true나 false 가 들어 갈수 있는 부분으로써 include를 실행하기 전에 out.flush()를 실행할지 여부를 결정하는 것입니다. 물론 true일때 out.flush()를 실행하겠지요. JSP 스펙 1.1 까지는 반드시 true로 설정이 되어 있어야만 했으니, 1.2 부터는 true/false중 원하는것을 선택하면 됩니다.


* include 지시어 - <%@ include file="URI" %>

include 지시어 와 Action 구문과의 가장 큰 차이점은 include 지시어는 컴파일 되기전에 파일이 내용이 합쳐진다는 것입니다. 즉, doc3.jsp 는 doc2.jsp의 내용을 자신의 문서내에 포함하여 하나의 파일로 인식한다는 것입니다. doc2.jsp 에 보면 page Directive 가 생략이 되어 있는데, 그것이 바로 이러한 이유 때문입니다.

doc2.jsp에도 page Directive를 설정해 주었다면 에러가 발생할 것입니다. 하나의 페이지에 두번 선언을 하는 꼴이 되어 버릴테니까 말이죠.


* Action 구문과 include 지시어의 중요한 차이점

JSP프로그래밍을 조금이라도 접해 보신 분들이라면 누구나 아는 대로 JSP는 먼저 servlet 으로 변환되고, 그 다음 servlet 이 컴파일 되어 그결과를 화면에 출력해 주게 되어 있습니다.
그런데, Action 구문을 사용 하였을 때에는 두개의 파일 각각 다른 파일처리 되어 두개의 servlet 파일 생성하게 됩니다. 따라서 어느 한 파일이 수정되면 곧바로 적용되어 화면에 출력이 되게 됩니다.

하지만 include 지시어 문을 사용하게 되면 하나의 servlet 파일이 생성되게 됩니다. 이로 인해 엄청난 차이점이 발생하게 되는데, JSP의 특성상 JSP파일이 조금이라도 수정이 되어 있으면 servlet 으로 재 변경되어 다시 컴파일이 이루어 지게 됩니다. 그런데, doc2.jsp 파일을 내용을 수정하고, doc3.jsp 파일을 부르게 되면 수정되기 전의 doc2.jsp 파일의 내용이 출력됩니다.

또다시 doc3.jsp 파일을 살짝 고치고 doc3.jsp 을 부르게 되면 이제서야 수정된 doc2.jsp파일의 내용이 화면에 출력 되게 될 것입니다. 눈치 빠르신 분들은 알아 차리셨으리라 생각됩니다만..
이렇게 된 원인은 아무리 doc2.jsp의 내용이 수정된다 하더라도 JSP엔진에서는 doc3.jsp가 수정이 되지 않아 JSP 엔진에서는 수정되지 않은 같은 파일로 인식하여, servlet 파일을 다시 생성하지 않았기 때문입니다.

따라서, include 지시어 문을 사용하셨을 경우에는 두개의 파일 모두 수정해 주어야(doc3.jsp는 공백하나가 추가 되더라도 수정되어야 합니다) 원하는 결과를 얻을수가 있게 됩니다.
이경우 하나의 파일을 여러개의 파일에서 include 지시어 로 include 하였다면 이것은 치명적일수도 있습니다. 예를 들어 dbcon 같은 내용을 만들어 include 해서 사용하는 경우 상당히 많은데, 이럴때 큰 문제 거리가 될수도 있습니다.
이러한 문제점을 한번에 해결하는 방법이 있는데, ...tomcat/ 디렉토리에 보면 work 라는 디렉토리가 있습니다. 이곳이 바로 변환된 servlet 파일들이 저장되어 있는 곳인데, 이 디렉토리를 완전 삭제 한후에 tomcat을 재시작 시키면, 변경된 내용들이 한번에 적용이 될것입니다.(모든 servlet 파일이 재작성되니 당연한 결과 이겠지요)
그런데 이러한 특징은 tomcat 5 버젼대부터 달라지게 되었는데, include되는 파일을 수정하더라도 서블릿 컨테이너가 알아서 모두 재 컴파일 해준다는 것입니다. 필자가 확인한 바로는 OC4J 최신 버젼에서도 tomcat 5와 같이 자동으로 처리되었습니다.

2007/09/28 10:26 2007/09/28 10:26
[원문] http://okjsp.pe.kr/lecture/siva6/equals.txt 



음....우연히 작업을 하다 나도 모르게 문자열 비교하는곳에  "==" 를
입력했다가.....오류가 나서 한참 찾았다...-0-;;;

또 equals 로 String 을 비교하다가 비교값으로 "비교값" 이 아닌 '비교값' 을 넣었다가
한참 찾았다......
비교값은 문자열이 아니라 문자 였다.
'TEST' 이렇게 했다면 실행도 되지 않고 에러가 나왔을것이다.

그러다 우연찮게 이런 문서를 찾게 되었다..-0-;;;;
이거저거 하다보니 가끔 헷갈려 ㅜㅜ



참고로...

요건 비교값을 int 형으로 반환
int compareTo(String anotherString)
          Compares two strings lexicographically.
int compareToIgnoreCase(String str)
          Compares two strings lexicographically, ignoring case differences.

요건 boolean 형으로 반환
boolean equals(Object anObject)
          Compares this string to the specified object.
boolean equalsIgnoreCase(String anotherString)
          Compares this String to another String, ignoring case considerations

그리고 위 메소드 중 IgnoreCase 이게 붙은 메소드는 대소문자 구분없이 비교하는 메소드이다 -0-//

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

[ "==" 과 "equals()" 의 차이점]

     Q&A를 읽다보면, String을 "=="연산자로 비교해서 에러를 발생시키는 경우가 많이
    있었습니다. 그래서, 여기에 대해서 정리를 해보고자 이 글을 작성했습니다. 여기
    쓰여있는 내용은 제 추측과 상상력이 동원되기도 했기 때문에 사실과 차이가 있을
    수도 있습니다. 그런 내용은 바로 알려주세요.

    두개는 어떤 차이가 있을까요?
    간단히 말하면, "=="은 연산자고 "equals()"는 메소드입니다.
    "=="에 대한 정의는 jvm에 있을 것이고,
    "equals()"에 대한 정의는 class에서 되어 있겠죠.

    "=="은 양쪽 항의 값을 비교하는 것입니다.
    "equals()"는 class에서 구현된 것에따라 어떤 처리를 해서 결과를 나타내겠죠..
    (구현에 따라서 다른 결과를 나타낼 수 있습니다.)

    우선, "=="부터 살펴보죠.
    위에서 말했듯이 양항의 값을 비교합니다.
    여기에 대한 설명은 java가 Call by reference 인지 Call by value인지에 대한
    설명이 되어야 하는데 이것은 다음 기회에 설명하겠습니다.(없을지도 모름)

    int i = 10, j = 20;
    의 코드가 실행되었다면,
    i라는 변수는 10이라는 값을 가지게 됩니다.
    물론, j는 20이라는 값을 가지게 됩니다.

    그런데,
    String str0 = "TEST", str1 = "테스트";
    라고 하면,
    str0는 "TEST"라는 객체를 가리키는 참조값을 가지게 됩니다.
    위에서 용어를 다르게 사용했습니다.
    "값을 가진다"와 "참조값을 가진다"
    객체는 직접 접근할 수 없습니다.
    단지, 그 위치를 참조하는 참조값을 가지고 접근하는 것 뿐입니다.

    다시 본론으로가면, "=="은 그 변수가 같은 값을 가지고 있는지만 체크하는 것입니다.
    int i = 10, int j = 20;
    int k = 10;
    String str0 = "TEST", str1 = "테스트";
    String str2 = new String("TEST");
    String str3 = "TEST"
    위의 코드를 수행하면, 메모리에는 다음과 같은 표의 상태가 됩니다.
    --------------------------------------
    |변수명| 변수값      | 실제값        |
    --------------------------------------
    | i    | 10          | (10)          |
    --------------------------------------
    | j    | 20          | (20)          |
    --------------------------------------
    | k    | 10          | (10)          |
    --------------------------------------
    | str0 | 0x3a3...(?) | [String]TEST  |
    --------------------------------------
    | str1 | 0xe1e...(?) | [String]테스트|
    --------------------------------------
    | str2 | 0xe2b...(?) | [String]TEST  |
    --------------------------------------
    | str3 | 0x3a3...(?) | [String]TEST  |
    --------------------------------------
    (변수값의 0x....는 그냥 상상의 숫자입니다. 너무 신경쓰지마세요.)

    그럼, 비교를 해볼까요..
    1.( i == j )  :  false
    2.( i == k )  :  true
    여기까지는 쉽게 이해가 갈 것입니다.
    3.( str0 == str1 ) : false  -> 당연?
    4.( str0 == str2 ) : false
    -> 이게 false인 이유는 "=="은 단지 가지고 있는 값을 비교하기 때문입니다..
    위의 표에서 본다면, 실제값이 아닌 변수값을 비교하게 됩니다.
    5.( str0 == str3 ) : true   -> 이건?
    -> 이건 억지라고요? 4번과 뭐가 다르냐고요?
    새로운 객체는까 변수값이 다를 것이고 결코 같은 값이 들어 오지 않을 것이라고
    생각할 수도 있습니다.
    하지만, java가 좀 똑똑한 놈이라 이런 경우가 발생합니다.
    new를 사용하여 만든 String은 항상 새로운 객체이지만 ""로 만든 문자열은
    공유를 할 수 있습니다...
    str0을 가리키는 "TEST"라는 문자열을 만들때 메모리의 어떤 부분에 String 객체가
    저장되겠죠. 그곳의 위치가 0xe1e...입니다.
    그런데, 새로 "TEST"라는 객체를 만들면, java는 이게 이전에 만든 0xe1e...에 있
    는 [String]TEST와 동일하다고 판단하고, 새로운 변수에는 0xe1e를 할당하게 됩니다.
    (모든 객체가 그런것은 아닙니다...여기에서 또 clone문제가 생기네요?
    이것도 다음기회...)

    이상의 설명에서 "=="이 무엇을 하는 놈인지 아셨는지.........
    알송달송하면, 아래까지 읽고 다시 읽어 보세요.

    위와 같은 현상때문에 사용자들이 아무 생각없이 "=="을 String에 사용하고,
    결과가 일관성이 없다고 말씀들을 하시더군요...
    보통, 사용자가 생각하는 비교는 실재 저장하는 값이지 결코, 그것을 가리키는
    변수가 아니라는 점에서 그렇습니다....
    그래서, java가 이상한 놈이라고 생각들 합니다.
    그럼, 객체의 "==" 비교는 어떤 의미가 있을까요?
    그건 동일한 객체라는 것입니다.
    위의 str0과 str3은 동일한 객체라는 것을 알 수 있습니다.
    반면, 같은 실재값을 가지고 있다고 하더라고 str0과 str2는 서로 다른 객체죠.
    (참고로, 서로 같은 class의 instance인가는 instanceof를 사용하여 check할 수 있습니다.)

    그럼 실제로 같은 값을 포함하고 있느냐는 무엇으로 비교할까요?
    네.."equals()"죠..
    물론, String등에서죠...
    하지만, equals()는 새로 만들 수도 있기 때문에 어떤 기능을 할지는 알 수가 없습니다.
    (만드는 사람 마음.....)

    여기서는 Object와 String 객체의 equals()만을 살펴보겠습니다.
    Object는 아시는 것처럼 모든 class의 부모입니다. 결국, 모든 class는 object를
    상속받고, 결국 생성되는 모든 객체는 equals()메소드를 갖게 됩니다.
    물론, 자식 class에서 equals()를 재정의하면 그 메소드를 따르지만요.

    자, 그럼 대망의 Object의 equals()를 직접보겠습니다.

    public boolean equals(Object obj) {
    return (this == obj);
    }

    이것입니다....(sun java 1.3.1 이지만, 다른 버젼도 별차이 없을것 같네요.)
    실망하셨나요?
    위의 글을 잘 읽으셨으면, (this == obj)가 어떤 의미를 가지는지는 판단하실 수
    있을 것입니다.

    그럼, String의 equals()는 어떻게 되어 있을까요?
    소스에서 바로 설명하죠.

    public boolean equals(Object anObject) {
    if (this == anObject) { //----> 동일한 객체라면 더 비교할 필요가 없겠죠.
        return true;
    }
    if (anObject instanceof String) { //---> 입력된 객체가 String인지 체크합니다.
                                      //---> type이 다른데 같은 값을가져도 무의미.
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) { //---> 먼저 길이가 같은지 체크하네요.
                                        //---> 길이가 다르면 다른 놈이죠.
        char v1[] = value;              //---> String은 내부적으로 char[]로 관리됩니다.
        char v2[] = anotherString.value;//---> 부럽습니다. 같은 class라고 private로
                                              선언되어 있어도 직접접근이 되는군요.
        int i = offset;
        int j = anotherString.offset;
        while (n-- != 0) {      //---> 하나하나 비교하는 군요.
            if (v1[i++] != v2[j++]) {
            return false;
            }
        }
        return true;
        }
    }
    return false;
    }

    String의 equals()는 이렇게 그 객체가 가지고 있는 char[]의 값을 비교하여
    같으면 true, 틀리면 false로 return하게 되어 있습니다.
    만약, 다른 설정은 다르더라도(그럴께 없지만)
    저장된 값이 같으면 true가 됩니다.
    위의 표를 보면, "equals()"로 비교하게 되면 str0, str2, str3이 모두 같은
    value를 가져 true를 return 하게 됩니다.

    사용자가 주로 원하는 비교의 결과는 이것이겠죠.

    결론을 말하면, 기본형은 "=="로 비교하고, 객체는 equals()로 비교해라 입니다.
    결론은 단순한데 너무 길게 설명했네요.

    ---Tip------------------------------------------------------
    String을 비교할 때의 Tip입니다.

    public void showHI(String str0)
    {
        if( str0.equals("TEST") ) System.out.println("Hi!!!");
    }

    이런 코드가 있을 수 있겠죠.
    showHI("TEST")의 결과는 Hi!!!입니다..
    showHI("테스트")의 결과는      입니다..(blank)
    그럼,
    showHI(null)의 결과는 무엇일까요?
    바로 NullPointException입니다...
    왜냐하면, equals()를 가진 str0자체가 null이기 때문에 equals()를 사용할 수
    없기 때문입니다.
    위의 메소드는 아래처럼 변경되어야 합니다.

    public void showHI(String str0)
    {
        if( "TEST".equals(str0) ) System.out.println("Hi!!!");
    }

    이 코드는 null이 들어와도 blank입니다.
    100%확실한 객체인 "TEST"를 사용하는 것이
    99.9999%의 확실성을 가진 str0 객체를 사용하는 것보다 좋습니다.

    일반적으로 String 비교를 사용할 때는
    비교할 문자열의 equals()를 사용하는 습관을 가져 주십시요.
    (물론 선택의 문제입니다.)
    ------------------------------------------------------------


==================================================
최초작성일 : 2002년 1월 25일
--------------------------------------------------
  본 문서는 자유롭게 배포/복사 할 수 있으나 반드시
  이 문서의 저자에 대한 언급을 삭제하시면 안됩니다.
  (이 내용은 javaservice.net에서 copy.)
--------------------------------------------------
  이호훈(siva6)
  E-mail: siva6@dreamwiz.com
==================================================
2007/09/01 23:04 2007/09/01 23:04
<%

public void test()
{
}

%>

요건 에러나므로

<%!

public void test()
{
}

%>


요렇게 %뒤에 !표를....붙이는게 뭐 스태틱으로 선언하는것과 같은거라나 머라나..할튼...
2007/09/01 22:57 2007/09/01 22:57