java.lang.System.currentTimeMillis()替换方法 [英] java.lang.System.currentTimeMillis() replace method

查看:1749
本文介绍了java.lang.System.currentTimeMillis()替换方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

除了重新编译 rt.jar 有什么方法可以用其中一个替换 currentTimeMillis()调用我自己的?

Aside from recompiling rt.jar is there any way I can replace the currentTimeMillis() call with one of my own?

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

1# The right way to do it is use a Clock object and abstract time.

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

I know it but we'll be running code developed by an endless number of developers that have not implemented Clock or have made an implementation of their own.

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

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

Even though that only works with Hotspot disabled -Xint and we have success using the code bellow it does not "persist" on external libraries. Meaning that you'd have to Mock it everywhere which, as the code is out of our control, is not feasible. All code under main() does return 0 milis (as from the example) but a new DateTime() will return the actual system millis.

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






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


3# Re-declare System on start up by using -Xbootclasspath/p (edited)

尽管可能,虽然您可以创建/更改方法,但有问题的方法被声明为 public static native long currentTimeMillis(); 。如果不深入研究Sun的专有和原生代码,你就无法改变它的声明,这将使这成为逆向工程和不稳定的方法。
所有最近的SUN JVM崩溃时出现以下错误:

While possible, and though you can create/alter methods, the one in question is declared as public static native long currentTimeMillis();. You cannot change it's declaration without digging into Sun's proprietary and native code which would make this an exercise of reverse engineering and hardly a stable approach. All recent SUN JVM crash with the following error:

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






4#使用自定义ClassLoader (评论中建议的新测试)


4# Use a custom ClassLoader (new test as suggested on the comments)

尽管使用 -Djava.system替换系统CL是微不足道的。 class.loader JVM实际上加载了使用默认classLoader的自定义classLoader,甚至没有通过自定义CL推送System。

While trivial to replace the system CL using -Djava.system.class.loader JVM actually loads up the custom classLoader resorting to the default classLoader and System is not even pushed trough the custom 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:class <从 rt.jar 加载/ p>

We can see that java.lang.System is loaded from rt.jar using java -verbose:class

Line 15: [Loaded java.lang.System from C:\jdk1.7.0_25\jre\lib\rt.jar]






我用完了选项。

我缺少一些方法吗?

推荐答案

您可以使用AspectJ编译器/ weaver来编译/编织有问题的用户代码,用您自己的代码替换对java.lang.System.currentTimeMillis()的调用。以下方面只会这样做:

You could use an AspectJ compiler/weaver to compile/weave the problematic user code, replacing the calls to java.lang.System.currentTimeMillis() with your own code. The following aspect will just do that:

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()替换方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆