Red Star OS : http://ashen-rus.livejournal.com/4300.html
크리에이티브 커먼즈 라이센스
Creative Commons License
2010/03/05 15:41 2010/03/05 15:41

Env.sh


start.sh


stop.sh


kill.sh - solaris


kill.sh - unix.linux


크리에이티브 커먼즈 라이센스
Creative Commons License
2010/03/03 17:26 2010/03/03 17:26

보통 bytecode instrumentation을 할 때 cglib, javassist등과 같은 도구를 사용하는 데 JVM 스펙상 이미 로드된 클래스코드에 대한 수정을 허용하지 않기 때문에(만약 조작한다 하더라도 그 코드는 의미가 없을 수 있다고 판단됩니다) javaagent의 premain을 이용하여 로드시점에 대상들에 대한 바이트 코드 조작이 필요합니다.

이 때 javassist를 사용하고 있는데 보통 WAS의 경우 다양한 클래스 로더(예 : EAR, Web, EJB 등)들을 가지고 있기 때문에 javassist에서 해당 클래스들에 대한 참조를 하지 못해 NotFoundException으로 인한 toClass등의 메소드에서 CannotCompileException이 발생합니다.

아래의 예제는 javaagent premain + ClassFileTransformer의 뼈대 코드로 WAS 클래스로더로 로딩되는 클래스를 참조할 수 있도록 합니다.


크리에이티브 커먼즈 라이센스
Creative Commons License
2010/02/22 07:51 2010/02/22 07:51

static으로 선언된 HashMap의 경우 containsKey() 이후 해당 객체를 remove하면 삭제가 되지 않습니다. 너무 당연한 이야기인지도 모르겠습니다.

보통 삭제시킬 key값을 다른 메소드에서 로컬 변수 형태로 선언하고 그 값을 이용하여 삭제하려고 하는데 이 때 스태틱(static)메모리를 사용하는 경우 visible하지 않기 때문이겠지요.

이 경우 다음과 같이 키를 찾아 삭제해야 합니다.


크리에이티브 커먼즈 라이센스
Creative Commons License
2010/02/19 16:19 2010/02/19 16:19

ThreadLocal을 이용하여 호출되는 비즈니스 메소드들의 순서를 추적할 때 사용할 수 있는 예제 코드입니다. 좀 중요한 것을 만들고 있는데 그것의 뼈대 코드라고 할 수 있습니다.

아주 단순한 예제라 그리 어렵지 않을 듯 합니다. ThreadLocal이란 것에 대해서는 구글링을 해보시면 많이 나올 겁니다. 이것과 Java instrumentation을 이용하면 bytecode레벨을 조작하여 성능에 별 영향없이 profiling tool을 만들 수 있습니다.

CapturedTransaction.java

package org.jboss.jam.plugin.profiler;

import java.util.Stack;

public class CapturedTransaction {
protected long startTime = 0L;
protected String methodName;
protected CapturedTransaction(String methodName) {
this.startTime = System.currentTimeMillis();
this.methodName = methodName;
}
protected static ThreadLocal<Stack<CapturedTransaction>> threadLocal = new ThreadLocal<Stack<CapturedTransaction>>() {
protected synchronized Stack<CapturedTransaction> initialValue() {
            return new Stack<CapturedTransaction>();
        }
};
/**
* Starts a CapturedTransaction snapshot.
* Elapsed time will be captured in milliseconds
*/
public static void start(String methodName) {
threadLocal.get().push(new CapturedTransaction(methodName));
}
public static void end() {
CapturedTransaction snapshot = threadLocal.get().pop();
long elapsedTime = System.currentTimeMillis() - snapshot.startTime;
System.out.println(snapshot.methodName + " >>> " + elapsedTime);
}

}



A.java

package org.jboss.jam.plugin.profiler.test;

import org.jboss.jam.plugin.profiler.CapturedTransaction;

public class A {
public static void main(String [] args) {
CapturedTransaction.start("A.main");
B b = new B();
b.start();
System.out.println("A : " + Thread.currentThread().getName());
CapturedTransaction.end();
}
}


B.java

package org.jboss.jam.plugin.profiler.test;

import org.jboss.jam.plugin.profiler.CapturedTransaction;

public class B extends Thread{
public void run() {
CapturedTransaction.start("B.business");
C c = new C();
System.out.println("Hello B");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
c.business();
System.out.println("B : " + Thread.currentThread().getName());
CapturedTransaction.end();
}
}


package org.jboss.jam.plugin.profiler.test;

import org.jboss.jam.plugin.profiler.CapturedTransaction;

public class C {

public void business() {
CapturedTransaction.start("C.business()");
System.out.println("Hello C");
System.out.println("C : " + Thread.currentThread().getName());
CapturedTransaction.end();
}

}


크리에이티브 커먼즈 라이센스
Creative Commons License
2010/02/19 13:09 2010/02/19 13:09