What is post-compile (binary) weaving, and when would you use it instead of ordinary compile-time weaving?
answer
- weave compiled .class/JARs, not source
- ajc -inpath (woven) vs -classpath (visible only)
- advise third-party / vendor bytecode
- weaveDependencies / aspectLibraries in the plugin
- still needs aspectjrt, no agent
basics
~20 sPost-compile (binary) weaving runs ajc over already-compiled .class files or JARs instead of source. You use it to weave aspects into bytecode you didn't compile yourself — third-party libraries or a separately built module — via ajc's -inpath.
solid answer
~50 sCompile-time weaving needs source: ajc compiles your .java together with the aspects and weaves in one step. Post-compile weaving, also called binary weaving, takes *already compiled* bytecode — .class files or whole JARs — and weaves aspects into it after the fact. You point ajc's -inpath at the compiled artifacts (as opposed to -sourceroots for source), and it emits woven copies. With the aspectj-maven-plugin you configure weaveDependencies or a weaveDirectories/inpath entry. The killer use case is advising code you don't own or can't recompile from source: a vendor JAR, a shaded library, or a downstream module already built by another team. It's also how you weave an aspect library that itself ships as a compiled JAR (aspectLibraries). The result is still fully static woven bytecode — no runtime agent, no proxy — with the same aspectjrt runtime dependency as CTW.
code
xml · 24 lines<!-- aspectj-maven-plugin: binary-weave a dependency's compiled bytecode -->
<plugin>
<groupId>dev.aspectj</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<configuration>
<!-- weave aspects INTO this already-compiled dependency (-inpath) -->
<weaveDependencies>
<weaveDependency>
<groupId>com.vendor</groupId>
<artifactId>legacy-lib</artifactId>
</weaveDependency>
</weaveDependencies>
<!-- aspects supplied as a compiled JAR (-aspectpath) -->
<aspectLibraries>
<aspectLibrary>
<groupId>com.katajob</groupId>
<artifactId>audit-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution><goals><goal>compile</goal></goals></execution>
</executions>
</plugin>go deeper
Just know it weaves compiled bytecode/JARs rather than source.
Add the third-party/no-source use case and the -inpath mechanism.
Explain plugin config (weaveDependencies/aspectLibraries), -inpath vs -classpath, and version-brittleness gotchas.
Reason about when to prefer binary weaving vs LTW for instrumenting artifacts you can't recompile, including support/licensing and upgrade-fragility implications.
AspectJ offers three weaving times: **compile-time**, **post-compile (binary)**, and **load-time**. This question is about the middle one. **Compile-time weaving (CTW)** compiles source with `ajc` and weaves in the same pass — you must have the `.java` for the code being advised. **Post-compile / binary weaving** decouples the two: the code is *already compiled* (by `javac` or an earlier `ajc` run) into `.class` files or JARs, and `ajc` then runs again purely as a *weaver* over that bytecode. Nothing about the source is needed — only the bytecode. The mechanics: - `ajc -inpath <jars-or-dirs>` feeds **compiled artifacts to be woven** (contrast `-sourceroots`/`-classpath`, where classpath entries are visible but NOT woven). - `-aspectpath <jar>` supplies **already-compiled aspects** to apply. - The output is woven `.class`/JAR bytecode, semantically identical to what CTW would have produced. **With the `aspectj-maven-plugin`** (groupId `dev.aspectj`, or historically `org.codehaus.mojo`) you express binary weaving through: - `<weaveDependencies>` — list Maven dependencies (by groupId/artifactId) whose compiled classes should be woven (each becomes an `-inpath` entry). - `<weaveDirectories>` — weave classes in a directory. - `<aspectLibraries>` — apply aspects packaged in an external JAR (`-aspectpath`). **When to choose it over CTW:** 1. **You lack the source** — a third-party or vendor library where you only have the JAR. CTW is impossible; binary weaving can still instrument it. 2. **Cross-module / multi-project builds** — module A is compiled independently (perhaps by another team or in another repo), and you want to weave aspects into its published bytecode without forcing a recompile of A's source. 3. **Shared aspect libraries** — the aspects live in their own compiled artifact and are applied via `-aspectpath`/`aspectLibraries`. 4. **Instrumenting test or generated bytecode** produced by tools that only emit `.class`. **Edge cases / gotchas:** - You still need `aspectjrt` at runtime; the woven vendor classes now call into it. - Weaving vendor bytecode can be brittle across upstream version bumps — pointcuts matching internal methods may silently stop matching after an upgrade, so prefer stable public signatures. - Re-weaving already-woven classes is generally avoided; AspectJ tracks weave state to prevent double-weaving. - Licensing/warranty: modifying a vendor's bytecode may have legal or support implications. - If the goal is purely *runtime* instrumentation you can't rebuild at all, **load-time weaving** (agent + `aop.xml`) may be a better fit; binary weaving still requires a build step that rewrites the artifact. **Bottom line:** binary weaving = CTW's mechanism applied to bytecode instead of source, chosen precisely when source isn't available or recompilation isn't desirable, while keeping the static, proxy-free, agent-free runtime profile.
- What's the difference between ajc's -inpath and -classpath?-inpath lists compiled artifacts that ajc will actually weave into and re-emit; -classpath lists artifacts only made visible for type resolution and are NOT woven. Binary weaving hinges on putting the target on -inpath.
- Could you achieve the same third-party instrumentation with load-time weaving instead?Yes — LTW weaves the vendor classes as they're loaded via the aspectjweaver agent and aop.xml, needing no rebuilt artifact, but it adds a java agent and class-load-time cost. Binary weaving bakes it into a rebuilt JAR up front with no agent.
saying these in an interview costs you the question
- Claiming post-compile weaving needs the target's source code.
- Confusing -inpath (woven) with -classpath (visible only).
- Saying binary weaving uses a runtime agent like LTW does.