Skip to content

Commit

Permalink
feat: support earlier transformation as -javaagent
Browse files Browse the repository at this point in the history
Signed-off-by: Joke de Buhr <joke@xckk.de>
  • Loading branch information
joke committed Nov 6, 2022
1 parent d6f6027 commit 84b4fd5
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 1 deletion.
7 changes: 7 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ image:https://badgen.net/github/release/joke/spock-mockable/stable[]
dependencies {
testImplementation 'io.github.joke:spock-mockable:x.y.z'
}
// to load the agent even earlier add it as a JVM argument
tasks.withType(Test) {
jvmArgs += ["-javaagent:${classpath.find { it.name.contains('spock-mockable') }.absolutePath}"]
}
----

=== Maven
Expand Down Expand Up @@ -119,6 +124,8 @@ At the start of a test JVM these detected classes are transformed by the JVM ins
regardless of the actual specification there the mock invocation has been detected.
This might lead to unexpected behaviour between different specifications.

For the earliest possible transformation of classes start the agent by using the JVM argument (`-javaagent`).

IMPORTANT: For agent instrumentation to work the JVM must support this feature. A JRE is most likely not sufficient.

IMPORTANT: The agent is attached to the JVM as early as possible but some classes not be transformed nevertheless because they are used prior. This restriction applies to some `java.lang` classes but also to some junit classes.
Expand Down
10 changes: 10 additions & 0 deletions spock-mockable/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ shadowJar {
minimize()
}

jar {
manifest {
attributes(
'Can-Redefine-Classes': 'true',
'Can-Retransform-Classes': 'true',
'Premain-Class': 'io.github.joke.spockmockable.agent.AgentInstaller',
)
}
}

publishing {
publications {
spockMockable(MavenPublication) { publication ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import javax.inject.Singleton;
import java.lang.instrument.Instrumentation;
import java.util.Optional;

import static java.lang.Boolean.parseBoolean;
import static java.lang.System.getProperty;
Expand All @@ -20,10 +21,19 @@
@Component(modules = AgentInstaller.Module.class)
public abstract class AgentInstaller {

@Nullable
private static Instrumentation instrumentation;

@SuppressWarnings("SameNameButDifferent")
@Getter(value = PRIVATE, lazy = true, onMethod_ = @Nullable)
private static final AgentInstaller agentInstaller = DaggerAgentInstaller.create().init();

@SuppressWarnings("DoNotCallSuggester")
public static void premain(String agentArgs, Instrumentation instrumentation) {
AgentInstaller.instrumentation = instrumentation;
install();
}

@Synchronized
public static void install() {
getAgentInstaller();
Expand Down Expand Up @@ -57,7 +67,8 @@ interface Module {
@Provides
@Singleton
static Instrumentation getInstrumentation() {
return ByteBuddyAgent.install();
return Optional.ofNullable(AgentInstaller.instrumentation)
.orElseGet(ByteBuddyAgent::install);
}

}
Expand Down

0 comments on commit 84b4fd5

Please sign in to comment.