gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 16:46:13 32 4
gpt4 key购买 nike

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

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

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

<小时/>

2# 使用 JMockit 等模拟工具来模拟该类。

尽管这仅适用于禁用 Hotspot 的 -Xint 并且我们成功使用了下面的代码,但它不会“持久”在外部库上。这意味着您必须在任何地方模拟它,因为代码不在我们的控制范围内,这是不可行的。 main() 下的所有代码确实返回 0 milis(如示例所示),但 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 的专有和 native 代码,您就无法更改它的声明,这将使其成为逆向工程的练习,而且很难成为一种稳定的方法。所有最近的 SUN JVM 崩溃都出现以下错误:

    EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000, pid=4668, tid=5736  
<小时/>

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

虽然使用 -Djava.system.class.loader 替换系统 CL 很简单,但 JVM 实际上会借助默认的 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 是使用 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/61773371/

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