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.
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.
- installation directory, do not have spaces, otherwise you have to use fsutil for short path conversion, see error resolution for details.
- 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.
- 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.
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.
-
Run the Java program.
1
2
|
ubuntu@zhang:~/jdk11u-113c646a33d2$ ./build/linux-x86_64-normal-server-slowdebug/jdk/bin/java hello.java
Hello World
|
-
Find the PID of the Java program.
1
2
3
|
ubuntu@zhang:~$ jps
12257 Main
12302 Jps
|
-
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.