Skip to content

Commit 9fd4a6b

Browse files
committed
Add agent arguments to be passed to the java agent. Fixes #3
1 parent e21f5f2 commit 9fd4a6b

File tree

9 files changed

+76
-10
lines changed

9 files changed

+76
-10
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,12 @@ Note that in this case, the agent dependency is actually added under the `provid
6060

6161
If the *compile* scope is not enabled, then the agent dependency is put under a special `javaagent` configuration so that it doesn't appear as a regular library dependency or on build classpaths.
6262

63+
## Agent arguments
64+
65+
A Java agent can have an extra argument string added to it that is provided to the `premain` method in the agent. To add an argument string simply provide it to the `JavaAgent` constructor.
66+
67+
```scala
68+
javaAgents += JavaAgent("com.example" % "agent" % "1.2.3" % "compile;test", arguments = "java_agent_argument_string")
69+
```
70+
6371
[sbt-native-packager]: https://github.com/sbt/sbt-native-packager
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
package maxwell;
22

33
import java.lang.instrument.Instrumentation;
4+
import java.util.regex.Pattern;
45

56
public class Maxwell {
67
public static void premain(String agentArgs, Instrumentation instrumentation) {
7-
System.out.println("Agent 86");
8+
String[] output = new String[] { "Agent 86" };
9+
if (agentArgs != null) {
10+
output = agentArgs.split(Pattern.quote(";"));
11+
}
12+
for (String string: output)
13+
System.out.println(string);
814
}
915
}

src/main/scala/com/lightbend/sbt/javaagent/JavaAgent.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ object JavaAgent extends AutoPlugin {
2727

2828
case class AgentScope(compile: Boolean = false, test: Boolean = false, run: Boolean = false, dist: Boolean = true)
2929

30-
case class AgentModule(name: String, module: ModuleID, scope: AgentScope)
30+
case class AgentModule(name: String, module: ModuleID, scope: AgentScope, arguments: String)
3131

3232
case class ResolvedAgent(agent: AgentModule, artifact: File)
3333

@@ -40,8 +40,9 @@ object JavaAgent extends AutoPlugin {
4040
* Create an agent module from a module dependency.
4141
* Scope is also derived from the given module configuration.
4242
*/
43-
def apply(module: ModuleID, name: String = null, scope: AgentScope = AgentScope()): AgentModule = {
43+
def apply(module: ModuleID, name: String = null, scope: AgentScope = AgentScope(), arguments: String = null): AgentModule = {
4444
val agentName = Option(name).getOrElse(module.name)
45+
val agentArguments = Option(arguments).map("=" + _).getOrElse("")
4546
val confs = module.configurations.toSeq.flatMap(_.split(";"))
4647
val inCompile = scope.compile || confs.contains(Compile.name) || confs.contains(Provided.name)
4748
val inRun = scope.run || inCompile || confs.contains(Runtime.name)
@@ -50,7 +51,7 @@ object JavaAgent extends AutoPlugin {
5051
val configuration = if (inCompile) Provided else AgentConfig
5152
val reconfiguredModule = module.copy(configurations = Some(configuration.name))
5253
val configuredScope = AgentScope(compile = inCompile, test = inTest, run = inRun, dist = inDist)
53-
AgentModule(agentName, reconfiguredModule, configuredScope)
54+
AgentModule(agentName, reconfiguredModule, configuredScope, agentArguments)
5455
}
5556

5657
override def requires = plugins.JvmPlugin
@@ -87,8 +88,8 @@ object JavaAgent extends AutoPlugin {
8788
}
8889

8990
private def agentOptions(enabled: ResolvedAgent => Boolean) = Def.task[Seq[String]] {
90-
resolvedJavaAgents.value filter enabled map { agent =>
91-
"-javaagent:" + agent.artifact.absolutePath
91+
resolvedJavaAgents.value filter enabled map { resolved =>
92+
"-javaagent:" + resolved.artifact.absolutePath + resolved.agent.arguments
9293
}
9394
}
9495

src/main/scala/com/lightbend/sbt/javaagent/JavaAgentPackaging.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,21 @@ object JavaAgentPackaging extends AutoPlugin {
2121
override def requires = JavaAgent && PluginRef("com.typesafe.sbt.packager.archetypes.JavaAppPackaging")
2222

2323
override def projectSettings = Seq(
24-
mappings in Universal ++= agentMappings.value,
24+
mappings in Universal ++= agentMappings.value.map(m => m._1 -> m._2),
2525
bashScriptExtraDefines ++= agentScriptOptions.value
2626
)
2727

28-
private def agentMappings = Def.task[Seq[(File, String)]] {
28+
private def agentMappings = Def.task[Seq[(File, String, String)]] {
2929
resolvedJavaAgents.value filter (_.agent.scope.dist) map { resolved =>
30-
resolved.artifact -> (Project.normalizeModuleID(resolved.agent.name) + File.separator + resolved.artifact.name)
30+
(resolved.artifact,
31+
Project.normalizeModuleID(resolved.agent.name) + File.separator + resolved.artifact.name,
32+
resolved.agent.arguments)
3133
}
3234
}
3335

3436
private def agentScriptOptions = Def.task[Seq[String]] {
3537
agentMappings.value map {
36-
case (_, path) => s"""addJava "-javaagent:$${app_home}/../${normalizePath(path)}" """
38+
case (_, path, arguments) => s"""addJava "-javaagent:$${app_home}/../${normalizePath(path)}$arguments" """
3739
}
3840
}
3941

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
lazy val agentOptions = project in file(".") enablePlugins (JavaAgent, JavaAppPackaging)
2+
3+
javaAgents += JavaAgent(module = "sbt.javaagent.test" % "maxwell" % sys.props("project.version") % "dist;test",
4+
arguments = "Get_Smart;Agent_99")
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
addSbtPlugin("com.lightbend.sbt" % "sbt-javaagent" % sys.props("project.version"))
2+
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % sys.props("packager.version"))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
object Main extends App

src/sbt-test/agent/arguments/test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
> stage
2+
> check

src/sbt-test/agent/arguments/test.sbt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
TaskKey[Unit]("check") := {
2+
assert(
3+
(fork in Test).value,
4+
"fork in Test is not enabled"
5+
)
6+
7+
assert(
8+
(javaOptions in Test).value exists (s => s.contains("-javaagent:") && s.contains("maxwell")),
9+
"javaOptions in Test do not contain 'maxwell' agent"
10+
)
11+
12+
assert(
13+
(javaOptions in Test).value exists (s => s.contains("-javaagent:") && s.contains("maxwell") && s.contains("=Get_Smart;Agent_99")),
14+
"javaOptions in Test do not contain 'Get_Smart;Agent_99' agent arguments"
15+
)
16+
17+
assert(
18+
(mappings in Universal).value exists { case (file, path) => path == "maxwell/maxwell.jar" },
19+
"dist mappings do not include 'maxwell/maxwell.jar'"
20+
)
21+
22+
val output = ((stagingDirectory in Universal).value / "bin" / packageName.value).absolutePath.!!
23+
24+
assert(
25+
!(output contains "Agent 86"),
26+
"output includes 'Agent 86'"
27+
)
28+
assert(
29+
!(output contains ";"),
30+
"output includes ';'"
31+
)
32+
assert(
33+
output contains "Get_Smart",
34+
"output does not include 'Get_Smart'"
35+
)
36+
assert(
37+
output contains "Agent_99",
38+
"output does not include 'Agent_99'"
39+
)
40+
}

0 commit comments

Comments
 (0)