java.lang.System.currentTimeMillis()替换方法
除了重新编译之外,rt.jar
还有什么方法可以用currentTimeMillis()
我自己的一个替换调用?
我知道,但是我们将运行由大量尚未实现Clock
或自己实现的开发人员开发的代码。
即使仅在禁用Hotspot的情况下有效,-Xint
并且使用下面的代码也成功,但它不会“持久化”在外部库上。这意味着您必须在所有地方都进行模拟,因为代码不受我们的控制,因此这是不可行的。下的所有代码main()
的确返回0毫秒(如示例所示),但是a
new DateTime()
将返回实际的系统毫秒数。
@MockClass(realClass = System.class) public class SystemMock extends MockUp<System> {
// returns 1970-01-01
@Mock public static long currentTimeMillis() { return 0; }
}
(已编辑)
在可能的情况下,尽管您可以创建/更改方法,但有问题的方法声明为public static native long
currentTimeMillis();。您必须先深入研究Sun的专有和
代码,才能更改其声明,这将使之成为逆向工程,而且几乎不是一种稳定的方法。所有最近的SUN JVM崩溃,并出现以下错误:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000, pid=4668, tid=5736
(评论中建议的新测试)
尽管使用-Djava.system.class.loader
JVM轻松替换系统CL的过程实际上是通过默认的classLoader加载了自定义classLoader,并且系统甚至没有通过自定义CL。
public class SimpleClassLoader extends ClassLoader { public SimpleClassLoader(ClassLoader classLoader) {
super(classLoader);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return super.loadClass(name);
}
}
我们可以看到,java.lang.System
从装载rt.jar
使用java -verbose:class
Line 15: [Loaded java.lang.System from C:\jdk1.7.0_25\jre\lib\rt.jar]
我没有其他选择了。
回答:
您可以使用AspectJ编译器/编织器来编译/编织有问题的用户代码,将对java.lang.System.currentTimeMillis()的调用替换为您自己的代码。以下方面将做到这一点:
public aspect CurrentTimeInMillisMethodCallChanger { long around():
call(public static native long java.lang.System.currentTimeMillis())
&& within(user.code.base.pckg.*) {
return 0; //provide your own implementation returning a long
}
}
以上是 java.lang.System.currentTimeMillis()替换方法 的全部内容, 来源链接: utcz.com/qa/406760.html