Skip to content

Commit 7cb49fa

Browse files
committed
Further tighten up error checks for JVM detection
1 parent e6f3b7e commit 7cb49fa

File tree

1 file changed

+23
-14
lines changed

1 file changed

+23
-14
lines changed

src/interceptors/jvm.ts

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ import { ErrorLike } from '../util/error';
1313

1414
type JvmTarget = { pid: string, name: string, interceptedByProxy: number | undefined };
1515

16-
const OLD_JAVA_MISSING_ATTACH_CLASS = 'com/sun/tools/attach/AgentLoadException';
17-
const MISSING_ATTACH_LIB_MESSAGE = 'java.lang.UnsatisfiedLinkError: no attach in java.library.path';
18-
const JRE_NOT_JDK_MESSAGE = 'Are we running in a JRE instead of a JDK';
19-
2016
// Check that Java is present, and that it's compatible with agent attachment:
2117
const javaBinPromise: Promise<string | false> = (async () => {
2218
// Check what Java binaries might exist:
@@ -73,16 +69,16 @@ const javaBinPromise: Promise<string | false> = (async () => {
7369
// The most common reason for this is that outdated Java versions (most notably Java 8) don't include
7470
// the necessary APIs to attach to remote JVMs. That's inconvenient, but unavoidable & not unusual.
7571
// Fortunately, I think most active Java developers do have a recent version of Java installed.
76-
const unusualJavaErrors = javaTestResults.filter(({ output }) =>
77-
// Not caused by a known normal not-supported-in-your-env error:
78-
![
79-
MISSING_ATTACH_LIB_MESSAGE, OLD_JAVA_MISSING_ATTACH_CLASS, JRE_NOT_JDK_MESSAGE
80-
].some(knownError =>
81-
output.stderr.includes(knownError) || output.stdout.includes(knownError)
82-
) &&
83-
// And not caused by ENOENT for an invalid Java path:
84-
!('spawnError' in output && output.spawnError.code === 'ENOENT')
85-
);
72+
const unusualJavaErrors = javaTestResults.filter(({ output }) => {
73+
const outputText = output.stderr + '\n' + output.stdout;
74+
75+
// Ignore any errors that we know definitely aren't recoverable/aren't our problem:
76+
return !hasUnsupportedJvmError(outputText) && // Not caused by a known incompatible JVM issue
77+
!hasJvmOomError(outputText) && // Not caused by a simple OOM
78+
!hasBrokenJvmError(outputText) && // Not a corrupted JVM
79+
// And not caused by ENOENT for an invalid Java path:
80+
!('spawnError' in output && output.spawnError.code === 'ENOENT')
81+
});
8682

8783
if (unusualJavaErrors.length === 0) {
8884
console.warn('=> Java attach APIs are not available');
@@ -129,6 +125,19 @@ function testJavaBin(possibleJavaBin: string) {
129125
]);
130126
}
131127

128+
const hasUnsupportedJvmError = (testOutput: string) =>
129+
testOutput.includes('com/sun/tools/attach/AgentLoadException') || // Old Java missing Attach classes
130+
testOutput.includes('java.lang.UnsatisfiedLinkError: no attach in java.library.path') || // Similar
131+
testOutput.includes('Are we running in a JRE instead of a JDK') || // JREs aren't sufficient
132+
testOutput.includes('Unsupported major.minor version 52.0'); // Pre Java 8(!)
133+
134+
const hasBrokenJvmError = (testOutput: string) =>
135+
testOutput.includes('jvm.cfg'); // Somehow it seems that JVMs 'lose' this file and can't start?
136+
137+
const hasJvmOomError = (testOutput: string) =>
138+
testOutput.includes('insufficient memory') ||
139+
testOutput.includes('Could not reserve enough space for object heap');
140+
132141
export class JvmInterceptor implements Interceptor {
133142
readonly id = 'attach-jvm';
134143
readonly version = '1.0.1';

0 commit comments

Comments
 (0)