admin write
blogblogblogbloglocation loglocation logtag listtag listguest bookguest book
rss feed


웹프로젝트 개발팀원 한명이 실수로 이클립스상에서 문서 전체를 formatter 를 돌려 커밋을 하고

다른 개발팀원들이 그 흉물스럽게(?) 바뀐 소스를 수정 작업을 반복하는 바람에

뒤늦게와서 이러지도 저러지도 못하는 상황..

Eclipse 의 javascript formatter 를 직접 설정해보았는데

공들인 시간만큼 엄청 만족스러워서 공유해봅니다

이클립스 Preferences에서

JavaScript - Code Style - Formatter 에서

임포트 하시고 ctrl-alt-f 를 남발해보세요~


javascript.xml






수시간동안 메모리 프로파일링을 해보아도 증가하는 메모리도, 객체수도 없지만

작업관리자를 보면 IE의 프로세스 메모리점유율이 장시간에 걸쳐 상승하다가

어느순간 모든 이미지?관련된(img태그라던가 svg, 그외 flash 객체 등등) 부분들이 하얗게 경직되어

장렬하게 응답없음을 내뱉고 전사합니다.

구글링을 해보니 IE에 GDI관련 리소스관리가 개판이라 릭이 발생한다고 하는데

증상이 같네요. (하얗게 변한후 응답없음)

소스에 문제거나 릭이 발생하거나 객체가 증가하면 무적에 새로고침을 써서라도 릴리즈 하고 싶지만

이증상은 새로고침에도 속수무책입니다 (프로세스 종료가 아닌이상 계속해서 남아있어요..)

해결방법이 존재하지 않나봐염

IE 퇴출좀여 ㅠ



해결) IE 추가기능에 영향을 받아 (시만택 안티바이러스 등) 릭이 생기는 경우가 있다하여

확인해보니 내부네트워크 보안용 PMS 라는 추가기능을 사용안함 하였더니 해결되었음

Error:Error:line (13)cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element  ...


프로젝트 완료후 실서비스를 위해 테스트 하던중 위와같은 오류를 만났다

오류내용을 자세히 뜯어보니 Spring프레임워크의 xml 네임스페이스와 schemaLocation 설정에

문제가 있는듯 했다 

그런데 생각해보니 실서비스를 하는 WAS서버가 내부망으로 묶여 내부망으로의 서비스만을 위한

서버로 인터넷을 연결하지 않는 서버였다.

반나절을 구글링을 해보니 spring-flex integration 라이브러리가 dtd관련한 이슈가 많이 검색되어 

보였다


일반적인 schemaLocation 예시

xsi:schemaLocation="

        http://www.springframework.org/schema/beans 

        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"


스키마의 해당 xsd 주소를 찾아들어가 브라우져의 "다른 이름으로 저장" 기능등을 통해 

xsd 를 다운받는다.


절대경로로 설정한 schemaLocation 예시 

(참조가 필요할때 해당 URL이 아닌 내부 파일시스템에서 참조)

xsi:schemaLocation=" 

        http://www.springframework.org/schema/flex             

        file:///C:/Workspace/LTEB/WebContent/WEB-INF/lib/spring-flex-1.5.xsd"


※ schemaLocation 설정시 함께 설정하는 xml 네임스페이스(xmlns)와 URL이 한쌍이다. 






tomcat-jdbc로 MySQL에 연결한 경우 "java.net.SocketException: Broken pipe" 에러가 발생하는 경우를 가끔 볼 수 있다. 대부분의 경우 connection idle time이 MySQL에 설정된 wait_timeout을 지나서 DB에서 연결을 끊은 것이다. 이를 방지하려면 connection이 일정 기간동안 사용되지 않으면 close되도록 설정하거나 connection 대여시에 connection을 체크하도록 하면 된다.


설정 1 - 일정 기간동안 사용되지 않으면 connection을 테스트

validationQuery="SELECT 1"

testWhileIdle="true"

minEvictableIdleTimeMillis="3600000"

timeBetweenEvictionRunsMillis="60000"


(*) DB에 쿼리를 하기 때문에 이 때마다 DB의 session idle time이 갱신된다. 만약 connection이 이미 끊겼다면 에러가 발생할테고 해당 connection은 pool에서 제거된다.


(*) timeBetweenEvictionRunsMillis의 기본값은 5000 (5초)이고, minEvictableIdleTimeMillis의 기본값은 60000 (60초)이다. minEvictableIdleTimeMillis 값은 MySQL에 설정된 wait_timeout이나 방화벽에 설정된 session timeout 값보다 작아야 한다.


설정 2 - connection 대여 시 테스트

validationQuery="SELECT 1"

testOnBorrow="true"


(*) 매번 connection 대여 시 마다 체크하는 것은 아니다. 체크 한 connection은 validationInterval 기간 안에는 다시 체크하지 않는다. validationInterval의 기본값은 30000 (30초).


설정 3 - 일정 기간동안 사용되지 않으면 connection을 close

minIdle="0"


설정 1을 사용한 JDBC Resource 설정 예

 context.xml

 <?xml version="1.0" encoding="UTF-8"?>

<Context>

<Resource name="jdbc/testDB" auth="Container" type="javax.sql.DataSource"

factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"

driverClassName="com.mysql.jdbc.Driver"

url="jdbc:mysql://localhost/smartconnect?useUnicode=true&amp;characterEncoding=utf8"

username="username" 

password="password" 

initialSize="10" 

minIdle="10"

maxIdle="50" 

maxActive="50" 

maxWait="5000"

validationQuery="SELECT 1"

validationInterval="30000"

testWhileIdle="true" />

</Context>


tomcat-jdbc PoolCleaner 동작

PoolCleaner thread는 timeBetweenEvictionRunsMillis 만큼 sleep하다 idle/abandoned connection을 체크한다.

  • removeAbandoned="true"이면 abandoned connection 체크
    • connection이 대여된 후 removeAbandonedTimeout (초, 기본값 60)안에 반납되지 않으면 connection을 pool에서 제거하고 close한다.
  • pool의 idle connection 개수가 minIdle보다 크면 체크
    • idle connection 개수가 minIdle이 될 때 까지 마지막 사용시간이 minEvictableIdleTimeMillis (기본값 60000)을 지난 idle connection을 찾아 pool에서 제거하고 close한다.
  • testWhileIdle="true"이면 idle connection들에 대해 validation 테스트
    • 전체 idle connection에 대해 validationQuery에 설정된 SQL을 수행해서 Exception이 발생하면 pool에서 제거하고 close한다.


MySQL wait_time 설정값 확인 방법 (단위: 초)

mysql>select @@global.wait_timeout;

+-----------------------+

| @@global.wait_timeout |

+-----------------------+

|                 28800         |

+-----------------------+

1 row in set (0.00 sec)



[출처] Tomcat7 tomcat-jdbc 설정 - Broken pipe 에러 회피|작성자 소프  

http://blog.naver.com/clotho95?Redirect=Log&logNo=140142861915






maxActive - 연결할 커넥션의 최대 갯수

maxIdle - 풀에 대기시킬 커넥션의 최대 갯수

minIdle - 풀에 대기시킬 커넥션의 최소 갯수 

  (0은 놀고있는 커넥션을 풀에 간직하지 않고 모두 close함을 뜻한다)


당연히 maxActive 값보다 maxIdle 값은 적어야 하며

maxIdle 보다 minIdle 값은 또 적어야 한다.


minIdle 을 0이상 잡을 경우

DB의 일방적인 세션 끊김을 방지하는 차원으로

testWhileIdle="true" 의 validation 속성을 추가로 설정하는것이 좋다.


ParameterDefaultDescription
validationQueryThe SQL query that will be used to validate connections from this pool before returning them to the caller. If specified, this query MUST be an SQL SELECT statement that returns at least one row.





작업할게 있어

새로운 이클립스 Indigo에 Aptana 3 plugin 설치후 JQuery 번들을 설치하려하는데


This Terminal Emulator is not functional because no 'bash' shell could be found. Please correct the problem and restart the IDE.

 

와 같은 메시지가 터미널에 뜨며 아무런 터미널 작업이 안되네요 ;;

같은 문구로 비슷한 문제가 많아 한참 구글링하다 겨우 해결방법을 찾았습니다.

이클립스에서 Aptana3 Plugin 설치시 사용된 Workspace 의 \.metadata 폴더를 찾으신후

.metadata\.plugins\org.eclipse.core.runtime\.settings 경로 안에 있는

org.eclipse.core.runtime.prefs 파일을 메모장등으로 열어

"ignore_no_git=true" 라인을 삭제해주세요.

그리고 이클립스를 제기동하시면 자동으로 Preference - Team - Git 의 경로를 새로 설정하고

정상 동작합니다.

이래도 안되신다면

http://wiki.appcelerator.org/display/tis/Git#Git-ReInstallingPortableGit 

를 참고하셔서 Git 를 수동으로 설치하시면 됩니다.


 

ORA-01861: literal does not match format string
 

JDBC를 통한 SQL Insert 를 할경우 다음과 같은 에러 메시지가 발생한다

java.sql.SQLDataException: ORA-01861: literal does not match format string(스트링이 형식에 맞지 않는다....)

 

TOAD나 Orange등 DB Tool을 사용하여 SQL Insert 할경우는 정상이다

 

이런 경우, 사용하는 WAS 계정의 .profile에 한글설정이 제대로 안된 경우가 대부분이다

.profile에 아래와 같이 한글 캐릭터셋 설정부분 추가후 WAS를 재기동 해주면 문제는 깨끗이 해결된다



# TESTSvr#]  ./.profile (.profile 적용)

# TESTSvr#] vi .profile


export LANG=ko_KR.eucKR


작성자 으랏차차

[출처] ORA-01861: literal does not match format string  

 



 

설명을 덧붙이자면 약간 복잡한 아무쿼리던지
 

아주 쌩뚱맞게 이런증상이 나옵니다. 꼭 Insert만 그런것은 아니고..

프로젝트를 UTF던 eucKR이던 뭐던 아무상관없이 발생하며

JDBC가 참고할수있도록  profile 또는 bash_profile 에 추가해줘야합니다.


Where 절에 to_Char, to_Date  등이 겹치고 좀 복잡해지면 자주 보이는 증상인데

로컬 이클립스환경이나 특정 개발환경에서 잘 동작하다가도 실서비스 이후

갑자기 쿼리에서 ORA-01861 오류가 발생하면 의심해봐야하는 첫번째 증상입니다. 




'개발 > Other' 카테고리의 다른 글

Serveral ports (8005, 8080, 8009) required by Tomcat...  (0) 2010.04.07

이클립스에서 Aptana Plugin 을 설치방법입니다.

 




주소는 "http://download.aptana.com/studio3/plugin/install" 입니다.
 

Help - Install New Software 에서 설치하시면 되구요~

Dynamic Web 개발환경에서 HTML5 힌트까지 지원되는 JavaScript 개발환경을 지원해줍니다.

더 나아가서 Android ADB 플러그인까지 설치하고 웹앱도 개발가능하구요

개발환경은 역시 이클립스를 벗어날수가 업네요

 

웹앱 & 일반웹 프로젝트 개발환경 구축을 위해 Appspresso 를 사용중인데

Appspresso 의 커스터마이징 플러그인으로는 Dynamic 웹프로젝트의 생성이 안되고

그렇다고 재설치 역시 오류가 나는 ㅠ

일단 아래와 같이 플러그인을 설치하고



프로젝트는 Static Web Project로 생성하여 클라이언트(뷰) 부분만 개발하고

서버는 별도의 일반 이클립스의 Dynamic 웹프로젝트로 뷰단 없이 (그대로 화면출력형태) 개발한후

두개의 프로젝트를 서로 연결하는 방법으로 테스트 하고 있는데..;

안드로이드 앱스프레소 프로젝트도 SDK 2.1 고정이고... 디바이스 지원외에 장점을 찾기가 조금..

기존방식데로 이클립스에 안드로이드 개발환경을 설치하고 Aptana HTML5 코드힌트 플러그인

설치하고 안드로이드 프로젝트 하나만들어서 웹뷰올리고 로테이션 처리대충하고 

HTML 에 필요한 JS받아 올려놓고, Dynamic 프로젝트에서 WebApp 개발해가며, 뷰단 개발해가며

쓰는것이 아직은 손에 더 맛는다고 해야하나..


좀 느려서 그렇지 그래도 암호/복호화가 필요하면 많이 쓰이는 기법이지요

어서 줏어듣기로는 키를 모르면 일일이 푸는데 계산상 100년이걸린다고 합니다;

-----------------------------------------------------------------------------------------
package AES;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class AES {    
    // 128 비트는 키가 16글자, 192, 256비트는 각각 24, 32글자임
    public static String key = "wtfrudoinganpang";

    /**
     * hex to byte[] : 16진수 문자열을 바이트 배열로 변환한다.
     * 
     * @param hex    hex string
     * @return
     */
    public static byte[] hexToByteArray(String hex) {
        if (hex == null || hex.length() == 0) {
            return null;
        }

        byte[] ba = new byte[hex.length() / 2];
        for (int i = 0; i < ba.length; i++) {
            ba[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
        }
        return ba;
    }

    /**
     * byte[] to hex : unsigned byte(바이트) 배열을 16진수 문자열로 바꾼다.
     * 
     * @param ba        byte[]
     * @return
     */
    public static String byteArrayToHex(byte[] ba) {
        if (ba == null || ba.length == 0) {
            return null;
        }

        StringBuffer sb = new StringBuffer(ba.length * 2);
        String hexNumber;
        for (int x = 0; x < ba.length; x++) {
            hexNumber = "0" + Integer.toHexString(0xff & ba[x]);

            sb.append(hexNumber.substring(hexNumber.length() - 2));
        }
        return sb.toString();
    } 

    /**
     * AES 방식의 암호화
     * 
     * @param message
     * @return
     * @throws Exception
     */
    public static String encrypt(String message) throws Exception {

        // use key coss2
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");

        // Instantiate the cipher
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

        byte[] encrypted = cipher.doFinal(message.getBytes());
        return byteArrayToHex(encrypted);
    }

    /**
     * AES 방식의 복호화
     * 
     * @param message
     * @return
     * @throws Exception
     */
    public static String decrypt(String encrypted) throws Exception {

        // use key coss2
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");

        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] original = cipher.doFinal(hexToByteArray(encrypted));
        String originalString = new String(original);
        return originalString;
    }
    
    public static void main(String[] args)
    {
        try {
            String encrypt = encrypt("test1234");
            System.out.println("origin str = "+"test1234");
            System.out.println("encrypt str = "+encrypt);
            
            String decrypt = decrypt(encrypt);
            System.out.println("decrypt str = "+decrypt);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
}


 

5년전에 만들어 묵혀두었던 라이브러리인데

HTML로 플젝트를 진행하게 되면서 도로 꺼내보네욥

근데 5년된 소스치고 상당히 괜찮아보여 혼자쓰기 아까워 구글코드에 등록을 했습니다.

맘껏 가져다 쓰시고 고치시고 하세욥

http://code.google.com/p/sollayer/