Noak
A library for reading and writing java class files.
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 class file 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.