Skip to content

Commit 0cb14e3

Browse files
committed
Clearly fail when VM scanning isn't available
It appears that in some environments (JRE 15 on Windows, at least) you can try to scan, but it just always returns an empty list. Since it'll never normally be an empty list, we need to clearly and loudly fail if that happens, so we know scanning isn't available.
1 parent c8fc394 commit 0cb14e3

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

src/main/kotlin/tech/httptoolkit/javaagent/AttachMain.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,20 @@ fun main(args: Array<String>) {
2828
// This isn't guaranteed to work everywhere, but it should work in most places:
2929
val (pid) = ManagementFactory.getRuntimeMXBean().name.split("@")
3030

31+
val vms = VirtualMachine.list()
32+
if (vms.isEmpty()) {
33+
// VMs should never be empty, because at the very least _we_ should be in there! If it's empty then
34+
// scanning isn't working at all, and we should fail clearly.
35+
System.err.println("Can't scan for attachable JVMs. Are we running in a JRE instead of a JDK?")
36+
exitProcess(4)
37+
}
3138

32-
VirtualMachine.list().forEach { vmd ->
39+
vms.forEach { vmd ->
3340
if (vmd.id() != pid) {
3441
println("${vmd.id()}:${vmd.displayName()}")
3542
}
3643
}
44+
3745
exitProcess(0)
3846
} else if (args.size != 4) {
3947
System.err.println("Usage: java -jar <agent.jar> <target-PID> <proxyHost> <proxyPort> <path-to-certificate>")
@@ -63,4 +71,4 @@ fun main(args: Array<String>) {
6371
exitProcess(3)
6472
}
6573
}
66-
}
74+
}

src/test/kotlin/IntegrationTests.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import io.kotest.core.spec.style.StringSpec
77
import io.kotest.core.test.TestCase
88
import io.kotest.core.test.TestResult
99
import io.kotest.matchers.shouldBe
10+
import io.kotest.matchers.string.shouldNotBeEmpty
11+
import java.io.BufferedReader
1012
import java.lang.Thread.sleep
1113
import java.nio.file.Path
1214
import java.nio.file.Paths
@@ -40,6 +42,24 @@ val wireMockServer = WireMockServer(options()
4042
val runningProcs = arrayListOf<Process>()
4143

4244
class IntegrationTests : StringSpec({
45+
"Launching with list-targets should return successfully" {
46+
val proc = ProcessBuilder(
47+
javaPath,
48+
"-jar", AGENT_JAR_PATH,
49+
"list-targets"
50+
).start()
51+
runningProcs.add(proc)
52+
val outputReader = proc.inputStream.bufferedReader()
53+
54+
proc.waitFor(10, TimeUnit.SECONDS)
55+
56+
val output = outputReader.use(BufferedReader::readText)
57+
output.shouldNotBeEmpty()
58+
59+
proc.isAlive.shouldBe(false)
60+
proc.exitValue().shouldBe(0)
61+
}
62+
4363
"Launching with -javaagent should intercept all clients" {
4464

4565
val agentArgs = "$proxyHost|${wireMockServer.port()}|$certPath"

0 commit comments

Comments
 (0)