Skip to content

[Bug] [dolphinscheduler-common] JSONUtils tool class time zone problem reporting error #10282

@106umao

Description

@106umao

Search before asking

  • I had searched in the issues and found no similar issues.

What happened

report error in mvn test,but not occur error when use Junit to run JSONUtilsTets.java file。

    @Test
    public void dateToString() {
        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
        String time = "2022-02-22 13:38:24";
        Date date = DateUtils.stringToDate(time);
        String json = JSONUtils.toJsonString(date);
        Assert.assertEquals(json, "\"" + time + "\"");

        String errorFormatTime = "Tue Feb 22 03:50:00 UTC 2022";
        Assert.assertNull(DateUtils.stringToDate(errorFormatTime));
    }

    @Test
    public void stringToDate() {
        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
        String json = "\"2022-02-22 13:38:24\"";
        Date date = JSONUtils.parseObject(json, Date.class);
        Assert.assertEquals(date, DateUtils.stringToDate("2022-02-22 13:38:24"));
    }

The dateToString and stringToDate methods get the following errors when running mvn test

[ERROR] Tests run: 19, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 0.118 s <<< FAILURE! - in org.apache.dolphinscheduler.common.utils.JSONUtilsTest
Tests run: 19, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 0.118 s <<< FAILURE! - in org.apache.dolphinscheduler.common.utils.JSONUtilsTest
stringToDate(org.apache.dolphinscheduler.common.utils.JSONUtilsTest)  Time elapsed: 0.014 s  <<< FAILURE!

java.lang.AssertionError: expected:<Tue Feb 22 21:38:24 CST 2022> but was:<Tue Feb 22 13:38:24 CST 2022>
	at org.apache.dolphinscheduler.common.utils.JSONUtilsTest.stringToDate(JSONUtilsTest.java:280)
[ERROR] dateToString(org.apache.dolphinscheduler.common.utils.JSONUtilsTest)  Time elapsed: 0.003 s  <<< FAILURE!
dateToString(org.apache.dolphinscheduler.common.utils.JSONUtilsTest)  Time elapsed: 0.003 s  <<< FAILURE!


org.junit.ComparisonFailure: expected:<"2022-02-22 [05]:38:24"> but was:<"2022-02-22 [13]:38:24">
	at org.apache.dolphinscheduler.common.utils.JSONUtilsTest.dateToString(JSONUtilsTest.java:269)

What you expected to happen

use case passed

How to reproduce

OS Version : Any
JDK Versin : Oracle JDK11
Run mvn test -e in the terminal or press the button in IDEA

Anything else

I wrote a demo to show how to reproduce it easily without waiting a long time for mvn test to run. I will analyze why this problem occurs and submit a pull request.

import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.common.utils.JSONUtilsTest;
import java.util.TimeZone;
public class TimeZoneTest {
    public static void main(String[] args) {
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
        JSONUtils.createArrayNode();// This step is to load class and initialize JSONUtils's static code block
        new JSONUtilsTest().stringToDate();
        new JSONUtilsTest().dateToString();
    }
}

image
image
image

The above one gives my demo and some source code screenshots. The reason for the bug is among them:

  • when using junit to execute use cases, each use case is isolated, and the JSONUtils class will not be shared among multiple use cases. In this case, TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai")) will not fail.Because the JSONUtils class is reinitialized once per use case

  • In the case of using mvn test, which is described in my demo, when the default time zone of the TimeZone class is set in other places through TimeZone.setDefault, the initialization of JSONUtils is carried out. At this time, JSONUtils final and static descriptors are modified parts The default time zone information in TimeZone will be loaded, and setting the TimeZone time zone via TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai")) in the future will not have any effect on JSONUtils.

上面个给出了我的demo和部分源码截图,bug出现的原因就在其中:

  • 当使用junit执行用例时,每个用例都是隔离的,此时多个用例之间不会共享JSONUtils类,这种情况下就不会出现TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"))失效。因为每个用例都会重新初始化一次JSONUtils类
  • 而在使用mvn test的情况中,也就是我demo中描述的那样,当在其他地方通过TimeZone.setDefault设置过TimeZone类默认时区后再进行JSONUtils的初始化,此时JSONUtils final 和static描述符修饰的部分就会加载TimeZone中默认的时区信息,而在以后再通过TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"))设置TimeZone时区并不会对JSONUtils产生任何影响。

Version

dev

Are you willing to submit PR?

Code of Conduct

Metadata

Metadata

Assignees

Labels

backendbugSomething isn't working

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions