3333import org .apache .commons .lang3 .StringUtils ;
3434import org .slf4j .Logger ;
3535import org .slf4j .LoggerFactory ;
36- import org .sonarsource .scanner .lib .internal .ArchResolver ;
36+ import org .sonarsource .scanner .lib .internal .FailedBootstrap ;
3737import org .sonarsource .scanner .lib .internal .InternalProperties ;
38- import org .sonarsource .scanner .lib .internal .IsolatedLauncherFactory ;
39- import org .sonarsource .scanner .lib .internal .OsResolver ;
40- import org .sonarsource .scanner .lib .internal .Paths2 ;
41- import org .sonarsource .scanner .lib .internal .ScannerEngineLauncherFactory ;
38+ import org .sonarsource .scanner .lib .internal .MessageException ;
39+ import org .sonarsource .scanner .lib .internal .SuccessfulBootstrap ;
4240import org .sonarsource .scanner .lib .internal .cache .FileCache ;
41+ import org .sonarsource .scanner .lib .internal .facade .forked .NewScannerEngineFacade ;
42+ import org .sonarsource .scanner .lib .internal .facade .forked .ScannerEngineLauncherFactory ;
43+ import org .sonarsource .scanner .lib .internal .facade .inprocess .InProcessScannerEngineFacade ;
44+ import org .sonarsource .scanner .lib .internal .facade .inprocess .IsolatedLauncherFactory ;
45+ import org .sonarsource .scanner .lib .internal .facade .simulation .SimulationScannerEngineFacade ;
4346import org .sonarsource .scanner .lib .internal .http .HttpConfig ;
47+ import org .sonarsource .scanner .lib .internal .http .HttpException ;
4448import org .sonarsource .scanner .lib .internal .http .ScannerHttpClient ;
4549import org .sonarsource .scanner .lib .internal .http .ssl .CertificateStore ;
50+ import org .sonarsource .scanner .lib .internal .util .ArchResolver ;
51+ import org .sonarsource .scanner .lib .internal .util .OsResolver ;
52+ import org .sonarsource .scanner .lib .internal .util .Paths2 ;
53+ import org .sonarsource .scanner .lib .internal .util .System2 ;
4654import org .sonarsource .scanner .lib .internal .util .VersionUtils ;
4755
4856import static java .util .Optional .ofNullable ;
@@ -107,10 +115,7 @@ public ScannerEngineBootstrapper setBootstrapProperty(String key, String value)
107115 return this ;
108116 }
109117
110- /**
111- * Bootstrap the scanner-engine.
112- */
113- public ScannerEngineFacade bootstrap () {
118+ public ScannerEngineBootstrapResult bootstrap () {
114119 if (LOG .isDebugEnabled ()) {
115120 LOG .debug ("Scanner max available memory: {}" , FileUtils .byteCountToDisplaySize (Runtime .getRuntime ().maxMemory ()));
116121 }
@@ -121,22 +126,59 @@ public ScannerEngineFacade bootstrap() {
121126 var isSimulation = immutableProperties .containsKey (InternalProperties .SCANNER_DUMP_TO_FILE );
122127 var sonarUserHome = resolveSonarUserHome (immutableProperties );
123128 var fileCache = FileCache .create (sonarUserHome );
124- var httpConfig = new HttpConfig (immutableProperties , sonarUserHome );
125- scannerHttpClient .init (httpConfig );
126- String serverVersion = null ;
127- if (!isSonarCloud ) {
128- serverVersion = getServerVersion (scannerHttpClient , isSimulation , immutableProperties );
129- }
130129
131130 if (isSimulation ) {
132- return new SimulationScannerEngineFacade (immutableProperties , isSonarCloud , serverVersion );
133- } else if (isSonarCloud || VersionUtils .isAtLeastIgnoringQualifier (serverVersion , SQ_VERSION_NEW_BOOTSTRAPPING )) {
134- var launcher = scannerEngineLauncherFactory .createLauncher (scannerHttpClient , fileCache , immutableProperties );
135- return new NewScannerEngineFacade (immutableProperties , launcher , isSonarCloud , serverVersion );
131+ var serverVersion = immutableProperties .getOrDefault (InternalProperties .SCANNER_VERSION_SIMULATION , "9.9" );
132+ return new SuccessfulBootstrap (new SimulationScannerEngineFacade (immutableProperties , isSonarCloud , serverVersion ));
133+ }
134+
135+ // No HTTP call should be made before this point
136+ try {
137+ var httpConfig = new HttpConfig (immutableProperties , sonarUserHome );
138+ scannerHttpClient .init (httpConfig );
139+
140+ var serverVersion = !isSonarCloud ? getServerVersion (scannerHttpClient ) : null ;
141+ if (isSonarCloud || VersionUtils .isAtLeastIgnoringQualifier (serverVersion , SQ_VERSION_NEW_BOOTSTRAPPING )) {
142+ var launcher = scannerEngineLauncherFactory .createLauncher (scannerHttpClient , fileCache , immutableProperties );
143+ return new SuccessfulBootstrap (new NewScannerEngineFacade (immutableProperties , launcher , isSonarCloud , serverVersion ));
144+ } else {
145+ var launcher = launcherFactory .createLauncher (scannerHttpClient , fileCache );
146+ var adaptedProperties = adaptDeprecatedPropertiesForInProcessBootstrapping (immutableProperties , httpConfig );
147+ return new SuccessfulBootstrap (new InProcessScannerEngineFacade (adaptedProperties , launcher , false , serverVersion ));
148+ }
149+ } catch (MessageException e ) {
150+ return handleException (e );
151+ }
152+ }
153+
154+ private static ScannerEngineBootstrapResult handleException (MessageException e ) {
155+ var message = new StringBuilder (e .getMessage ());
156+ if (e .getCause () instanceof HttpException ) {
157+ var httpEx = (HttpException ) e .getCause ();
158+ var code = httpEx .getCode ();
159+ if (code == 401 || code == 403 ) {
160+ var helpMessage = "Please check the property " + ScannerProperties .SONAR_TOKEN +
161+ " or the environment variable " + EnvironmentConfig .TOKEN_ENV_VARIABLE + "." ;
162+ message .append (". " ).append (helpMessage );
163+ }
164+ if (code == 407 ) {
165+ var helpMessage = "Please check the properties " + ScannerProperties .SONAR_SCANNER_PROXY_USER +
166+ " and " + ScannerProperties .SONAR_SCANNER_PROXY_PASSWORD + "." ;
167+ message .append (". " ).append (helpMessage );
168+ }
169+ }
170+ logWithStacktraceOnlyIfDebug (message .toString (), e );
171+ return new FailedBootstrap ();
172+ }
173+
174+ /**
175+ * For functional errors, the stacktrace is not necessary. It is only useful for debugging.
176+ */
177+ private static void logWithStacktraceOnlyIfDebug (String message , Throwable t ) {
178+ if (LOG .isDebugEnabled ()) {
179+ LOG .error (message , t );
136180 } else {
137- var launcher = launcherFactory .createLauncher (scannerHttpClient , fileCache );
138- var adaptedProperties = adaptDeprecatedPropertiesForInProcessBootstrapping (immutableProperties , httpConfig );
139- return new InProcessScannerEngineFacade (adaptedProperties , launcher , false , serverVersion );
181+ LOG .error (message );
140182 }
141183 }
142184
@@ -191,20 +233,21 @@ private static Path resolveSonarUserHome(Map<String, String> properties) {
191233 return Paths .get (sonarUserHome );
192234 }
193235
194- private static String getServerVersion (ScannerHttpClient scannerHttpClient , boolean isSimulation , Map <String , String > properties ) {
195- if (isSimulation ) {
196- return properties .getOrDefault (InternalProperties .SCANNER_VERSION_SIMULATION , "5.6" );
197- }
198-
236+ private static String getServerVersion (ScannerHttpClient scannerHttpClient ) {
199237 try {
200238 return scannerHttpClient .callRestApi ("/analysis/version" );
201239 } catch (Exception e ) {
202- try {
203- return scannerHttpClient .callWebApi ("/api/server/version" );
204- } catch (Exception e2 ) {
205- var ex = new IllegalStateException ("Failed to get server version" , e2 );
206- ex .addSuppressed (e );
207- throw ex ;
240+ if (e instanceof HttpException && ((HttpException ) e ).getCode () == 404 ) {
241+ // Fallback to the old endpoint
242+ try {
243+ return scannerHttpClient .callWebApi ("/api/server/version" );
244+ } catch (Exception e2 ) {
245+ var ex = new MessageException ("Failed to query server version: " + e2 .getMessage (), e2 );
246+ ex .addSuppressed (e );
247+ throw ex ;
248+ }
249+ } else {
250+ throw new MessageException ("Failed to query server version: " + e .getMessage (), e );
208251 }
209252 }
210253 }
0 commit comments