To explore the core underlying JDK source code, you must master native usage. This article will take “get the default time zone of the system” as an example to introduce how to view the source code of native corresponding methods.

This article is shared from Huawei cloud community “to explore the core underlying JDK source code, it must master native usage”, by Xiao Xu Zhu.

1, scene

If you are interested in exploring, you will be like me. At the end of reading JDK source code, there will be a native method, similar to the following method

/**
     * Gets the platform defined TimeZone ID.
     **/
    private static native String getSystemTimeZoneID(String javaHome);
Copy the code

If you see this native, you’ve got the core. At this point, it’s still not clear how to get the default time zone for your system.

Download the OpenJDK from gitee.com/mirrors/ope…

2. What is native

Native is a computer function, and a native Method is a Java interface that calls non-Java code. Methods are implemented in non-Java languages, such as C or C++.

3. What about native source code

Take ** Private Static Native String getSystemTimeZoneID(StringjavaHome)** as an example

The package java.util.TimeZone where the getSystemTimeZoneID method resides;Copy the code

Find the getSystemTimeZoneID method under timezone.c, as shown in the figure

/* * Gets the platform defined TimeZone ID */ JNIEXPORT jstring JNICALL Java_java_util_TimeZone_getSystemTimeZoneID(JNIEnv *env, jclass ign, jstring java_home, jstring country) { const char *cname; const char *java_home_dir; char *javaTZ; if (java_home == NULL) return NULL; java_home_dir = JNU_GetStringPlatformChars(env, java_home, 0); if (java_home_dir == NULL) return NULL; if (country ! = NULL) { cname = JNU_GetStringPlatformChars(env, country, 0); /* ignore error cases for cname */ } else { cname = NULL; } /* * Invoke platform dependent mapping function */ javaTZ = findJavaTZ_md(java_home_dir, cname); free((void *)java_home_dir); if (cname ! = NULL) { free((void *)cname); } if (javaTZ ! = NULL) { jstring jstrJavaTZ = JNU_NewStringPlatform(env, javaTZ); free((void *)javaTZ); return jstrJavaTZ; } return NULL; }Copy the code

Important: Call different platform-specific mapping functions

 /*
     * Invoke platform dependent mapping function
     */
    javaTZ = findJavaTZ_md(java_home_dir, cname);
Copy the code

The findJavaTZ_md method exists in both solaris and Windows directories.

Check the difference between the two directories:

Because the OpenJDK, the Java standard library and some of the tools source repo (JDK directory), BSD and Linux platform related source is in the Solaris directory. In the original Sun JDK source code, the platform-related directories start from solaris and Windows. Later, all Unix platform-related code is placed in solaris directory, sharing most of the code.

Author: RednaxelaFX

Link: www.zhihu.com/question/58…

Source: Zhihu

The simple understanding is:

On Windows, use the JDK code compiled in the Windows directory

On Unix platforms, JDK code compiled in solaris directories is used

4. Understand the findJavaTZ_md method execution in different systems

4.1 Windows

/* * Detects the platform time zone which maps to a Java time zone ID. */ char *findJavaTZ_md(const char *java_home_dir,  const char *country) { char winZoneName[MAX_ZONE_CHAR]; char winMapID[MAX_MAPID_LENGTH]; char *std_timezone = NULL; int result; winMapID[0] = 0; result = getWinTimeZone(winZoneName, winMapID); if (result ! = VALUE_UNKNOWN) { if (result == VALUE_GMTOFFSET) { std_timezone = _strdup(winZoneName); } else { std_timezone = matchJavaTZ(java_home_dir, result, winZoneName, winMapID, country); } } return std_timezone; }Copy the code

The comment is clearly written to get the current Time zone in the “Time Zones” registry

/*
 * Gets the current time zone entry in the "Time Zones" registry.
 */
static int getWinTimeZone(char *winZoneName, char *winMapID)
{
...
}
Copy the code

Setting the time zone:

Where is the value of the select value on the range taken from, as stated above, is in the registry

Open the registry: Regedit — >

Computer \HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\Copy the code

4.2 Unix Platform

The findJavaTz_md() method comments make it clear: map the platform time zone ID to the Java time zone ID

/* * findJavaTZ_md() maps platform time zone ID to Java time zone ID * using <java_home>/lib/tzmappings. If the TZ value  is not found, it * trys some libc implementation dependent mappings. If it still * can't map to a Java time zone ID, it falls back to the GMT+/-hh:mm * form. `country', which can be null, is not used for UNIX platforms. */ /*ARGSUSED1*/ char * findJavaTZ_md(const char *java_home_dir, const char *country) { char *tz; char *javatz = NULL; char *freetz = NULL; tz = getenv("TZ"); #ifdef __linux__ if (tz == NULL) { #else #ifdef __solaris__ if (tz == NULL || *tz == '\0') { #endif #endif tz = getPlatformTimeZoneID(); freetz = tz; } /* * Remove any preceding ':' */ if (tz ! = NULL && *tz == ':') { tz++; } #ifdef __solaris__ if (strcmp(tz, "localtime") == 0) { tz = getSolarisDefaultZoneID(); freetz = tz; } #endif if (tz ! = NULL) { #ifdef __linux__ /* * Ignore "posix/" prefix. */ if (strncmp(tz, "posix/", 6) == 0) { tz += 6; } #endif javatz = strdup(tz); if (freetz ! = NULL) { free((void *) freetz); } } return javatz; }Copy the code

Steps:

< Java home>/lib/tzmappings. If the “TZ” variable is not found, proceed to step 2

Tz = getPlatformTimeZoneID(); Perform a Linux-specific mapping, returning a time zone ID if found, null otherwise

【Linux】Centos7 change the system timezone.

timedatectl
Copy the code

Modify the time zone

timedatectl  set-timezone Asia/Shanghai
Copy the code

3, compare /etc/localtime with “/usr/share/zoneinfo “files, if the same, return the time zone ID, if not, go to step 4

4. Return to GMT

Click to follow, the first time to learn about Huawei cloud fresh technology ~