Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .settings/spotbugs-exclude.xml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,22 @@
<Bug pattern="EI_EXPOSE_STATIC_REP2"/>
</Match>

<!--
getSettingsLock() has to return the exact same SETTINGS_LOCK instance to callers
outside this class (I-032): the settings live as two separate copies of this class, one
per classloader, and JavaAOPTestCase / the AspectJ and instrumentation advice toolboxes
reach the *other* copy's lock reflectively so a write on one classloader's copy and
reset() on the other cannot interleave. That cross-classloader coordination is only
possible if the accessor is public, which is exactly the pattern this bug flags when
reset() also synchronises on the same field internally. Narrowing the accessor's
visibility would defeat the fix it exists to support.
-->
<Match>
<Class name="de.tum.cit.ase.ares.api.aop.java.JavaAOPTestCaseSettings"/>
<Method name="reset"/>
<Bug pattern="USO_UNSAFE_ACCESSIBLE_OBJECT_SYNCHRONIZATION"/>
</Match>

<!--
This method is a transparent replacement for one Object.wait() invocation. It must call
wait exactly once and return with the same semantics as the original call site; introducing
Expand Down
6 changes: 3 additions & 3 deletions docs/HowToMakeAProjectAnAresProject.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ configurations {
}
```

**Explanation:** This creates a new Gradle configuration named `aresAgent`. A Gradle configuration is a named bucket of dependencies that can be resolved independently; by creating a dedicated one for the agent, the agent JAR is downloaded and resolved separately from the compile and test classpaths. This keeps the agent's bundled dependencies (e.g., the bundled ByteBuddy classes) out of Gradle's compile and test dependency resolution, and it lets us reference the agent JAR by its exact file path in the `jvmArgs` of the `test` task (see [Section 3.1.4](#314-attach-agent-to-test-execution)). Note that this isolation only applies to build-time classpath resolution: at runtime, the `-javaagent` mechanism appends the agent JAR to the system classpath, so its bundled classes are still visible to the test JVM.
**Explanation:** This creates a new Gradle configuration named `aresAgent`. A Gradle configuration is a named bucket of dependencies that can be resolved independently; by creating a dedicated one for the agent, the agent JAR is downloaded and resolved separately from the compile and test classpaths, and it lets us reference the agent JAR by its exact file path in the `jvmArgs` of the `test` task (see [Section 3.1.4](#314-attach-agent-to-test-execution)). The agent JAR itself contains only Ares's own classes plus the `Premain-Class` manifest entry — it does not bundle Byte Buddy or any other dependency. Byte Buddy still reaches the instrumented JVM because `-javaagent` attaches to the *same* JVM that runs your tests, and that JVM's classpath already carries Byte Buddy transitively via the `testImplementation "de.tum.cit.ase:ares"` dependency declared in [Section 3.1.3](#313-add-ares-dependencies).

> **Note:** If your `build.gradle` already contains a `configurations` block, add the `aresAgent` configuration to that existing block instead of creating a new one.

Expand Down Expand Up @@ -126,7 +126,7 @@ dependencies {
> Then reference `libs.ares` and `libs.aspectjrt` in `build.gradle`. Note that Gradle version catalogs do not natively support Maven classifiers, so the `aresAgent` dependency with the `:agent` classifier must remain as a direct dependency string in `build.gradle`.

**Explanation:**
- `aresAgent "de.tum.cit.ase:ares:..."`: Downloads the Ares **agent** JAR (with classifier `agent`) into the custom `aresAgent` configuration. This JAR contains the ByteBuddy instrumentation agent with the correct `Premain-Class` manifest entry and all bundled dependencies (bundled under their original package names, without relocation).
- `aresAgent "de.tum.cit.ase:ares:..."`: Downloads the Ares **agent** JAR (with classifier `agent`) into the custom `aresAgent` configuration. This JAR contains only Ares's own instrumentation classes plus the correct `Premain-Class` manifest entry — it does **not** bundle Byte Buddy or any other dependency (Maven's shade-plugin `<artifactSet>` for this build only includes `de.tum.cit.ase:ares`). Byte Buddy is available to the instrumented JVM anyway, via the `testImplementation` dependency below, since `-javaagent` attaches to that same JVM rather than a separate one.
- `aresAgent 'org.aspectj:aspectjrt:...'`: Also adds the AspectJ runtime JAR to the `aresAgent` configuration so that it can be resolved in [Section 3.1.4](#314-attach-agent-to-test-execution) via `filter { it.name.contains('aspectjrt') }` for the `-Xbootclasspath/a:` JVM argument.
- `testImplementation`: Makes Ares classes available on the test classpath so your test code can use `@Policy`, `@Public`, and other Ares annotations. We use `testImplementation` instead of `implementation` because Ares is only needed during testing, not in the production code of the exercise. Using `implementation` would unnecessarily add Ares to the main classpath and the final artefact, which could interfere with student code and violates the principle of minimal dependency scope.
- `aspect "de.tum.cit.ase:ares:..."`: Registers the Ares JAR as an **aspect library** for the freefair AspectJ plugin. This is what makes `ajc` weave the binary aspects shipped inside the Ares JAR into your bytecode; a plain `testImplementation` dependency alone is not enough, because `ajc` only weaves aspects that are on the aspect path (see [Section 3.1.5](#315-how-compile-time-weaving-works)).
Expand Down Expand Up @@ -431,4 +431,4 @@ Run `./gradlew test` (or `mvn test`). If the test passes, the Ares dependency an
| **`--add-opens` / `--add-exports`** | JVM flags that grant access to internal Java modules. Required by Ares to instrument bytecode in `java.base`. |
| **`withinPath`** | The path to compiled student bytecode, relative to the build output directory. Differs between Gradle (`classes/java/main/...`) and Maven (`classes/...`). |
| **`ProgrammingLanguageConfiguration`** | An enum encoding the combination of build tool (Maven/Gradle), static analysis framework (ArchUnit/WALA), and runtime enforcement mechanism (AspectJ/Instrumentation). |
| **Classifier (`:agent`)** | A Maven/Gradle coordinate qualifier that selects a specific variant of an artefact. The `:agent` classifier selects the agent JAR (with bundled dependencies) carrying the `Premain-Class` manifest entry. |
| **Classifier (`:agent`)** | A Maven/Gradle coordinate qualifier that selects a specific variant of an artefact. The `:agent` classifier selects the agent JAR, which carries the `Premain-Class` manifest entry but does not bundle Byte Buddy or any other dependency — see [Section 3.1.2](#312-configure-ares-agent-configuration)'s explanation of why that's still sufficient. |
Loading
Loading