为了测试日期/时间设置为过去或将来的java代码,我想尝试libfaketime(目前我们只是调整系统时钟,但它会带来很多麻烦,比如不工作的kerberos等等)。
我尝试这个小测试程序:
$ 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[root@myhost ~]#
但正如你所见,我只是收到一条错误信息。
测试在RHEL6.5服务器内核2.6.32-431和
libfaketime 0.9.6版
你对我如何解决这个问题有什么建议吗?我还想听听你在RHEL上使用libfaketime和Java的经验。
我也在:https://github.com/wolfcw/libfaketime/issues
最好的收割者,
埃尔林
最佳答案
我在ibm jvm 1.7.0中也观察到了这种不正确的行为,而在oraclejvm1.6.0中,这种行为可以按预期工作。
解释是,ibm jvm显然有一个内部bug,它通过使用错误的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
这将阻止LyFabKeTime.所以,1库从现有的错误中你正在观察
printf("\nInvalid clock_id for clock_gettime: %d", clk_id);
exit(EXIT_FAILURE);
请注意,此解决方案有一个缺点,即如果jvm错误地向系统请求无效的clockid,我们将假定有效的clockid,这可能不是应用程序所期望的。
关于java - RHEL 5/RHEL 6上的libfaketime和Java,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26602617/