Code Monkey home page Code Monkey logo

jclass's Introduction

jclass: Java Class File Builder

jclass makes it easy to generate and analyze Java class files in Common Lisp. Build a compiler backend or a JVM bytecode analyzer with jclass!

Java classes, fields, methods, annotations, and more are represented as Lisp objects for easy analysis and manipulation. jclass also automatically builds the constant pool for you (but you can still make the pool manually if you want!)

It's also possible to create custom class attributes with jclass. An attribute description DSL makes it easy to add new attributes. Great for targeting custom JVMs or experimental features.

jclass is feature complete and the API is mostly stable. jclass will be updated with new JVM features whenever they are released, so do not (:use #:jclass) in your packages.

Hello World Example

For in-depth information, see the manual.

;; Build the main method
(defparameter *main*
  (make-instance 'jclass:method-info
    :flags '(:public :static)
    :name "main"
    :descriptor "([Ljava/lang/String;)V" ; void (String[])
    :attributes
      (list
        (make-instance 'jclass:code
          :max-stack  2
          :max-locals 1
          :bytecode
            `((:getstatic "java/lang/System" "out" "Ljava/io/PrintStream;")
              (:ldc ,(jclass:make-string-info "Hello, world!"))
              (:invokevirtual "java/io/PrintStream" "println" "(Ljava/lang/String;)V")
              :return)
          :exceptions '()
          :attributes '()))))

;; Generate the class file
(with-open-file (stream "./Hello.class"
                        :direction :output
                        :element-type '(unsigned-byte 8))
  (write-sequence
    (jclass:java-class-bytes
      (make-instance 'jclass:java-class
        ;; version 55.0 = Java 11
        :major-version 55
        :minor-version 0
        :flags '(:public)
        :name "Hello"
        :parent "java/lang/Object"
        :interfaces '()
        :fields '()
        :methods (list *main*)
        :attributes '()))
        stream))

The class file executes as expected:

$ java Hello
Hello, world!

Output from javap:

$ javap -v Hello.class
Classfile Hello.class
  Last modified Aug 22, 2021; size 281 bytes
  MD5 checksum b1d5aa6684ec1b281718b3cb249f21a0
public class Hello
  minor version: 0
  major version: 55
  flags: (0x0001) ACC_PUBLIC
  this_class: #1                          // Hello
  super_class: #2                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 1, attributes: 0
Constant pool:
   #1 = Class              #9             // Hello
   #2 = Class              #10            // java/lang/Object
   #3 = Utf8               main
   #4 = Utf8               ([Ljava/lang/String;)V
   #5 = Fieldref           #11.#13        // java/lang/System.out:Ljava/io/PrintStream;
   #6 = String             #16            // Hello, world!
   #7 = Methodref          #17.#19        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #8 = Utf8               Code
   #9 = Utf8               Hello
  #10 = Utf8               java/lang/Object
  #11 = Class              #12            // java/lang/System
  #12 = Utf8               java/lang/System
  #13 = NameAndType        #14:#15        // out:Ljava/io/PrintStream;
  #14 = Utf8               out
  #15 = Utf8               Ljava/io/PrintStream;
  #16 = Utf8               Hello, world!
  #17 = Class              #18            // java/io/PrintStream
  #18 = Utf8               java/io/PrintStream
  #19 = NameAndType        #20:#21        // println:(Ljava/lang/String;)V
  #20 = Utf8               println
  #21 = Utf8               (Ljava/lang/String;)V
{
  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=1, args_size=1
         0: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #6                  // String Hello, world!
         5: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
}

Installation

Manual Install

jclass is currently not in Quicklisp or Ultralisp.

Install by cloning to your ~/common-lisp/ or quicklisp/local-projects/ directories.

Then run the following:

(ql:register-local-projects)
(asdf:load-system "jclass")

Roswell Install

If you have Roswell, you can install from Github.

$ ros install davidsun0/jclass

Portability / Compatibility

jclass should work on conforming Common Lisps with the following features:

  • char-code and code-char must work with Unicode code points.
    • If not working with Unicode, the functions must use ASCII values.

Incompatibility with an implementation that meets these requirements should be considered a bug. Please report any issues.

Verification

Since jclass works at the binary level, it only performs structural validation, not semantic validation. For example, certain attributes and flags are incompatible. Some features may only work with certain class file versions. jclass does not ensure that a JVM will accept a generated class.

It is up to the user to correctly match class file features.

Implemented Structures by JVM Spec Section

  • 4.1 The ClassFile Structure
  • 4.4 The Constant Pool
  • 4.5 Fields
  • 4.6 Methods
  • 4.7 Attributes
    • 4.7.2 ConstantValue
    • 4.7.3 Code
    • 4.7.4 StackMapTable
    • 4.7.5 Exceptions
    • 4.7.6 InnerClasses
    • 4.7.7 EnclosingMethod
    • 4.7.8 Synthetic
    • 4.7.9 Signature
    • 4.7.10 SourceFile
    • 4.7.11 SourceDebugExtension
    • 4.7.12 LineNumberTable
    • 4.7.13 LocalVariableTable
    • 4.7.14 LocalVariableTypeTable
    • 4.7.15 Deprecated
    • 4.7.16 RuntimeVisibleAnnotations
    • 4.7.17 RuntimeInvisibleAnnotations
    • 4.7.18 RuntimeVisibleParameterAnnotations
    • 4.7.19 RuntimeInvisibleParameterAnnotations
    • 4.7.20 RuntimeVisibleTypeAnnotaions
    • 4.7.21 RuntimeInvisibleTypeAnnotations
    • 4.7.22 AnnotationDefault
    • 4.7.23 BootstrapMethods
    • 4.7.24 MethodParameters
    • 4.7.25 Module
    • 4.7.26 ModulePackages
    • 4.7.27 ModuleMainClass
    • 4.7.28 NestHost
    • 4.7.29 NestMembers
    • 4.7.30 Record
    • 4.7.31 PermittedSublcasses

Bytecode Instructions

  • Bytecode instructions (205 / 205)
    • Constants (21 / 21)
    • Loads (33 / 33)
    • Stores (33 / 33)
    • Stack (9 / 9)
    • Math (37 / 37)
    • Conversions (15 / 15)
    • Comparisons (19 / 19)
    • References (18 / 18)
    • Control (11 / 11)
    • Extended (6 / 6)
    • Reserved (3 / 3)

Library Design

jclass is based off of the Java Virtual Machine Specification, and not the Java Programming Language. As such, it can generate code that uses the invokedynamic instruction or use special characters in names.

The class file is represented as a tree of objects. Every named structure in the JVM Specification has an equivalent Lisp object.

There are functions to assemble and disassemble a java-class object to and from a .class file. As fields, methods, and attributes are part of a class, they cannot be serialized independently.

License

MIT

jclass's People

Contributors

davidsun0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

jclass's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.