Home » Java » Core Java » How is Java / JVM built ? Adopt OpenJDK is your answer!

About Attila Mihaly Balazs

Attila Mihaly Balazs

How is Java / JVM built ? Adopt OpenJDK is your answer!

Introduction & history

As some of you may already know, starting with Java 7, OpenJDK is the Reference Implementation (RI) to Java. The below timeline gives you an idea about the history of OpenJDK:

 
 
 
 
 

OpenJDK history (2006 till date)

OpenJDK history (2006 till date)

See Adopt OpenJDK – the past present and future [1] for some more details.

If you have wondered about the JDK or JRE binaries that you download from vendors like Oracle, Red Hat, etcetera, then the clue is that these all stem from OpenJDK. Each vendor then adds some extra artefacts that are not open source yet due to security, proprietary or other reasons.

What is OpenJDK made of ?

OpenJDK is made up of a number of repositories, namely corba, hotspot, jaxp, jaxws, jdk, langtools, and nashorn. Between OpenjJDK8 and OpenJDK9 there have been no new repositories introduced, but lots of new changes and restructuring, primarily due to Jigsaw – the modularisation of Java itself [2] [3] [4] [5].

repo composition, language breakdown (metrics are estimated)

repo composition, language breakdown (metrics are estimated)

 

How has Java the language and platform built over the years ?

Java is built by bootstrapping an older (previous) version of Java – i.e. Java is built using Java itself as its building block. Where older components are put together to create a new component which in the next phase becomes the building block. A good example of bootstrapping can be found at Scheme from Scratch [6] or even on Wikipedia [7].

OpenJDK8 [8] is compiled and built using JDK7, similarly OpenJDK9 [9] is compiled and built using JDK8. In theory OpenJDK8 can be compiled using the images created from OpenJDK8, similarly for OpenJDK9 using OpenJDK9. Using a process called bootcycle images – a JDK image of OpenJDK is created and then using the same image, OpenJDK is compiled again, which can be accomplished using a make command option:

$ make bootcycle-images       # Build images twice, second time with newly built JDK

make offers a number of options under OpenJDK8 and OpenJDK9, you can build individual components or modules by naming them, i.e.

$ make [component-name] | [module-name]

or even run multiple build processes in parallel, i.e.

$ make JOBS=<n>                 # Run <n> parallel make jobs

Finally install the built artefact using the install option, i.e.

$ make install

Some myths busted

OpenJDK or Hotspot to be more specific isn’t completely written in C/C++, a good part of the code-base is good ‘ole Java (see the composition figure above). So you don’t have to be a hard-core developer to contribute to Open JDK. Even the underlying C/C++ code code-base isn’t scary or daunting to look at. For example here is an extract of a code snippet from vm/memory/universe.cpp
in the HotSpotrepo – http://hg.openjdk.java.net/jdk6/jdk6/hotspot/raw-file/a541ca8fa0e3/src/share/vm/memory/universe.cpp [10]:

.
.
.
Universe::initialize_heap()

if (UseParallelGC) {
    #ifndef SERIALGC
    Universe::_collectedHeap = new ParallelScavengeHeap();
    #else // SERIALGC
        fatal("UseParallelGC not supported in this VM.");
    #endif // SERIALGC

} else if (UseG1GC) {
    #ifndef SERIALGC
    G1CollectorPolicy* g1p = new G1CollectorPolicy();
    G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
    Universe::_collectedHeap = g1h;
    #else // SERIALGC
        fatal("UseG1GC not supported in java kernel vm.");
    #endif // SERIALGC

} else {
    GenCollectorPolicy* gc_policy;

    if (UseSerialGC) {
        gc_policy = new MarkSweepPolicy();
    } else if (UseConcMarkSweepGC) {
        #ifndef SERIALGC
        if (UseAdaptiveSizePolicy) {
            gc_policy = new ASConcurrentMarkSweepPolicy();
        } else {
            gc_policy = new ConcurrentMarkSweepPolicy();
        }
        #else // SERIALGC
            fatal("UseConcMarkSweepGC not supported in this VM.");
        #endif // SERIALGC
    } else { // default old generation
        gc_policy = new MarkSweepPolicy();
    }

    Universe::_collectedHeap = new GenCollectedHeap(gc_policy);
}
.
.
.

(please note that the above code snippet might have changed since published here)
The things that appears clear from the above code-block are, we are looking at how pre-compiler notations are used to create Hotspot code that supports a certain type of GC i.e. Serial GC or Parallel GC. Also the type of GC policy is selected in the above code-block when one or more GC switches are toggled i.e. UseAdaptiveSizePolicy when enabled selects the Asynchronous Concurrent Mark and Sweep policy. In case of either Use Serial GC or Use Concurrent Mark Sweep GC are not selected, then the GC policy selected is Mark and Sweep policy. All of this and more is pretty clearly readable and verbose, and not just nicely formatted code that reads like English.

Further commentary can be found in the section called Deep dive Hotspot stuff in the Adopt OpenJDK Intermediate & Advance experiences [11] document.

Steps to build your own JDK or JRE

Earlier we mentioned about JDK and JRE images – these are no longer only available to the big players in the Java world, you and I can build such images very easily. The steps for the process have been simplified, and for a quick start see the Adopt OpenJDK Getting Started Kit [12] and Adopt OpenJDK Intermediate & Advance experiences [11] documents. For detailed version of the same steps, please see the Adopt OpenJDK home page [13]. Basically building a JDK image from the OpenJDK code-base boils down to the below commands:
(setup steps have been made brief and some commands omitted, see links above for exact steps)

$ hg clone http://hg.openjdk.java.net/jdk8/jdk8 jdk8  (a)...OpenJDK8

or

$ hg clone http://hg.openjdk.java.net/jdk9/jdk9 jdk9  (a)...OpenJDK9

$ ./get_sources.sh                                    (b)

$ bash configure                                      (c)

$ make clean images                                   (d)

(setup steps have been made brief and some commands omitted, see links above for exact steps)

To explain what is happening at each of the steps above:

(a) We clone the openjdk mercurial repo just like we would using git clone ….

(b) Once we have step (a) completed, we change into the folder created, and run the get_sources.sh command, which is equivalent to a git fetch or a git pull, since the step (a) only brings down base files and not all of the files and folders.

(c) Here we run a script that checks for and creates the configuration needed to do the compile and build process

(d) Once step (c) is success we perform a complete compile, build and create JDK and JRE images from the built artefacts

As you can see these are dead-easy steps to follow to build an artefact or JDK/JRE images [step (a) needs to be run only once].

Benefits

  • contribute to the evolution and improvement of the Java the language & platform
  • learn about the internals of the language and platform
  • learn about the OS platform and other technologies whilst doing the above
  • get involved in F/OSS projects
  • stay on top the latest changes in the Java / JVM sphere
  • knowledge and experience that helps professionally but also these are not readily available from other sources (i.e. books, training, work-experience, university courses, etcetera)
  • advancement in career
  • personal development (soft skills and networking)

Contribute

Join the Adopt OpenJDK [14] and Betterrev [15] projects and contribute by giving us feedback about everything Java including these projects. Join the Adoption Discuss mailing list and other OpenJDK related mailing lists to start with, these will keep you updated with latest progress and changes to OpenJDK. Fork any of the projects you see and submit changes via pull-requests.

Thanks and support

Adopt OpenJDK [14] and umbrella projects have been supported and progressed with help of JCP [21], the Openjdk team [22], JUGs like London Java Community [16], SouJava [17] and other JUGs in Brazil, a number of JUGs in Europe i.e. BGJUG (Bulgarian JUG) [18], BeJUG (Belgium JUG) [19], Macedonian JUG [20], and a number of other small JUGs. We hope in the coming time more JUGs and individuals would get involved. If you or your JUG wish to participate please get in touch.

(0 rating, 0 votes)
You need to be a registered member to rate this.
Start the discussion Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments