Fewer than 20 files make a JVM for yourself! Now there are only 11 files!
Support Java 8, Java 11 and Java 14!
This purpose is not only for me, but also for the other javaer.
- For fun.
- To know how JVM works.
- To learn Java deeply.
- Make it (JJVM) Simple, Clean and Funny.
. # main project
├── build # generated by gradle
├── build.gradle
├── demo # subproject
│ ├── build # generated by gradle
│ ├── build.gradle
│ └── src
│ └── main # some examples
├── gradle
├── gradlew
├── gradlew.bat
├── README.md
├── settings.gradle
└── src # gradle project
├── main # core code
└── test # test case
The structure of the core code:
src/main/java/me/chongwish/jjvm/
├── Argument.java # parse command line argument
├── Bytecode.java # bytecode wrapper
├── Classfile.java # parse the .class file
├── Classloader.java # class loader
├── Classpath.java # find class from [file,directory,jar,zip,jrt]
├── Frame.java # java frame, is not jframe
├── Instruction.java # jvm instruction
├── Interpreter.java # jvm interpreter
├── NativeMethod.java # jvm native method
├── RuntimeDataArea.java # jvm runtime data area
└── Starter.java # jjvm entry
Mine is that:
- emacs + lsp-java
- openjdk 14 & openjdk 11 & openjdk 8
- gradle version 6
- archlinux container on gentoo host & windows 10
I haven't tested other jdk version.
Build a jar first:
./gradlew clean build
And then a JVM which name is jjvm.jar will be generated in the build directory. Run it:
java -jar build/libs/jjvm.jar
Some message was displayed in your terminal:
Usage: jjvm [-?] [-version] [-cp=<classpaths>]... mainclass [args......]
A toy of jvm
mainclass main class
[args......] arguments following the main class
-?, -help display help message
-cp, -classpath=<classpaths>
class search path of directories
-version display version info
There are some samples in the demo project. For example, there are three java file:
// file: demo/src/main/java/me/chongwish/jjvm/demo/Main.java
package me.chongwish.jjvm.demo;
import me.chongwish.jjvm.demo.sort.Bubble;
import me.chongwish.jjvm.demo.sort.Sort;
public class Main {
public static void main(String[] args) {
System.out.println("Bubble.sort");
Integer[] array = new Integer[] { 5, 4, 1, 8, 12, 6 };
System.out.print("before: ");
for (int n : array) {
System.out.print(n + " ");
}
System.out.println();
Sort<Integer> fn = new Bubble<>();
fn.sort(array);
System.out.print("after: ");
for (int n : array) {
System.out.print(n + "");
}
System.out.println();
}
}
// file: demo/src/main/java/me/chongwish/jjvm/demo/sort/Sort.java
package me.chongwish.jjvm.demo.sort;
public interface Sort<T extends Comparable<? super T>> {
public T[] sort(T[] array);
}
// file: demo/src/main/java/me/chongwish/jjvm/demo/sort/Bubble.java
package me.chongwish.jjvm.demo.sort;
public class Bubble<T extends Comparable<? super T>> implements Sort<T> {
@Override
public T[] sort(T[] array) {
for (int i = 0; i < array.length - 1; ++i) {
for (int j = 0; j < array.length - 1 - i; ++j) {
if (array[j].compareTo(array[j + 1]) > 0) {
T temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
return array;
}
}
The class file was generated automatically when you run the command gradle run build
.
demo/build/classes/java/main/me/chongwish/jjvm/demo/
├── Main.class
└── sort
├── Bubble.class
└── Sort.class
To use our JVM to run the class which name is Main
:
java -jar build/libs/jjvm.jar -cp demo/build/classes/java/main me.chongwish.jjvm.demo.Main
The output:
Bubble.sort
before: 5 4 1 8 12 6
after: 1 4 5 6 8 12
- Unfinished Instruction (0/4)
- Multi Thread
- Reflection (A poorly implementation)
- Native Method
- Exception (A poorly implementation)
- Newer Feature come from Java 8+
- VM System Class Initialization
- The Java® Language Specification
- The Java® Virtual Machine Specification
- 《自己动手写 Java 虚拟机》