이것저것 돌아다니다가 결국은 블로그는 아직은 플랫폼 지원을 받는게 더 편하겠다라는 생각으로 다시 리턴했다.

다시 작성해봐야지.. 기존에 있던 글은 부끄럽지만 그냥 냅두기로 했다. 

오류 메세지 : 

Invalid property 'metaDatas[256]' of bean class[com.comas.solme.ecm.admin.cm.action.ContentsModel]: Index of out of bounds in property path 'metaDatas[256]'; nested exception is java.lang.IndexOutOfBoundsException: Index: 256, Size: 256
DefaultController.java
@Controller
public class DefaultController {
    public static class Command {
        private List<MetaValueModel> metaDatas = new ArrayList<MetaValueModel>();
        // ...
    }
 
    public void edit(@ModelAttribute Commmand commmand) {
        // ...
    }
 
 
}

 

위와 같은 오류는 스프링 MVC 에서 폼 Path 에 해당하는 속성의 컬렉션 크기를 256으로 설정되어 있기 때문에 발생한다. 엄밀히 말하면 오류라기보다는 설정상의 문제.

다음과 같이 컬렉션의 제한 크기를 늘려주면 된다.  주의할 점은 반드시WebDataBinder 설정시 가장 먼저 setAutoGrowNestedPaths 값을 true 로 바꿔주고 초기화를 진행해야한다는 것이다. 안 그럼 "DataBinder is already initialized - call setAutoGrowNestedPaths before other configuration methods" 이런 오류를 만날 것이다.

  • binder.setAutoGrowNestedPaths(true);
  • binder.setAutoGrowCollectionLimit(5000);

 

DefaultController.java
@Controller
public class DefaultController {
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.setAutoGrowNestedPaths(true); // insert this line
        binder.setAutoGrowCollectionLimit(5000); // insert thist line
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        binder.registerCustomEditor(Date.classnew CustomDateEditor(dateFormat, true));
        binder.registerCustomEditor(String.classnew StringTrimmerEditor(true));
    }
}


요새는 gradle 쓰지, ant 를 얼마나 쓸까 싶으냐만은 언제나 후다다닥 할땐-_-)s


.. 자

Ant 빌드에서 메이븐 명령어를 사용하는 방법이다.

전체적인 스텝은 다음과 같다. 

  1. maven-ant-task 다운로드
  2. build.xml 에 namespace 추가
  3. 메이븐 홈 위치 설정
  4. target 작성 후 target 안에 artifact:xxxxx 와 같은 task 추가
  5. target  실행

이제 각 단계 별로 자세히 알아보자.

1.Maven Ant Task 다운로드

ant 에서 maven 을 사용하기 위해서는 maven 이 제공해주는 ant 용 메이븐 task 가 필요한다.

다음 사이트에서 maven-ant-task-x.x.x.jar 파일을 다운로드받는다. (본 문서 작성시에 안정버젼은 2.1.3 이였다.)

Download Site : http://maven.apache.org/ant-tasks/

다운받은 maven-ant-task-x.x.x.jar 파일을 build.xml 이 참조할 수 있는 위치에 둔다. (ex: src/antlib/maven-ant-task-2.1.3.jar)

2.build.xml 에 namespace 추가

build.xml 의 루트 element 인 project 엘리먼트에 다음과 같이 artifact namespace 를 추가한다.

이때 maven-ant-task.classpath 패스에 1단계에서 내려받은 maven-ant-task-x.x.x.jar 를 참조할 수 있도록 위치를 지정한다.

build.xml
<?xml version="1.0" encoding="utf-8" ?>
<project name="ECM RPC Project" default="genkey" basedir="." xmlns:artifact="antlib:org.apache.maven.artifact.ant">
    <path id="maven-ant-tasks.classpath" path="src/antlib/maven-ant-tasks-2.1.3.jar" />   
    <typedef resource="org/apache/maven/artifact/ant/antlib.xml"
             uri="antlib:org.apache.maven.artifact.ant"
             classpathref="maven-ant-tasks.classpath" />
</project>

 

3.자신의 환경에 맞도록 메이븐 홈 위치 설정

사용할 메이븐 홈 디렉토리를 설정한다. 본 문서에서는 시스템 환경변수로부터 읽어들였다.

build.xml
<?xml version="1.0" encoding="utf-8" ?>
<project name="ECM RPC Project" default="genkey" basedir="." xmlns:artifact="antlib:org.apache.maven.artifact.ant">
    <path id="maven-ant-tasks.classpath" path="src/antlib/maven-ant-tasks-2.1.3.jar" />   
    <typedef resource="org/apache/maven/artifact/ant/antlib.xml"
             uri="antlib:org.apache.maven.artifact.ant"
             classpathref="maven-ant-tasks.classpath" />
     
    <property name="maven-home.path" value="${env.M2_HOME}" />
     
</project>

 

4.target 작성

메이븐 명령어(mvn)도 결국은 ant target 으로 실행된다. target 을 생성한 후 하위에 필요한 maven task 를 작성하도록 하자.

메이븐 task 들은 2단계에서 설정한 namespace 로 찾을 수 있다.

자세한 모든 task 는 공식 사이트(http://maven.apache.org/ant-tasks/) 를 참조하라.

다음은 "mvn clean war:exploded -Pcomas -Pslothink1" 과 동일한 명령어를 수행하는 task 이다.

build.xml
<target name="make-webapp-with-slothink1-profile">
    <artifact:mvn pom="pom.xml" mavenHome="${maven-home.path}" fork="true">
        <arg value="clean"/>
        <arg value="war:exploded"/>
        <arg value="-Pcomas"/>
        <arg value="-Pslothink1"/>
    </artifact:mvn>
</target>

 

5.target 실행

4단계에서 설정한 target 을 실행한다. 

 

참조 : http://maven.apache.org/ant-tasks

일반적으로 자바 디컴파일러에 JAD 를 많이 사용하나, JAD 는 1.5 버젼부터는 잘 지원안된다.

그래서 보통 JD 를 많이 사용하는데, JD core 를 이용한 JD-Gui 를 이용하여 주로 사용한다.

허나, 이 또한 일부 디컴파일된 파일이 불안전할 수 가 있는데, 그 대안으로 cfr 을 추천한다.

cfr 또한 불안전한 파일이 나올 수 있으므로 본인은 JD-Gui 로 선행 작업 후, 컴파일 오류가 나는 것들에 대해서 cfr 로 디컴파일한 파일들을 사용한다. 

CFR

cfr 은 java 로 개발된 디컴파일로써, java8 의 람다와 java 7 의 switch 등을 지원한다.

http://www.benf.org/other/cfr/ 에서 최신 버젼을 내려 받은 후 다음과 같이 실행하면 된다. (문서 작성 당시에 cfr 버젼은 0.8.1 이었다.)

> java -jar cfr_0_81.jar <디컴파일할 jar 파일 경로> --outputdir <디컴파일된 소스 파일이 등록될 경로>

다음은 샘플이다.

D:\App\cfr>java -jar cfr_0_81.jar lnk.jar --outputdir d:/app/cfr/result

물론 이렇게 단순한 방법 말고도, 디컴파일시 소스 번호가 나오게 한다던지 등등 다양한 옵션이 존잰한다.

자세한 방법은 --help 를 쳐보면 된다 (웃음)

D:\App\cfr>java -jar cfr_0_81.jar --help
CFR 0_81
   --showops                        (int >= 0)  default: 0
   --decodeenumswitch               (boolean)  default: true if class file from
version 49.0 (Java 5) or greater
   --sugarenums                     (boolean)  default: true if class file from
version 49.0 (Java 5) or greater
   --decodestringswitch             (boolean)  default: true if class file from
version 51.0 (Java 7) or greater
   --arrayiter                      (boolean)  default: true if class file from
version 49.0 (Java 5) or greater
   --collectioniter                 (boolean)  default: true if class file from
version 49.0 (Java 5) or greater
   --innerclasses                   (boolean)  default: true
   --removeboilerplate              (boolean)  default: true
   --removeinnerclasssynthetics     (boolean)  default: true
   --decodelambdas                  (boolean)  default: true if class file from
version 52.0 (Java 8) or greater
   --hidebridgemethods              (boolean)  default: true
   --liftconstructorinit            (boolean)  default: true
   --removedeadmethods              (boolean)  default: true
   --removebadgenerics              (boolean)  default: true
   --sugarasserts                   (boolean)  default: true
   --sugarboxing                    (boolean)  default: true
   --showversion                    (boolean)  default: true
   --decodefinally                  (boolean)  default: true
   --tidymonitors                   (boolean)  default: true
   --lenient                        (boolean)  default: false
   --dumpclasspath                  (boolean)  default: false
   --comments                       (boolean)  default: true
   --forcetopsort                   (boolean)
   --forceexceptionprune            (boolean)
   --outputdir                      (string)
   --stringbuffer                   (boolean)  default: false if class file from
 version 49.0 (Java 5) or greater
   --stringbuilder                  (boolean)  default: true if class file from
version 49.0 (Java 5) or greater
   --silent                         (boolean)  default: false
   --recover                        (boolean)  default: true
   --eclipse                        (boolean)  default: true
   --override                       (boolean)  default: true if class file from
version 50.0 (Java 6) or greater
   --aexagg                         (boolean)
   --forcecondpropagate             (boolean)
   --hideutf                        (boolean)  default: true
   --hidelongstrings                (boolean)  default: false
   --commentmonitors                (boolean)  default: false
   --allowcorrecting                (boolean)  default: true
   --labelledblocks                 (boolean)  default: true
   --j14classobj                    (boolean)  default: false if class file from
 version 49.0 (Java 5) or greater
   --hidelangimports                (boolean)  default: true
   --recovertypeclash               (boolean)
   --forcereturningifs              (boolean)
   --help                           (string)

  

참조 : 다른 디컴파일러들에 대한 정보는 다음 링크에 잘 나와있다.

https://community.jboss.org/people/ozizka/blog/2014/05/06/java-decompilers-a-sad-situation-of

윈도우 서비스로 시작된 프로그램이 네트워드 드라이브에 연결된 저장소에 연결할 때에 접근 권한이 필요하다.

다음과 같은 스크립트를 실행해줌으로써, 권한을 적용할 수 있다.


[allow-access.bat]

@echo off

SET USER=YourWindowAccount

SET PASSWD=YourWindowAccountPassword

SET SERVER=123.123.123.123


net use Y: \\%SERVER%\to\access\repository %PASSWD% /user:%USER% /persistent:yes


Intellj IDEA 에서 java 파일의 크기가 너무 클 경우 컴파일이 안되는 경우가 있다.

그럴 경우에는 아이콘이 다음과 같이 나타난다.

이럴 경우에는 idea.properties 파일의 idea.max.intellisense.filesize 의 값을 늘려주자.

idea.properties
#---------------------------------------------------------------------
# Maximum file size (kilobytes) IDE should provide code assistance for.
# The larger file is the slower its editor works and higher overall system memory requirements are
# if code assistance is enabled. Remove this property or set to very large number if you need
# code assistance for any files available regardless their size.
#---------------------------------------------------------------------
idea.max.intellisense.filesize=25000

기본값은 2500 이며, 필요한 크기만큼 늘려준다.


Idea.properties

idea.properties 파일은 ${INTELLIJ_HOME}/bin 디렉토리에서 찾을 수 있다.

예로 Win7(64bit) 의 경우엔 C:\Program Files (x86)\JetBrains\IntelliJ IDEA 12.1.6\bin 이다.

None 
     Edit Labels


    허드슨 마스터 서버외에 다른 서버에서 허드슨 마스터의 서버를 통제받고 싶다면 허드슨 슬레이브를 추가하면 된다. 

    1.슬레이브 서버에 허드슨 슬레이브 jar 다운로드

    우선, 슬레이브가 추가될 서버에서 마스터에 접속해 라이브러리를 받아야한다.

    다음과 같이 허드슨 마스터 URL 하위에 붙여서 라이브러리를 다운 받는다.

    download_slave.sh
    shell> mkdir hudson
    shell> cd hudson
    shell> wget http://yourserver:port/jnlpJars/slave.jar

    2. 관리콘솔에서 허드스 슬레이브 서버 등록

    hudson 관리콘솔에서 Manage/Manage Nodes 페이지로 접속한다.


    2.1 '신규노드'를 클릭한다.



    2.2 노드명 입력

    노드명을 입력한다. 슬레이브가 설치되는 서버명을 입력하고 'OK' 를 클릭한다.



    2.3 기본 정보 입력

    노드의 기본 정보를 입력하는데, 주요 필수 속성은 다음과 같다. 잘 입력해주자.

    PropertyDescriptionExample
    Name관리콘솔에서 식별하는 슬레이브 서버(노드)명

    demo-app

     

    #of executors
    작업이 한번에 돌아가는 수. 일반적으로 cpu 코어의 수 만큼 맞춘다.1
    Remote FS root

    슬레이브 서버의 hudson slave 가 설최드는 물리적인 경로

    slave.jar 파일이 받아진 위치를 지정한다.

    /home/slothink/hudson
    Launch Method

    마스터와 슬레이브 연결 지정방식이다.

    • Launch slave agents vis JNLP : JNLP 프로토콜을 이용해서 슬레이브에서 마스터로 접속한다.
    • Launche slave via execution of command on the Master : 마스터에서 커맨드 입력을 통해 슬레이브로 접속한다.

    여기에서는 JNLP 프로토콜을 사용하도록 한다.

     



    2.4 Tool Location 입력

    그리고 엄청 중요한 노드 속성들을 입력한다.

    Node Properties 의 Tool Locations 를 설정하지 않으면, 해당 툴을 이용한 작업들이 원격(슬레이브)에서 실행되지 않는다.

    슬레이브 서버에 존재하는 툴에 대한 물리적인 경로를 입력해준다.



    'save' 를 클릭한다. 그러면 다음과 같이 추가된 노드를 볼 수 있다. 



    아직 슬레이브 연결을 하지 않았으므로 공포의 X가 보인다.

    3. Hudson Slave 연결

    이제 노드 관리 화면에서 방금 추가한 노드를 선택하면 다음과 같은 화면이 나온다.



    여기서 나온 실행명령어를 슬레이브 서버의 허드슨 디렉토리(slave.jar 있는 곳)에서 실행한다.

    slave-start.sh
    java -jar slave.jar -jnlpUrl http://source.comas.co.kr:12080/hudson/computer/demo-app/slave-agent.jnlp

    콘솔에 Connected 라는 메시지가 나오고 관리 콘솔에 다음과 같이 나오면 정상 연결된것이다.



    4.작업 생성

    이제 작업을 원격에서 실행할 수 있도록 하면 된다.

    4.1 새 작업 생성

    '새 작업' 을 클릭한다. 

    기본 작업명 하고, 이건 알아서 스스로 어린이.



    4.2 실행할 노드 선택

    그리고 'Restrict where this job can be run' 을 체크한다.

    작업을 실행할 슬레이브 노드 선택방법에 따라 다음과 같이 선택한다.

    ValueDescription
    Node and label menu특정한 노드를 선택한다.
    Advanced Node and Label expressions

    표현식으로써 여러개의 노드를 선택할 수 있다. 예로 들어

    aix1 -> aix2 -> demo-app 라고 지정하면, aix1 번에서 작업 후, aix2 에서 작업 후, 마지막으로 demo-app 에서 작업하게 된다.

    자세한 것은 오른쪽의 도움말 참조.


    그리고 저장하고 실행해본다.


    Building remotely on ... 가 나오면 이제 울면 된다. TT-TT 

    이제 진정한 노가다 배포에서 해결할 준비가 되었다.

    AIX 에 SSH 설치 방법이다.
    엔지니어에겐 같잖은내용이지만, 유닉스 생초는 이런게 아주 귀할거다. ㅜㅜ

    1.openssl, openssh 이미지 획득

    다음 링크에서 최신 openssl 과 openssh 이미지를 다운 받는다.

     다운로드 URL : https://www14.software.ibm.com/webapp/iwm/web/preLogin.do?source=aixbp 

    본 문서에서는 openssl-0.9.8.2500.tar.Z 와 OpenSSH_6.0.0.6102.tar.Z 를 받았다.

    각 파일을 압축을 푼다.

    uncompress.shell
    shell> uncompress openssl-0.9.8.2500.tar.Z
    shell> tar xvf openssl-0.9.8.2500.tar

    2.Smitty 로 이미지 설치하기

    다음과 같이 수행한다. (실행 위치는 상관없다.)

    install.shell
    shell> inutoc .
    shell> smitty install_selectable_all

    smitty 가 뜨면 다음과 같은 순으로 진행한다.

    1. INPUT device/directory for software 안에 이미지가 들어있는 디렉토리를 입력한 후 엔터친다. 예) /tmp/comas/dn/aix/openssl-0.9.8.2500, /tmp/comas/dn/aix/OpenSSH_6.0.0.6102
    2. F4 를 누른다. 이때 설치할 패키지가 놔야한다.
    3. F7 을 눌러가면서 모든 패키지를 선택한 후 엔터를 친다.
      1. 실제 버젼까지 들어있는 패키지를 선택한다. 그룹핑 되어있는 레이블은 선택하지 않는다.
      2. 라이센스도 꼭 설치한다.
      3. msg 는 자기가 사용하는 언어를 설치한다.
    4. ACCEPT new license agreements? 가 있을 경우(없다면 5단계로) 해당 라인 선택 후 F7 을 눌른 후, Tab 을 눌러 yes 로 바꿔준후 엔터친다.
    5. 다시 한번 엔터친다.
    6. 마지막으로 진행할 거냐 묻는데 엔터친다.
    7. F10 눌러 종료한다.
    이과 같이 openssl 먼저 설치한 후 openssh 도 설치한다.
    설치가 되면 자동으로 OpenSSH 가 실행된다. 여튼 시작과 정지 명렁어는 다음과 같다.

    3. SSH 실행과 정지

    ssh-start-stop.shell
    startsrc -s sshd # 시작
    stopsrc -s sshd # 정지

     

    참조 : 

     

    tar 를 풀 때, 리눅스에서 아카이빙 한 경우일 경우 체크섬 오류가 발생하는 경우다.

    error-shell
    #tar xvf Java6_64.sdk.6.0.0.425.tar
    tar: 0511-169 A directory checksum error on media; 804399360 not equal to 12401.

    이것은 리눅스용 파티션에서 아카이빙한 것을 다른 파티션 형태인 AIX 에서 풀 때 발생하곤한다.

    그럴 땐, 리눅스용 tar, gnu tar 를 설치하면 된다.

    해당 라이브러리리는 다음에서 찾을 수 있다. 이름하여 "AIX Toolbox for Linux Applications" (gtar 외에도 리눅스용 커맨드가 많다.)

    http://www-03.ibm.com/systems/power/software/aix/linux/toolbox/ezinstall.html

    이곳에서 tar 를 다운받아 설치한다.

    shell
    # ls
    Java6_64.sdk.6.0.0.425.tar
    tar-1.22-1.aix6.1.ppc.rpm
    # rpm -ivh tar-1.22-1.aix6.1.ppc.rpm
    tar                         ##################################################
    #

    설치한 후에는 gtar 이용하여 linux tar 사용하듯이 사용하면 된다.

    shell
    # ls
    Java6_64.sdk.6.0.0.425.tar
    subversion-1.4.6-apache-python (1).tar.gz
    tar-1.22-1.aix6.1.ppc.rpm
    # gtar -xvf Java6_64.sdk.6.0.0.425.tar
    Java6_64.sdk
    #

    에에에에에~

    Nexus 에 배포(deploy)할 때, 400 에러가 날 경우 (보통 릴리즈 버젼) 에는 넥서스의 리파지토리의 중복 등록 허용이 불가로 설정되어있을 경우 그러하다.

    err.log
    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.5:deploy (default-deploy) on project ecm-parent: Failed to deploy artifacts: Could not transfer artifact com.comas.solme.ecm:ecm-parent:pom:5.0.0 from/to releases (http://nexus.yourcompany.co.kr:8081/nexus/content/repositories/releases): Failed to transfer file: http://nexus.yourcompany.co.kr:8081/nexus/content/repositories/releases/com/comas/solme/ecm/ecm-parent/5.0.0/ecm-parent-5.0.0.pom. Return code is: 400 -> [Help 1]

    다음과 같이 'Allow Redeploy'로 바꿔주자.



    1. BlogIcon 서류 2013.12.17 16:03

      구글링하다 따뜻한 한글 문서가~ 권한문제인 줄로만 알고 삽질하다ㅋ 감사합니다.

      • BlogIcon slothink 편현장 2014.01.02 11:06 신고

        도움이 되셨다니, 참 다행이네요. 댓글까지 달아주니, 포스팅 하는 것에 대한 보람을 느낍니다. 감사해요 ㅠ_ㅠ


    error.log
    javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of com.comas.solme.framework.servicelib.board.Board.orderNo
        org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1389)
        org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:802)
        org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:756)

    위와 같은 오류는 null 일 수 없는 컬럼을 가진 레코드가 있을 경우 발생한다.

    대개, 이미 레코드가 존재하는 상황에서 boolean 등의 속성이 추가로 생성되어(컬럼이 생성되어) 기존 데이터 값을 null 로 초기화 하므로 발생한다.

    이럴 경우에는 해당 객체의 속성에 해당하는 컬럼의 값을 적절한 값으로 초기화 하는 작업을 해줘야한다.

    위 오류와 같은 경우에는 다음과 같이 해결할 수 있다.

    fix.sql
    update BOARD set ORDER_NO = 0 where ORDER_NO is null;
    None  Edit Labels


    Java 로 구현하는 JMeter 샘플러 구현방법이다.

    우선 다음의 라이브러리를 의존 라이브러리로 추가한다.

    pom.xml
    <dependency>
        <groupId>org.apache.jmeter</groupId>
        <artifactId>ApacheJMeter_core</artifactId>
        <version>2.8</version>
    </dependency>           
     
    <dependency>
        <groupId>org.apache.jmeter</groupId>
        <artifactId>ApacheJMeter_java</artifactId>
        <version>2.8</version>
    </dependency>

    작성할 주요 부분은 다음 4가지 부분이다.

    • AbstractJavaSamplerClient 상속 받기
    • 기본 파라미터 생성 부분
    • 파라미터 가져오는 부분
    • 실행 하는 부분

    AbstractJavaSamplerClient 상속받기

    Jmeter 테스트 소스로 인식하고 잘 동작하기 위해서 AbstractJavaSamplerClient 를 상속받아 자신의 클래스를 만든다.

     

    CreateFileTest.java
    public class CreateFileTest extends AbstractJavaSamplerClient implements Serializable {
     
     
    }

     

    기본 파라미터 생성

    기본 파라미터는 JMeter 화면에서 테스트 클래스를 선택했을 때 나타나는 다음과 같은 파라미터 화면이다.



    이 기본 값들을 생성해줌으로써 좀 더 테스트가 원할해질 수 있겠다.

    CreateFileTest.java
    @Override
    public Arguments getDefaultParameters() {
        Arguments params = new Arguments();
        params.addArgument("url", "http://localhost:8080/vine-rpc");
        params.addArgument("file", "input file path");
        params.addArgument("limitFileSize", "-1");
        params.addArgument("maxFileSizeForHessian", "-1");
        return params;
    }

    파라미터 가져오기

    파라미터 가져오는 단계는 테스트 소스를 실행할 때, 사용자가 입력한 파마미터를 실행 클래스에 전달해 실행을 준비한다.

    말을 어렵게 했지만, 여튼 사용자가 입력한 값을 테스트 클래스에서 가지고 간다는거다.

    CreateFileTest.java
    private long limitFileSize = -1L;
    private long maxFileSizeForHessian = -1L;
    private File file;
    private EcmClient ecmClient;   
     
    @Override
    public void setupTest(JavaSamplerContext context) {
        getLogger().debug(whoAmI() + "\tsetupTest()");
        listParameters(context);
        limitFileSize = context.getLongParameter("limitFileSize", limitFileSize);
        maxFileSizeForHessian = context.getLongParameter("maxFileSizeForHessian", maxFileSizeForHessian);
        String url = context.getParameter("url");
        this.file = new File(context.getParameter("file"));
                 
        DomainConfig config = new DomainConfig();
        config.setLimitFileSize(limitFileSize);
        config.setMaxFileSizeForHessian(maxFileSizeForHessian);
        config.getUrls().add(new EcmUrl(url));
         
        Configuration configuration = new Configuration(config);
        ecmClient = configuration.makeStub();
         
    }

     

    실행 부분

    이부분은 아주 중요한 부분이다. 

    SampleResult 를 생성하고, 던져줘야하며. 실제 시간을 체크하고 싶은 시점에 sampleStart 와 sampleEnd 를 찍어준다.

    CreateFileTest.java
    public SampleResult runTest(JavaSamplerContext context) {
        SampleResult results = new SampleResult();
        FileInputStream fis = null;
        try {
            // Record sample start time.
            results.sampleStart();
            fis = new FileInputStream(this.file.path);
            ecmClient.createFile(this.file.name, null,null, null, fis);
            results.setSuccessful(true);
        } catch (Exception e) {
            results.setSuccessful(false);
        } finally {
            IOUtils.closeQuietly(fis);
            results.sampleEnd();
        }
        return results;
    }


    배포하기

    만들어진 소스는 jar 파일 형태로 패키징하여 ${JMETER_HOME}/lib/ext 에 넣는다.

    그리고 재시작하면 된다. 

    이제 다 죽었다..ㅋㅋㅋㅋ

    참조 : http://www.javajigi.net/pages/viewpage.action?pageId=184

    MySQL 에서 Select 질의시에는 잘 읽어들이나, inser, update 시에는 깨질 경우이다.

    MySQL 서버 설정에 다음과 같은 설정이 필요하다.


    #/etc/my.cnf

    [mysqld]
    ...
    default-character-set=utf8
    default-collation=utf8_general_ci
    ...


    물론 UTF-8 관련 설정들도 빠짐없는지 확인해야했음은 물론이다. :)

    • Databse, Table 의 캐릭터셋
    • HttpServletRequest 의 인코딩
    • Java 런타임시 -Dfile.encoding=UTF-8 (이사항은 DB 랑은 직접적인 연관은 없다)

    참조 : http://mathiasrichter.blogspot.kr/2009/10/character-encoding-utf-8-with.html

    대부분이 OOME 등이 발생하면 이런 쉬운것(메모리 분석)도 안해보고 왜 그러지, 왜 그러지 하면서 이것저것 손보는데 시간만 보내기십상이다. 

    일단 이거 엄청 간단하니깐 일단 이렇게부터 해보구 삽질을 했으면 좋겠다.-_- 여우같은 마눌 보러 가야징


    JVM 메모리 분석을 위한 과정은 다음과 같다.

    1. 분석할 프로세스 ID 조회
    2. 메모리 힙덤프 추출
    3. 힙덤프 분석

    분석할 프로세스 ID 조회

    프로세스 id 조회는 ps - ef | grep 찾을 놈 관련된 텍스트 와 같이 하면 아래와 같이 귀찮게 나올 수 있다. 이건 뭐, 얼마 안된 케이스긴 하지만. 여튼 그렇다.

     

    shell.sh
    [freshkorea@multi-003 ~]$ ps -ef | grep freshkorea
    root     12044  3911  0 15:16 ?        00:00:00 sshd: freshkorea [priv]
    1493     12105 26169  0 15:16 ?        00:00:00 /usr/local/apache2/bin/httpd -k start -f /usr/local/apache2/conf/hosting/freshkorea/httpd.conf
    1493     12205 12044  0 15:17 ?        00:00:00 sshd: freshkorea@pts/2
    1493     12655 26169  0 15:17 ?        00:00:00 /usr/local/apache2/bin/httpd -k start -f /usr/local/apache2/conf/hosting/freshkorea/httpd.conf
    1493     12925 26169  0 15:17 ?        00:00:00 /usr/local/apache2/bin/httpd -k start -f /usr/local/apache2/conf/hosting/freshkorea/httpd.conf
    1493     13004 26169  0 15:17 ?        00:00:00 /usr/local/apache2/bin/httpd -k start -f /usr/local/apache2/conf/hosting/freshkorea/httpd.conf
    1493     13005 26169  0 15:17 ?        00:00:00 /usr/local/apache2/bin/httpd -k start -f /usr/local/apache2/conf/hosting/freshkorea/httpd.conf
    1493     14438 12206  0 15:17 pts/2    00:00:00 grep freshkorea
    root     26169     1  0 Jan30 ?        00:05:26 /usr/local/apache2/bin/httpd -k start -f /usr/local/apache2/conf/hosting/freshkorea/httpd.conf
    root     27019  3911  0 15:11 ?        00:00:00 sshd: freshkorea [priv]
    1493     27051 27019  0 15:11 ?        00:00:00 sshd: freshkorea@notty
    1493     29991     1  1 Mar29 ?        00:44:22 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/home/hosting_users/freshkorea/tomcat/conf/logging.properties -XX:MaxPermSize=128m -Xmx128m -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/home/hosting_users/freshkorea/tomcat/endorsed -classpath /home/hosting_users/freshkorea/tomcat/bin/bootstrap.jar -Dcatalina.base=/home/hosting_users/freshkorea/tomcat -Dcatalina.home=/home/hosting_users/freshkorea/tomcat -Djava.io.tmpdir=/home/hosting_users/freshkorea/tomcat/temp org.apache.catalina.startup.Bootstrap start

    그럴 땐 JDK/bin 밑에 있는 jps 명령을 이용하자.

    jps 는 현재 계정의 java 프로세스만 보여준다.

     

    shell.sh
    [freshkorea@multi-003 ~]$ jps
    29991 Bootstrap
    14957 Jps

    와우! 바로 딱 나온다. 

    tomcat 은 실행시 bootstrap.jar 를 이용하기 때문에 bootstrap 으로 나온다.
    이거 가지고 잘 모르겠다면, 'jps -mlv' 이렇게 쳐보라. -_-)b

    메모리 힙덤프 추출

    보통 힙 덤프 뜰 땐 kill -3 <pid> 를 사용한다. 허나, 그렇게 해도 안찍힐 경우에 jmap 을 이용해 보자.
    jmap dump:format=b,file=<output filename> <pid>
    메모리 분석을 위해서 fomat=b 을 줌으로써, 바이너리 파일로 생성해야한다.

     

    healdump.sh
    [freshkorea@multi-003 ~]$ jmap -dump:format=b,file=heap.hprof 29991
    Dumping heap to /home/hosting_users/freshkorea/heap.hprof ...
    Heap dump file created
    [freshkorea@multi-003 ~]$

    힙덤프 분석

    힙덤프는 분석 툴을 이용해 분석하는게 편하다. eclipse 의 mat 은 공짜이면서 leak 원인까지 찾아주는 기능이 있다.

    http://www.eclipse.org/mat/

    받아서 설치하자. (그냥 압축 풀면 끝이다.)

    설치 후에 Fille -> Open -> Heap dump 를 하면 결과가 다음처럼 대충 나온다. 

     

     

    그리고 Details 를 클릭해서 들어가보면 다음과 같이 나온다. 

    여기선 hashMap 이 아주 무식하다는게 드러난다. 

     

    이제 소스를 보면 왜 이런 참상이 생겼는지 알꺼다.

    이렇게 OOME 가 엄청 간단하게 해결되었다.


    Intellij IDEA 시 과도하게 메모리 사이즈를 크게 설정할 경우 다음과 같은 오류가 발생하는 경우가 있다.

    The JVM could not be started. The maximum heap size (-Xmx) might be too large or an antivirus of firewall tool could block the execution.

     

     

    그럴 땐 다음 위치에서 파일을 변경해주면 된다.

    ${INTELLIJ_HOME}/bin/idea.exe.vmoptions

     

     

    기본 설정 값은 다음과 같다.

     

    -Xms128m
    -Xmx512m
    -XX:MaxPermSize=256m
    -XX:ReservedCodeCacheSize=64m
    -XX:+UseCodeCacheFlushing
    -ea
    -Dsun.io.useCanonCaches=false
    1. 2013.06.27 19:55

      경로를 xp기준에서 설명해주시면 안될까요 잘 모르겠네요 ㅠ

      • BlogIcon slothink 편현장 2013.07.07 22:45 신고

        네 기본 설치시에는 다음과 같은 경로입니다.
        c:\Program Files\JetBrains\IntelliJ IDEA 12.0.4\bin/idea.exe.vmoptions

    2. BlogIcon 단군소프트 2015.07.02 18:42 신고

      JetBrians 국내 세미나를 준비하기 위해 설문을 실시하고 있으니 설문 참여하시고 스타벅스 커피 받아가세요.

      http://www.surveygizmo.com/s3/2182487/News-Media
      ↑↑↑ 위 링크로 가셔 설문 가능합니다.

    Oracle 이 XA 를 위한 구성이 되어있지 않을 경우 다음과 같은 오류가 발생할 수 있다.

    error
    WARN[12-11-09 16:09:38]-Error in recovery (com.atomikos.logging.Slf4jLogger.logWarning(Slf4jLogger.java:24))
    javax.transaction.xa.XAException
        at oracle.jdbc.xa.OracleXAResource.recover(OracleXAResource.java:709)
        at com.atomikos.datasource.xa.XATransactionalResource.recover(XATransactionalResource.java:579)
        at com.atomikos.datasource.xa.XATransactionalResource.endRecovery(XATransactionalResource.java:669)
        at com.atomikos.icatch.imp.TransactionServiceImp.recover(TransactionServiceImp.java:604)
        at com.atomikos.datasource.xa.XATransactionalResource.setRecoveryService(XATransactionalResource.java:495)