ITコンサルの日常

ITコンサル会社に勤務する普通のITエンジニアの日常です。

GluonJでjava.util.Date#getTimeをインターセプトしてみる。(うまくいかず)

http://www.csg.is.titech.ac.jp/projects/gluonj/downloads/index.html
辺りから落としてきました。ver1.5 betaです。

まずはチュートリアルを参考にやってみる。

>more src\test\Hello.java
package test;

public class Hello
{
        public static void main(String[] args)
        {
                hello();
        }

        public static void hello()
        {
                System.out.println("hello");
        }
}
>more src\test\Mock.java
package test;

import javassist.gluonj.*;
import test.*;

@Glue public class Mock
{
        @Refine static class Hello extends test.Hello
        {
                public static void hello()
                {
                        System.out.println("hello call start.");

                        test.Hello.hello();

                        System.out.println("hello call end.");
                }
        }
}
>javac -s src -d classes -cp gluonj.jar src\test\*.java

>java -javaagent:gluonj.jar=test.Mock -cp gluonj.jar;classes test.H
ello
hello call start.
hello
hello call end.

>


インターセプターっていうか、なんでも出来る感じですね。
元の実装はいじりませんし、javaの実行オプションをいじるだけです。とてもいい感じです。


で、java.util.Date#getTimeにチャレンジしてみる。

>more src\test2\test.java
package test2;

import java.util.Date;

public class test
{
        public static void main(String[] args)
        {
                Date dt = new Date();
                System.out.println(dt.getTime());
        }
}
>more src\test2\Mock.java
package test2;

import java.util.Date;

import javassist.gluonj.*;

@Glue public class Mock
{
        @Refine static class Date extends java.util.Date
        {
                public long getTime()
                {
                        System.out.println("hello call start.");

                        long result = super.getTime();

                        System.out.println("hello call end.");

                        return result;
                }
        }
}
>javac -s src -d classes -cp gluonj.jar src\test2\*.java

>java -javaagent:gluonj.jar=test2.Mock -cp gluonj.jar;classes test2
.test
1206282305328

>


うーん。残念ながらうまくいかず。
GluonJのドキュメントは、チュートリアルとソースしかないので、ちと厳しいなあ。
ソースをさらっと追った感じでは、
javassist.gluonj.weave.Weaver#isNonTransformable
で、コメントに

/**
* Returns true if the given class name represents a system class.
* Note that JVM does not accept transformed system classes.
*/

とあり、クラス名が以下で始まるものは変換不可としているためのようです(多分)

  • java.
  • javax.
  • com.sun.
  • sun.
  • sunw.

ちなみに、premainで

System.out.println("isModifiableClass(java.util.Date) = " + inst.isModifiableClass(java.util.Date.class));

とかすると、trueとか帰ってくるんですけど、ライセンス上の問題とかなんでしょうかね。良く分かりません。。