Miscellaneous Tools

This chapter provides provides a tutorial example on how to use 'jaotc' command to produce native code in the form of a shared library from Java bytecode files. But I didn't find any way to use the shared library.

__chapterToc__

Warning: "jaotc" has been removed since JDK 17.

What Is "jaotc"? - "jaotc" is a Java Ahead-Of-Time (AOT) static compiler which produces native code in the form of a shared library from Java bytecode files.

According to Java documentation, "The Java Virtual Machine can load these shared libraries and use native code from them when corresponding Java methods are called. By using jaotc, there is no need to wait for the JIT compiler to generate (by compiling bytecode) the fast native code for these Java methods. The code is already generated by jaotc and ready to be immediately used. For the same reason, there is no need to execute these methods in the Interpreter because fast compiled native code can be executed instead."

If you have %java_home%\bin directory included in "path" the environment variable, you can run "jaotc --help" to get the usage information:

herong> jaotc --help

Usage: jaotc <options> list

  list       A : separated list of class names, modules, jar files
             or directories which contain class files.

where options include:
  --output <file>      Output file name
  --class-name <class names> List of classes to compile
  --jar <jarfiles>     List of jar files to compile
  --module <modules>   List of modules to compile
  --directory <dirs>   List of directories where to search for
                       files to compile
  --search-path <dirs> List of directories where to search for
                       specified files
  --compile-commands <file> Name of file with compile commands
  --compile-for-tiered Generate profiling code for tiered compilation
  --compile-with-assertions Compile with java assertions
  --compile-threads <number> Number of compilation threads to be used
  --ignore-errors      Ignores all exceptions thrown during class loading
  --exit-on-error      Exit on compilation errors
  --info               Print information during compilation
  --verbose            Print verbose information
  --debug              Print debug information
  -? -h --help         Print this help message
  --version            Version information
  --linker-path        Full path to linker executable
  -J<flag>             Pass <flag> directly to the runtime system

Here is what I did to try the "jaotc" tool. on my macOS computer with JDK 15.

1. Create a test class file called Circle.java:

/* Circle.java
 * Copyright (c) 2018 HerongYang.com. All Rights Reserved.
 */
public class Circle {
  public String uom = "Centimeter";
  private int x = 0;
  private int y = 0;
  private int r = 1;

  public void setRadius(int radius) {
    r = radius;
  }
  public void setCenter(int centerX, int centerY) {
    x = centerX;
    y = centerY;
  }
  public void printRadius() {
    System.out.println(r + " " + uom);
  }
  public void printArea() {
    double area = getArea();
    System.out.println(area + " " + uom + "^2");
  }
  private double getArea() {
    return 3.14159*r*r;
  }
}

2. Create another class to call methods in the Circle class:

/* CircleTest.java
 * Copyright (c) 2018 HerongYang.com, All Rights Reserved.
 */
public class CircleTest {
  public static void main(String[] a) {
  Circle c = new Circle();
  c.setRadius(3);
  c.setCenter(1,1);
  c.printRadius();
  c.printArea();
  }
}

3. Compile both class files:

herong$ javac Circle.java
herong$ javac CircleTest.java
herong$ ls -l

-rw-r--r--  1370  Circle.class
-rw-r--r--   602  Circle.java
-rw-r--r--   434  CircleTest.class
-rw-r--r--   260  CircleTest.java

4. Compile Circle.class into a native code library:

$ /Library/Java/JavaVirtualMachines/jdk-15.jdk/Contents/Home/bin/jaotc \
  --output libCircle.so Circle.class

herong$ ls -l

-rw-r--r--    1370  Circle.class
-rw-r--r--     602  Circle.java
-rw-r--r--     434  CircleTest.class
-rw-r--r--     260  CircleTest.java
-rw-r--r--  142088  libCircle.so

5. Run CircleTest with the native code library:

herong$ java -XX:+UnlockExperimentalVMOptions \
  -XX:AOTLibrary=./libCircle.so CircleTest

3 Centimeter
28.274309999999996 Centimeter^2

The output looks correct. But how can we confirm that JVM actually called the native code in libCircle.so instead of the bytecode in Circle.class?

6. Let's remove Circle.class and see what happens:

herong$ rm Circle.class

herong$ java -XX:+UnlockExperimentalVMOptions \
  -XX:AOTLibrary=./libCircle.so CircleTest

Exception in thread "main" java.lang.NoClassDefFoundError: Circle

Too bad. JVM will not start without Circle.class.

7. Let's change the method printArea() in the Circle.class and see which version of the method gets called:

herong$ vi Circle.java
...
  public void printArea() {
    double area = getArea();
    System.out.println(area + " " + uom + "^2 - Changed");
  }
...

herong$ javac Circle.java

herong$ java -XX:+UnlockExperimentalVMOptions \
  -XX:AOTLibrary=./libCircle.so CircleTest

3 Centimeter
28.274309999999996 Centimeter^2 - Changed

That's really bad. JVM did not all native code in libCircle.so as instructed! It called the changed version from the bytecode in Circle.class.

So I am not able to use the native code in the shared library generated by "jaotc".

Table of Contents

 About This Book

 Java Tools Terminology

 Java Tools Included in JDK

 javac - The Java Program Compiler

 java - The Java Program Launcher

 jar - The JAR File Tool

 jlink - The JRE Linker

 jmod - The JMOD File Tool

 jimage - The JIMAGE File Tool

 jpackage - Binary Package Builder

 javadoc - The Java Document Generator

 jdeps - The Java Class Dependency Analyzer

 jdeprscan - The Java Deprecated API Scanner

 jdb - The Java Debugger

 jcmd - The JVM Diagnostic Tool

 jconsole - Java Monitoring and Management Console

 jstat - JVM Statistics Monitoring Tool

 JVM Troubleshooting Tools

 jhsdb - The Java HotSpot Debugger

 jvisualvm (Java VisualVM) - JVM Visual Tool

 jmc - Java Mission Control

 javap - The Java Class File Disassembler

 keytool - Public Key Certificate Tool

 jarsigner - JAR File Signer

 jshell - Java Language Shell

 jrunscript - Script Code Shell

Miscellaneous Tools

 serialver - serialVersionUID Generator

jaotc - Java Ahead-Of-Time Compiler

 jwebserver - Java Web Server

 native2ascii - Native-to-ASCII Encoding Converter

 JAB (Java Access Bridge) for Windows

 Archived Tutorials

 References

 Full Version in PDF/EPUB