現在時刻を偽装するJava Agent

作ってみたはいいが、実行するとJDK/JREの使用許諾に違反するようです。
現時点では著作権は放棄していませんしライセンスは未整理です。
javassist に依存しています。

作ってみたはいいが、実行するとJDK/JREの使用許諾に違反するようです。
現時点では著作権は放棄していませんしライセンスは未整理です。
javassist に依存しています。

  • タグ:
  • タグはありません
package org.ocharake.matobaa.utlib;
import java.io.ByteArrayInputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
import java.util.Calendar;
import java.util.Date;
import javassist.ClassPool;
import javassist.CtBehavior;
import javassist.CtClass;
public class NowDateMockAgent {
/**
* An entry point for insert NowDateMockAgent functionality to
* java.util.Date and java.util.GregorianCalendar.
*
* This method will be invoked before enter the main mathod with VM's
* runtime argument as follows: -javaagent:nowdateagent.jar
*
* @param agentArgs
* ignored. don't care.
* @param instrumentation
* ignored. don't care.
*/
public static void premain(String agentArgs, Instrumentation instrumentation) {
instrumentation.addTransformer(new DateTransformer());
}
private static final class DateTransformer implements ClassFileTransformer {
static String expected = "Long.parseLong(System.getProperty(\""
+ NowDateMockAgent.class.getCanonicalName() + "\"));";
public byte[] transform(ClassLoader loader, String className,
Class<?> void1, ProtectionDomain void2, byte[] classfileBuffer)
throws IllegalClassFormatException {
try {
// insert "time=0" at end of
// GregorianCalengar.<init>(TimeZone,Locale)
if (className.equals("java/util/GregorianCalendar")) {
ClassPool pool = ClassPool.getDefault();
ByteArrayInputStream stream = new ByteArrayInputStream(
classfileBuffer);
CtClass targetType = pool.makeClass(stream);
CtClass[] paramTypes = pool.get(new String[] {
"java/util/TimeZone", "java/util/Locale" });
CtBehavior constructor = targetType
.getDeclaredConstructor(paramTypes);
constructor.insertAfter("time = " + expected);
return targetType.toBytecode();
}
// insert "fastTime=0" at end of java.util.Date.<init>()
if (className.equals("java/util/Date")) {
ClassPool pool = ClassPool.getDefault();
ByteArrayInputStream stream = new ByteArrayInputStream(
classfileBuffer);
CtClass targetType = pool.makeClass(stream);
targetType.getDeclaredConstructor(new CtClass[0])
.insertAfter("fastTime = " + expected);
return targetType.toBytecode();
}
} catch (Exception initCause) {
IllegalClassFormatException e = new IllegalClassFormatException();
e.initCause(initCause);
throw e;
}
return null;
}
}
static {
System.setProperty(NowDateMockAgent.class.getCanonicalName(), "0");
}
/**
* Set the date value you expected.
*
* @param dateExpected
* expected date as long
*/
public static void setExpected(long dateExpected) {
System.setProperty(NowDateMockAgent.class.getCanonicalName(),
Long.toString(dateExpected));
}
/**
* Set the date value you expected
*
* @param dateExpected
* expected date as java.util.Date
*/
public static void setExpected(Date dateExpected) {
setExpected(dateExpected.getTime());
}
/**
* Set the date value you expected
*
* @param dateExpected
* expected date as java.util.Calendar
*/
public static void setExpected(Calendar dateExpected) {
setExpected(dateExpected.getTime().getTime());
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX