2014-10-28 137 views
1

爲了測試設置爲過去或未來日期/時間的java代碼,我想嘗試libfaketime(目前我們只是調整系統時鐘,但它會導致非常麻煩,如非工作Kerberos等)。RHEL 5/RHEL 6上的libfaketime和java

我嘗試用這個小測試程序:

$ cat time.java 
import java.util.*; 

class TimeTest { 

    public static void main(String[] s) { 

     long timeInMillis = System.currentTimeMillis(); 
     Calendar cal = Calendar.getInstance(); 
     cal.setTimeInMillis(timeInMillis); 
     java.util.Date date = cal.getTime(); 

     System.out.println("Date: " + date); 
    } 
} 

並執行這樣的:

LD_ASSUME_KERNEL=2.6.18 LD_PRELOAD=/usr/lib64/libfaketime.so.1 FAKETIME="-15d" /opt/IBM/WebSphere/AppServer/java_1.7_64/bin/java TimeTest 
Invalid clock_id for clock_gettime: -172402[[email protected] ~]# 

但你可以看到我剛剛得到一個錯誤信息。 該測試在RHEL 6.5服務器上執行,內核爲2.6.32-431和 libfaketime 0.9.6

您有什麼建議可以解決這個問題嗎?我也有興趣聽到您在RHEL上使用libfaketime和java的經驗。

我也報告這個問題在:https://github.com/wolfcw/libfaketime/issues

最佳reagards,

的Erling

回答

0

我已經觀察到了這種不正確的行爲,以及在IBM JVM 1.7.0,而在甲骨文JVM 1.6。 0按預期工作。 解釋是IBM JVM有一個內部錯誤,通過調用帶有錯誤的clock_id參數(隨機負值)的系統調用clock_gettime來體現。 解決方法(不是修復)是修改libfaketime.c將clock_id重置爲fake_clock_gettime函數中的有效值。

case FT_START_AT: /* User-specified offset */ 
    if (user_per_tick_inc_set) 
    { 
    /* increment time with every time() call*/ 
    next_time(tp, &user_per_tick_inc); 
    } 
    else 
    { 
    if (clk_id < 0) { // jvm calls clock_gettime() with invalid random negative clock_id value 
     clk_id = CLOCK_REALTIME; 
    } 

    switch (clk_id) 
    // the rest is the same 

這將防止libfaketime.so.1庫從現有的錯誤,您正在觀察

printf("\nInvalid clock_id for clock_gettime: %d", clk_id); 
exit(EXIT_FAILURE); 

請注意,這種解決方法的缺點是在JVM的情況下錯誤地要求系統無效clockid爲我們將假定有效的clockid,這可能不是應用程序所期望的。