A long time ago, I wanted to compile the source code of java on windows, and recently I have been trying, and I have tried many methods and encountered many problems.

Finally, I compile the process of difficulties and solutions encountered in the record, I hope to help those who come later.

Download source code

The source code of Openjdk 11 is stored on the URL https://hg.openjdk.java.net/jdk-updates/jdk11u/ and can be downloaded by clicking on the zip button on the left to download the source code zip file at the following address: https://hg.openjdk.java.net /jdk-updates/jdk11u/archive/tip.zip

After downloading, the size is 189M, after unzipping, the size is 600M.

Compiling and running

There are 2 optional tools for compiling openJdk source code, one using Cygwin and the other using WSL.

I recommend using WSL, but using Cygwin is also described in the article, if anyone needs it.

Note: Only one of WSL and Cygwin needs to be installed

Compiling with WSL

Installing WSL

First install WSL, see the official Microsoft documentation: Installing WSL on Windows 10 | Microsoft Docs for a detailed installation tutorial.

It is recommended to install Ubuntu 20.04 LTS for this version.

Software needed for installation

1
2
3
sudo su
apt update && apt upgrade
sudo apt install mercurial zip unzip make gcc g++ build-essential ccache libx11-dev libxext-dev libxrender-dev  libxrandr-dev libxtst-dev libxt-dev libcups2-dev libfreetype6-dev libasound2-dev libfontconfig1-dev ccache cmake gdb autoconf

Installing Java

To compile Java, you need N-1 version of Java. e.g. to compile Java 11 you need at least Java 10 and later installed on your computer.

1
sudo apt install openjdk-11-jdk

Compiling OpenJdk

1
2
chmod +x configure
./configure --with-debug-level=slowdebug --with-native-debug-symbols=internal --disable-warnings-as-errors --enable-ccache

To compile after the configuration is complete.

1
make all

Testing Java

To test that the compiled result works properly.

1
2
3
4
ubuntu@zhang:~/jdk11u-113c646a33d2$ ./build/linux-x86_64-normal-server-slowdebug/jdk/bin/java -version
openjdk version "11.0.12-internal" 2021-07-20
OpenJDK Runtime Environment (slowdebug build 11.0.12-internal+0-adhoc.ubuntu.jdk11u-113c646a33d2)
OpenJDK 64-Bit Server VM (slowdebug build 11.0.12-internal+0-adhoc.ubuntu.jdk11u-113c646a33d2, mixed mode)

Create a new Java file named hello.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import java.util.concurrent.ThreadLocalRandom;

public class hello {

    private static final int REPETITIONS = 100_000_000;

    public static void main(String[] args) throws InterruptedException {
        System.out.println("Hello World");
        for (var i = 0; i < REPETITIONS; i++) {
            Thread.sleep(1000);
            System.out.println("i is:" + i + ", current time is:" + System.currentTimeMillis() + ", random is:" + ThreadLocalRandom.current().nextLong());
        }
    }
}

Run the Java file.

1
2
ubuntu@zhang:~/jdk11u-113c646a33d2$ ./build/linux-x86_64-normal-server-slowdebug/jdk/bin/java hello.java
Hello World

Debugging Java is in the next section.

Using Cygwin with Visual Studio for compilation

Installing Cygwin

The compilation of openJdk requires the installation of Cygwin as the GNU environment, MSYS2 is not recommended.

Download: setup-x86_64.exe

Run the command to install the required components.

1
.\setup-x86_64.exe  -q -P autoconf -P make -P unzip -P zip -P gdb

Installing Visual Studio

The gcc version on windows requires the c++ compiler in vs to be selected.

To install Visual Studio 2019 Community version, select the component Desktop Development with C++ for the tools component.

Caution.

  1. installation directory, do not have spaces, otherwise you have to use fsutil for short path conversion, see error resolution for details.
  2. For the old version of openJdk source code, choose English for the language package, not Chinese, otherwise the compilation will fail. Now the new version of OpenJdk source code has solved this problem.
  3. When installing, in the right column of Desktop Development with C++, check the box to install MSVC v141-VS 2017 C++. openJdk 11 only supports VS 2017 version of c++, OpenJdk 15 source code is compiled to support VS 2019.

Installing Java

To compile Java, you need N-1 version of Java. e.g. to compile Java 11 you need to have at least Java 10 and later installed on your computer.

Download link: AdoptOpenJDK - Open source, prebuilt OpenJDK binaries

Select OpenJdk 11 version and JVM HotSpot.

Download and install, make sure the installation is successful.

1
2
3
4
$ java.exe -version
openjdk version "11.0.9.1" 2020-11-04
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.9.1+1)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.9.1+1, mixed mode)

Compile OpenJdk

Use Cygwin64 Terminal to switch to the source directory and execute the configure script, if it goes well no error will be reported.

You need to specify the installation directory of VS.

1
2
cd /cygdrive/d/jdk11u-113c646a33d2
./configure --with-debug-level=slowdebug --with-native-debug-symbols=external --disable-warnings-as-errors --with-tools-dir=/cygdrive/c/VS/VC/Auxiliary

Warning: If the VS/Windows Kits directory has spaces, then you need to use fsutil for short path conversion, see error resolution for details

To compile.

1
make all

When compiling, if you encounter errors, you can look at the problems in the error resolution at the bottom of the article.

If it goes smoothly, the compilation will be finished in about one hour. The folder size is 4G after completion.

Testing Java

To test if the compiled result works properly.

1
2
3
4
$ ./build/windows-x86_64-normal-server-slowdebug/images/jdk/bin/java -version
openjdk version "11.0.12-internal" 2021-07-20
OpenJDK Runtime Environment (slowdebug build 11.0.12-internal+0-adhoc.zhang.jdk11u-113c646a33d2)
OpenJDK 64-Bit Server VM (slowdebug build 11.0.12-internal+0-adhoc.zhang.jdk11u-113c646a33d2, mixed mode)

Create a new Java file named hello.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import java.util.concurrent.ThreadLocalRandom;

public class hello {

    private static final int REPETITIONS = 100_000_000;

    public static void main(String[] args) throws InterruptedException {
        System.out.println("Hello World");
        for (var i = 0; i < REPETITIONS; i++) {
            Thread.sleep(1000);
            System.out.println("i is:" + i + ", current time is:" + System.currentTimeMillis() + ", random is:" + ThreadLocalRandom.current().nextLong());
        }
    }
}

Run the Java file.

1
2
$ ./build/windows-x86_64-normal-server-slowdebug/images/jdk/bin/java hello.java
Hello World

Debugging Java

The following is an example of debugging the WSL version of Java.

  1. Run the Java program.

    1
    2
    
    ubuntu@zhang:~/jdk11u-113c646a33d2$ ./build/linux-x86_64-normal-server-slowdebug/jdk/bin/java hello.java
    Hello World
    
  2. Find the PID of the Java program.

    1
    2
    3
    
    ubuntu@zhang:~$ jps
    12257 Main
    12302 Jps
    
  3. Use gdb to connect to the program.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    
    ubuntu@zhang:~$ gdb -p 12257
    GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
    Copyright (C) 2020 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    Type "show copying" and "show warranty" for details.
    This GDB was configured as "x86_64-linux-gnu".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
        <http://www.gnu.org/software/gdb/documentation/>.
    
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    Attaching to process 12339
    [New LWP 12340]
    [New LWP 12341]
    [New LWP 12342]
    [New LWP 12343]
    [New LWP 12344]
    [New LWP 12345]
    [New LWP 12346]
    [New LWP 12347]
    [New LWP 12348]
    [New LWP 12349]
    [New LWP 12350]
    [New LWP 12351]
    [New LWP 12352]
    [New LWP 12353]
    [New LWP 12354]
    [New LWP 12357]
    [New LWP 12360]
    [New LWP 12361]
    [New LWP 12362]
    [New LWP 12363]
    [New LWP 12364]
    [New LWP 12365]
    [New LWP 12366]
    [New LWP 12367]
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    __pthread_clockjoin_ex (threadid=140260516488960, thread_return=0x7ffcefea4328, clockid=<optimized out>,
        abstime=<optimized out>, block=<optimized out>) at pthread_join_common.c:145
    145     pthread_join_common.c: No such file or directory.
    

Add a breakpoint, here I choose the source code implementation of main

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
(gdb) list JavaMain
388         } while (JNI_FALSE)
389
390
391     int
392     JavaMain(void* _args)
393     {
394         JavaMainArgs *args = (JavaMainArgs *)_args;
395         int argc = args->argc;
396         char **argv = args->argv;
397         int mode = args->mode;
(gdb) break JavaMain
Breakpoint 1 at 0x7f845ebe341d: file ../src/java.base/share/native/libjli/java.c, line 393.

Run the program.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/ubuntu/jdk11u-113c646a33d2/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff5c27700 (LWP 249)]
[Switching to Thread 0x7ffff5c27700 (LWP 249)]

Thread 2 "java" hit Breakpoint 1, JavaMain (_args=0x0) at ../src/java.base/share/native/libjli/java.c:393
393     {
(gdb) n
394         JavaMainArgs *args = (JavaMainArgs *)_args;
(gdb) n
395         int argc = args->argc;
(gdb) n
396         char **argv = args->argv;
(gdb) print *args
$1 = {argc = 0, argv = 0x5555555595a8, mode = 0, what = 0x0, ifn = {CreateJavaVM = 0x7ffff6a5a36b <JNI_CreateJavaVM(JavaVM**, void**, void*)>,
    GetDefaultJavaVMInitArgs = 0x7ffff6a59e91 <JNI_GetDefaultJavaVMInitArgs(void*)>, GetCreatedJavaVMs = 0x7ffff6a5a3a9 <JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*)>}}

As you can see, the breakpoint was successfully hit on the Java initialization code.

The desired method can be debugged later.

Postscript

It took quite a lot of time to write this, mainly in exploring how to solve the various error reports, and ultimately which method is more convenient to debug.

Finally compile debugging is completed, although not directly learned a lot of knowledge, the process of problem solving, but also learned a lot.

Error resolution

ls: cannot access ‘/cygdrive/d/VS2/VC/Redist/MSVC/*/x64/Microsoft.VC141.CRT/msvcp140.dll’: No such file or directory

The following errors were encountered.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
configure: Rewriting CYGWIN_VC_INSTALL_DIR to "/cygdrive/d/VS2/VC"
ls: cannot access '/cygdrive/d/VS2/VC/Redist/MSVC/*/x64/Microsoft.VC141.CRT/vcruntime140.dll': No such file or directory
configure: Found vcruntime140.dll at /cygdrive/c/progra~1/adopto~1/jdk-11~1.101/bin/vcruntime140.dll using well-known location in Boot JDK
checking found vcruntime140.dll architecture... ok
checking for vcruntime140.dll... /cygdrive/c/progra~1/adopto~1/jdk-11~1.101/bin/vcruntime140.dll
configure: Rewriting CYGWIN_VC_INSTALL_DIR to "/cygdrive/d/VS2/VC"
ls: cannot access '/cygdrive/d/VS2/VC/Redist/MSVC/*/x64/Microsoft.VC141.CRT/msvcp140.dll': No such file or directory
configure: Found msvcp140.dll at /cygdrive/c/progra~1/adopto~1/jdk-11~1.101/bin/msvcp140.dll using well-known location in Boot JDK
checking found msvcp140.dll architecture... ok
checking for msvcp140.dll... /cygdrive/c/progra~1/adopto~1/jdk-11~1.101/bin/msvcp140.dll
checking for UCRT DLL dir... configure: Rewriting CYGWIN_WINDOWSSDKDIR to "/cygdrive/d/windows kits/10"
no
configure: error: Could not find any dlls in
configure exiting with result code 1

Solution.

The reason for this problem is that Java 11 compilation does not support VS 2019, this problem is officially fixed in Java 15 compilation: [JDK-8242468] VS2019 build missing vcruntime140_1.dll - Java Bug System

The solution is to use visual studio installer and check the box to install MSVC v141-VS 2017 C++ in the Desktop Development with C++ column on the right.

Once the installation is complete, this error will be gone

configure: error: Could not find any dlls in

The following error was encountered

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
configure: Rewriting CYGWIN_VC_INSTALL_DIR to "/cygdrive/c/VS/VC"
POSSIBLE_MSVC_DLL /cygdrive/c/VS/VC/Redist/MSVC/14.16.27012/x64/Microsoft.VC141.CRT/vcruntime140.dll
configure: Found vcruntime140.dll at /cygdrive/c/VS/VC/Redist/MSVC/14.16.27012/x64/Microsoft.VC141.CRT/vcruntime140.dll using well-known location in VCINSTALLDIR
checking found vcruntime140.dll architecture... ok
checking for vcruntime140.dll... /cygdrive/c/VS/VC/Redist/MSVC/14.16.27012/x64/Microsoft.VC141.CRT/vcruntime140.dll
configure: Rewriting CYGWIN_VC_INSTALL_DIR to "/cygdrive/c/VS/VC"
POSSIBLE_MSVC_DLL /cygdrive/c/VS/VC/Redist/MSVC/14.16.27012/x64/Microsoft.VC141.CRT/msvcp140.dll
configure: Found msvcp140.dll at /cygdrive/c/VS/VC/Redist/MSVC/14.16.27012/x64/Microsoft.VC141.CRT/msvcp140.dll using well-known location in VCINSTALLDIR
checking found msvcp140.dll architecture... ok
checking for msvcp140.dll... /cygdrive/c/VS/VC/Redist/MSVC/14.16.27012/x64/Microsoft.VC141.CRT/msvcp140.dll
checking for UCRT DLL dir... configure: Rewriting CYGWIN_WINDOWSSDKDIR to "/cygdrive/d/windows kits/10"
no
configure: error: Could not find any dlls in
configure exiting with result code 1

The reason for this error is that the win10 sdk directory has spaces in it, the solution is to modify the file make/autoconf/toolchain_windows.m4

Put

1
UCRT_DLL_DIR="`ls -d $CYGWIN_WINDOWSSDKDIR/Redist/*/ucrt/DLLs/$dll_subdir \

Modify to

1
UCRT_DLL_DIR="``ls -d "$CYGWIN_WINDOWSSDKDIR"/Redist/*/ucrt/DLLs/$dll_subdir \

The error is solved after modification.

Using fsutil for short path conversion

Cygwin does not support paths with spaces, so you need to convert paths with spaces to paths without spaces.

For example, the installation path of Windows Kits is D:\Windows Kits, alias Kits2.

Open cmd as administrator, or powershell

1
fsutil file setshortname "D:\Windows Kits" Kits2

After conversion D:\Kits2 is equivalent to D:\Windows Kits

fatal error C1083: Cannot open include file: ‘crtdbg.h’: No such file or directory

The following error was encountered.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
formssel.cpp
c:\VS\VC\Tools\MSVC\14.29.30037\include\yvals.h(12): fatal error C1083: Cannot open include file: 'crtdbg.h': No such file or directory
   ... (rest of output omitted)
* For target hotspot_variant-server_tools_adlc_objs_main.obj:
cl : Command line warning D9024 : unrecognized source file type 'kits/10/include/10.0.19041.0/ucrt', object file assumed
cl : Command line warning D9027 : source file 'kits/10/include/10.0.19041.0/ucrt' ignored
cl : Command line warning D9024 : unrecognized source file type 'kits/10/include/10.0.19041.0/shared', object file assumed
cl : Command line warning D9027 : source file 'kits/10/include/10.0.19041.0/shared' ignored
cl : Command line warning D9024 : unrecognized source file type 'kits/10/include/10.0.19041.0/um', object file assumed
cl : Command line warning D9027 : source file 'kits/10/include/10.0.19041.0/um' ignored
cl : Command line warning D9024 : unrecognized source file type 'kits/10/include/10.0.19041.0/winrt', object file assumed
cl : Command line warning D9027 : source file 'kits/10/include/10.0.19041.0/winrt' ignored
cl : Command line warning D9024 : unrecognized source file type 'kits/10/include/10.0.19041.0/cppwinrt', object file assumed
cl : Command line warning D9027 : source file 'kits/10/include/10.0.19041.0/cppwinrt' ignored
main.cpp
c:\VS\VC\Tools\MSVC\14.29.30037\include\yvals.h(12): fatal error C1083: Cannot open include file: 'crtdbg.h': No such file or directory
   ... (rest of output omitted)

* All command lines available in /cygdrive/d/jdk11u-113c646a33d2/build/windows-x86_64-normal-server-slowdebug/make-support/failure-logs.
=== End of repeated output ===

No indication of failed target found.
Hint: Try searching the build log for '] Error'.
Hint: See doc/building.html#troubleshooting for assistance.

make[1]: *** [/cygdrive/d/jdk11u-113c646a33d2/make/Init.gmk:305: main] Error 2
make: *** [/cygdrive/d/jdk11u-113c646a33d2/make/Init.gmk:186: all] Error 2

This is because the Windows Kits directory has spaces in it, use fsutil :

1
fsutil file setshortname "D:\Windows Kits" Kits

Reconfiguration.

1
./configure --with-debug-level=slowdebug --with-native-debug-symbols=external --disable-warnings-as-errors --with-tools-dir=/cygdrive/c/VS/VC/Auxiliary

test_json.cpp(357): error C2143: syntax error: missing

Error encountered reporting.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(371): note: see previous definition of 'TestBody'
make[3]: *** [lib/CompileGtest.gmk:61: /cygdrive/d/jdk11u-113c646a33d2/build/windows-x86_64-normal-server-slowdebug/hotspot/variant-server/libjvm/gtest/objs/test_json.obj] Error 1
make[3]: *** Waiting for unfinished jobs....
make[2]: *** [make/Main.gmk:272: hotspot-server-libs] Error 2

ERROR: Build failed for target 'hotspot' in configuration 'windows-x86_64-normal-server-slowdebug' (exit code 2)

=== Output from failing command(s) repeated here ===
* For target hotspot_variant-server_libjvm_gtest_objs_test_json.obj:
test_json.cpp
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(357): error C2143: syntax error: missing ')' before ']'
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(355): error C2660: 'JSON_GTest::test': function does not take 1 arguments
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(49): note: see declaration of 'JSON_GTest::test'
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(357): error C2143: syntax error: missing ';' before ']'
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(357): error C2059: syntax error: ']'
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(357): error C2017: illegal escape sequence
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(357): error C2059: syntax error: ')'
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(363): error C2143: syntax error: missing ')' before ']'
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(361): error C2660: 'JSON_GTest::test': function does not take 1 arguments
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(49): note: see declaration of 'JSON_GTest::test'
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(363): error C2143: syntax error: missing ';' before ']'
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(363): error C2059: syntax error: ']'
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(363): error C2017: illegal escape sequence
d:/jdk11u-113c646a33d2/test/hotspot/gtest/utilities/test_json.cpp(363): error C2059: syntax error: ')'
   ... (rest of output omitted)

* All command lines available in /cygdrive/d/jdk11u-113c646a33d2/build/windows-x86_64-normal-server-slowdebug/make-support/failure-logs.
=== End of repeated output ===

No indication of failed target found.
Hint: Try searching the build log for '] Error'.
Hint: See doc/building.html#troubleshooting for assistance.

make[1]: *** [/cygdrive/d/jdk11u-113c646a33d2/make/Init.gmk:305: main] Error 2
make: *** [/cygdrive/d/jdk11u-113c646a33d2/make/Init.gmk:186: hotspot] Error 2

You can see that this error is a single test in the error, the solution: delete this file or delete this function that reports the error.