#java-class #class #java #bytecode #jvm #file-reader

noak

A library for reading and writing java bytecode fast

9 unstable releases

0.5.0 May 8, 2022
0.4.0 May 8, 2022
0.4.0-alpha.3 Apr 5, 2020
0.4.0-alpha.2 Jan 1, 2020
0.1.0 Aug 4, 2019

#1188 in Parser implementations

48 downloads per month

MIT license

305KB
9K SLoC

Noak

A library for reading and writing java bytecode.

Example

use noak::reader::Class;

let mut class = Class::new(&bytes)?;

println!("Major Version: {}", class.version().major);
println!(" Access Flags: {:?}", class.access_flags()?);
println!("   Class Name: {}", class.this_class_name()?.display()?);

Why should you use noak?

  • Reading:
    • You want to parse class files without losing information.
    • You don't want to parse the entire class file.
    • Any valid class file is accepted by noak. Many invalid class files are accepted as well (this can be useful for reading heavily obfuscated code).
  • Writing:
    • You want to write your own class files (limitations apply; see below).

Why wouldn't you use noak?

Many of these issues are in the process of being resolved, but that may take some time.

  • You want more than just a low-level class file reader and writer.
  • Noak makes heavy use of the type system and macros. This can cause problems with your IDE or make some aspects hard to understand.
  • Documentation is virtually non-existent.
  • The API is very unstable.
  • The code is not heavily tested.
  • Reading:
    • Some code may be repetitive (e.g. retrieving values from the constant pool).
  • Writing:
    • Modifying existing class files can be very tedious.
    • Not every attribute can be written at the moment (related issue)
    • Jumps above 65535 bytes may fail to be written.
    • The builder API isn't flexible enough for your use case.
    • Custom errors are quite restricted.
    • Stack Map Frames are not automatically generated.

Alternatives

This is not an exhaustive list. The statements below may not accurately reflect reality.

Libraries written in Rust:

  • cafebabe
    • Parses the entire file at once.
    • Accesses the constant pool during parsing. No explicit retrieval from the user side required.
  • classreader-rs
    • Parses the entire file at once.
    • Only supports parsing.
    • Does not support any attributes from version 53.0 and above.
    • Does not parse strings containing unpaired surrogates.
  • jbcrs
    • Parses the entire file at once.
    • Only supports parsing.
    • Does not support any attributes from version 53.0 and above.
    • Does not parse files containing UTF-8 constants with unpaired surrogates.
  • frappe/classfile
    • Parses the entire file at once.
    • Only supports parsing.
    • Does not support any attributes from version 53.0 and above.
    • Does not parse files containing UTF-8 constants with surrogates.
  • classfile-rs
    • Seems to be very incomplete.
    • Supports writing as well as parsing.
    • Parses the entire file at once.
    • Reads UTF-8 constants lossily.
  • classfile-parser
    • Seems to be very incomplete.
    • Parses the entire file at once.
    • Only supports parsing.
  • classfmt
    • Seems to be very incomplete.
    • Parses the entire file at once.
    • Only supports parsing.
  • javabc
    • Seems to be very incomplete.
    • Parses the entire file at once.
    • Only supports parsing.

A small fraction of libraries written in languages that are not Rust:

  • ASM (Java)
    • The most comprehensive and best supported bytecode manipulation and analysis framework.
    • Use this if noak does not suit your requirements and probably even if it does suit them.
  • javassist (Java)
    • A high-level bytecode library.
  • BCEL (Java)

License

This project is licensed under the MIT license.

Dependencies

~1MB
~18K SLoC