preface

It’s a long story, and recently I have been idle and bored. I have been reading the JDK source code, but many key points are native methods, which leads to the need to look deeper, that is, I need to read the openjdk source code, but the c++ code is not easy, and it is not so good.

I’ve compiled openJDK11 in the previous article, but it was a success, so I’m going to import the openJDK source code into the IDE. Here I’ll use Clion as an example.

Excited heart, trembling hands, OpenJdk11 compiled successfully in Deepin!!

It took me a day to import openJDK. After all, openJDK is very complicated, and some of the references in the article said only to import hotspot directory, some said to import openJDK \ SRC directory, and some said to import the root directory. Almost didn’t give up, but the day was wasted, so I don’t know whether it was successful or not. Anyway, it’s working.

The compiled Java program will be used later (Java under bin), so you must compile openJDK first.

Import its

Then in the “Select” dialog box, select the root directory of openJDK (yes, the root directory), and click OK when you see OK, click Finish when you see finish.

So it’s going to look something like this.

The Executable is a compiled Java Executable that you compiled in the bin directory and cannot be downloaded from the official website.

Remember to remove everything if there is anything under Before launch.Click Run to get the version information. This is where the -version parameter configured in the previous step comes in.

Running a Java program

But we need to run the program we have written, otherwise the map is what, so first write a simple:

public class Main {

    public static void main(String[] args){
        int a=12;
        int b=34;
        System.out.println("a+b="+(a+b));
    }
    public static void test(String[] args){
        System.out.println("test"); }}Copy the code

We know that Java programs start from main, but if we can’t start from main, we need to modify the OpenJDK source code. The test method above will be run as main later.

Let’s compile.

Then reconfigure the startup parameters.Run it again.

We can go back to the openJDK source, go to the java.c file, navigate to the JavaMain method, and there’s a section that gets the id of the main method, and then we’ll call that method later, All we need to do is change the “main” in the GetStaticMethodID parameter and recompile, this time just by making, which is fast.

([Ljava/lang/String;)V represents an array of strings, and methods return no value.

With all due respect, this is probably the most detailed class file structure analysis you’ve ever seen

int JNICALL
JavaMain(void * _args)
{
    mainID = (*env)->GetStaticMethodID(env, mainClass, "main"."([Ljava/lang/String;)V");
   (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
}
Copy the code

Run it again, and you can see that instead of executing main, the test method is executed.

The rest is to debug at breakpoints, such as the thread’s start0 method, which eventually calls the operating system’s API to start the thread from which we can debug breakpoints.