@@ -30,6 +30,7 @@ export class JreSetupManagerDependencies {
3030class JreSetupManager extends AsyncCreatable {
3131 private logger ! : Logger ;
3232 private config ! : Config ;
33+ private configFile : string ;
3334 private dependencies : JreSetupManagerDependencies ;
3435 private initialized : boolean ;
3536
@@ -40,6 +41,7 @@ class JreSetupManager extends AsyncCreatable {
4041 this . logger = await Logger . child ( 'verifyJRE' ) ;
4142
4243 this . config = await Controller . getConfig ( ) ;
44+ this . configFile = path . join ( Controller . getSfdxScannerPath ( ) , CONFIG_FILE )
4345 this . dependencies = new JreSetupManagerDependencies ( ) ;
4446
4547 this . initialized = true ;
@@ -80,7 +82,7 @@ class JreSetupManager extends AsyncCreatable {
8082 // So we'll just throw an error telling the user to set it themselves.
8183 if ( ! javaHome ) {
8284 const errName = 'NoJavaHomeFound' ;
83- throw new SfError ( getMessage ( BundleName . JreSetupManager , errName , [ ] ) , errName ) ;
85+ throw new SfError ( getMessage ( BundleName . JreSetupManager , errName , [ this . configFile ] ) , errName ) ;
8486 }
8587
8688 return javaHome ;
@@ -110,42 +112,50 @@ class JreSetupManager extends AsyncCreatable {
110112 } catch ( e ) {
111113 const error : NodeJS . ErrnoException = e as NodeJS . ErrnoException ;
112114 const errName = 'InvalidJavaHome' ;
113- throw new SfError ( getMessage ( BundleName . JreSetupManager , errName , [ javaHome , error . code ] ) , errName ) ;
115+ throw new SfError ( getMessage ( BundleName . JreSetupManager , errName , [ javaHome , error . code , this . configFile ] ) , errName ) ;
114116 }
115117 }
116118
117119 private async verifyJavaVersion ( javaHome : string ) : Promise < void > {
118- const versionOut = await this . fetchJavaVersion ( javaHome ) ;
119-
120- // Version output looks like this:
121- // MacOS: "openjdk version "11.0.6" 2020-01-14 LTS\nOpenJDK Runtime Environment Zulu11.37+17-CA (build 11.0.6+10-LTS)\nOpenJDK 64-Bit Server VM Zulu11.37+17-CA (build 11.0.6+10-LTS, mixed mode)\n"
122- // Win10: "openjdk 14 2020-03-17\r\nOpenJDK Runtime Environment (build 14+36-1461)\r\nOpenJDK 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)\r\n"
123- // We want to get the "11.0" or "14" part
124- // The version number could be of the format 11.0 or 1.8 or 14
125- const regex = / ( \d + ) ( \. ( \d + ) ) ? / ;
126- const matchedParts = regex . exec ( versionOut ) ;
127- this . logger . trace ( `Version output match for pattern ${ regex . toString ( ) } is ${ JSON . stringify ( matchedParts ) } ` ) ;
128-
129- // matchedParts should have four groups: "11.0", "11", ".0", "0" or "14", "14", undefined, undefined
130- if ( ! matchedParts || matchedParts . length < 4 ) {
131- throw new SfError ( getMessage ( BundleName . JreSetupManager , 'VersionNotFound' , [ ] ) ) ;
120+ const versionCommandOut = await this . fetchJavaVersion ( javaHome ) ;
121+
122+ // We are using "java -version" below which has output that typically looks like:
123+ // * (from MacOS): "openjdk version "11.0.6" 2020-01-14 LTS\nOpenJDK Runtime Environment Zulu11.37+17-CA (build 11.0.6+10-LTS)\nOpenJDK 64-Bit Server VM Zulu11.37+17-CA (build 11.0.6+10-LTS, mixed mode)\n"
124+ // From much research it should ideally say "version " and then either a number with or without quotes.
125+ // If instead we used java --version then the output would look something like:
126+ // * (from Win10): "openjdk 14 2020-03-17\r\nOpenJDK Runtime Environment (build 14+36-1461)\r\nOpenJDK 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)\r\n"
127+ // Notice it doesn't have the word "version" but again, we don't call "--version". But for sanity sakes,
128+ // we will attempt to support this as well. Basically we want to get the "11.0.6" or "14" part.
129+
130+ // First we'll see if the word "version" exists with the version number and use that first.
131+ const matchedParts = versionCommandOut . match ( / v e r s i o n \s + " ? ( \d + ( \. \d + ) * ) " ? / i) ;
132+ this . logger . trace ( `Attempt 1: Java version output match results is ${ JSON . stringify ( matchedParts ) } ` ) ;
133+ let version : string ;
134+ if ( matchedParts && matchedParts . length > 1 ) {
135+ version = matchedParts [ 1 ] ;
136+ } else {
137+ // Otherwise we'll try to get the version number the old way just be looking for the first number
138+ const matchedParts = versionCommandOut . match ( / \s + ( \d + ( \. \d + ) * ) / ) ;
139+ this . logger . trace ( `Attempt 2: Java version output match results is ${ JSON . stringify ( matchedParts ) } ` ) ;
140+ if ( ! matchedParts || matchedParts . length < 2 ) {
141+ throw new SfError ( getMessage ( BundleName . JreSetupManager , 'VersionNotFound' , [ this . configFile ] ) ) ;
142+ }
143+ version = matchedParts [ 1 ] ;
132144 }
133145
134- const majorVersion = parseInt ( matchedParts [ 1 ] ) ;
135- const minorVersion = matchedParts [ 3 ] ? parseInt ( matchedParts [ 3 ] ) : '' ;
136- const version = `${ majorVersion } ${ minorVersion ? `.${ minorVersion } ` : '' } ` ;
137-
138- // We want to allow 1.8 and greater.
139146 // Up to JDK8, the version scheme is 1.blah
140147 // Starting JDK 9, the version scheme is 9.blah for 9, 10.blah for 10, etc.
141- // If either version part clicks, we should be good.
148+ const versionParts : string [ ] = version . split ( '.' ) ;
149+ const majorVersion = parseInt ( versionParts [ 0 ] ) ;
150+ const minorVersion : number = versionParts . length > 1 ? parseInt ( versionParts [ 1 ] ) : 0 ;
151+
142152 if ( majorVersion === 1 && minorVersion === 8 ) {
143153 // Accommodating 1.8
144154 uxEvents . emit ( EVENTS . WARNING_ALWAYS_UNIQUE , getMessage ( BundleName . JreSetupManager , 'warning.JavaV8Deprecated' , [ path . join ( Controller . getSfdxScannerPath ( ) , CONFIG_FILE ) ] ) ) ;
145155 } else if ( majorVersion < 9 ) {
146156 // Not matching what we are looking for
147157 const errName = 'InvalidVersion' ;
148- throw new SfError ( getMessage ( BundleName . JreSetupManager , errName , [ version ] ) , errName ) ;
158+ throw new SfError ( getMessage ( BundleName . JreSetupManager , errName , [ version , this . configFile ] ) , errName ) ;
149159 }
150160
151161 this . logger . trace ( `Java version found as ${ version } ` ) ;
0 commit comments