gpt4 book ai didi

java.lang.System.currentTimeMillis() 替换方法

转载 作者:太空狗 更新时间:2023-10-29 22:57:25 27 4
gpt4 key购买 nike

除了重新编译 rt.jar 之外,还有什么方法可以用我自己的调用替换 currentTimeMillis() 调用吗?

1# 正确的做法是使用时钟对象和抽象时间。

我知道,但我们将运行由无数开发人员开发的代码,这些开发人员尚未实现 Clock 或已经实现了他们自己的实现。


2# 使用像 JMockit 这样的模拟工具来模拟该类。

即使这只适用于 Hotspot 禁用 -Xint 并且我们成功使用下面的代码它不会“持久”在外部库上。这意味着你必须在任何地方模拟它,因为代码不在我们的控制范围内,这是不可行的。 main() 下的所有代码确实返回 0 毫秒(如示例所示),但 new DateTime() 将返回实际的系统毫秒。

    @MockClass(realClass = System.class)
public class SystemMock extends MockUp<System> {
// returns 1970-01-01
@Mock public static long currentTimeMillis() { return 0; }
}

3# 在启动时使用 -Xbootclasspath/p 重新声明 System(已编辑)

虽然可能,并且尽管您可以创建/更改方法,但所讨论的方法被声明为 public static native long currentTimeMillis();。如果不深入研究 Sun 的专有代码和本地 代码,您就无法更改它的声明,这会使它成为一种逆向工程练习,很难成为一种稳定的方法。所有最近的 SUN JVM 崩溃并出现以下错误:

    EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000, pid=4668, tid=5736  

4# 使用自定义类加载器(评论中建议的新测试)

虽然使用 -Djava.system.class.loader 替换系统 CL 是微不足道的,但 JVM 实际上加载自定义 classLoader 求助于默认的 classLoader 并且 System 甚至不会通过自定义 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 是使用 java -verbose:classrt.jar 加载的

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() 替换方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18239859/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com