Utility tooling for instrumentation, test scaffolding, etc
In-memory/on-disk support for compilation and archiving, power-proxing and dynamic instrumentation, supporting JDKs 8, 9 and 10.
You could:
- Compile from a string, with dependencies from Maven artifact coordinates, stuffed into a signed, in-memory, multi-release JAR, complete with annotations processed, performing bytecode class transformation, an OSGi bundle manifest and a JPMS module-info, then load into current. runtime or publish to a maven repo…
- Attach a JavaAgent to a JUnit test without modifying the JVM start-up parameters (i.e. out-of-the-box IDE support)
- Proxy concrete classes with convenience of vanilla InvocationHandlers
Tests as Examples and Examples as Documentation
At this initial stage the aim is to prove minimal documentation through examples extracted from tests. Currently some modules have no documentation; these are typically of limited value to the end user. See the module list.
A ridiculous Hello World example demonstrates the use of multiple modules; it creates 3 interdependent JARs, and then executes as OSGi, JPMS and vanilla Java applications, entirely in-memory. A smaller example of just dynamic in-memory JPMS can be found in lade.jpms.
Otherwise, a sensible place to start is instrumental.archive, which lists the various extension modules, each of which has a brief example.
Module List
Module | Description | Examples |
---|---|---|
io.earcam.instrumental.reflect | Gentle reflection of types, names and resources | ✔ |
io.earcam.instrumental.compile | Compile from memory/filesystem to memory/filesystem, easily | ✔ |
io.earcam.instrumental.compile.glue | Glues instrumental.compile to instrumental.archive, compile to JAR entirely in-memory | ✔ |
io.earcam.instrumental.lade | Not just the usual fudge of ClassLoader.defineClass() - loads in-memory JARs returning valid resource URLs | ✔ |
io.earcam.instrumental.lade.jpms | Create and run dynamic JPMS module layers from an in-memory classloader | ✔ |
io.earcam.instrumental.fluent | Annotation to demarcate fluent API methods | ✗ |
io.earcam.instrumental.fluency | Annotation processor of fluently annotated methods, generating APIs with fluency | ✗ |
io.earcam.instrumental.module.manifest | Abstraction of java.util.jar.Manifest, extended variously | ✗ |
io.earcam.instrumental.module.auto | Bytecode parsing sufficient to enable auto-importing for programmatic modules | ✔ |
io.earcam.instrumental.module.jpms | JPMS module tooling; read/write bytecode/sourcecode | ✔ |
io.earcam.instrumental.module.osgi | OSGi module tooling; read/write bundle manifests | ✔ |
io.earcam.instrumental.archive | Create/read archives in-memory/on-disk, supports Multi-Release JARs | ✔ |
io.earcam.instrumental.archive.jpms | Archive extension for JPMS modules | ✔ |
io.earcam.instrumental.archive.osgi | Archive extension for OSGi bundles | ✔ |
io.earcam.instrumental.archive.sign | Archive extension for digital signing | ✔ |
io.earcam.instrumental.archive.glue | Glues instrumental.archive to to instrumental.compile, enabling in-memory archives as dependencies | ✔ |
io.earcam.instrumental.archive.maven | Install/Resolve archives to/from Maven repositories | ✔ |
io.earcam.instrumental.proxy | Smoother API than java.lang.reflect and various InvocationHandlers | ✔ |
io.earcam.instrumental.proxy.concrete | Proxy classes using standard java.lang.reflect.InvocationHandler | ✔ |
io.earcam.instrumental.agent | Dynamically load a Java Agent or acquire java.lang.instrument.Instrumentation via SPI | ✔ |
io.earcam.instrumental.agent.junit | Use Java Agents in JUnit tests (4.12 and 5.3.0-M1) without any external configuration | ✔ |
io.earcam.instrumental.agent.defy | Java Agent to remove final modifiers from classes, methods and fields | ✗ |