Skip to content

Commit 8c7105d

Browse files
authored
SCANJLIB-276 Allow to use a local Scanner Engine
1 parent a5551f3 commit 8c7105d

File tree

11 files changed

+89
-27
lines changed

11 files changed

+89
-27
lines changed

lib/src/main/java/org/sonarsource/scanner/lib/ScannerProperties.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ private ScannerProperties() {
103103
*/
104104
public static final String JAVA_EXECUTABLE_PATH = "sonar.scanner.javaExePath";
105105

106+
/**
107+
* Path of the Scanner Engine JAR to be used.
108+
*/
109+
public static final String SCANNER_ENGINE_JAR_PATH = "sonar.scanner.engineJarPath";
110+
106111
/**
107112
* Flag to skip the JRE provisioning.
108113
*/

lib/src/main/java/org/sonarsource/scanner/lib/internal/cache/CachedFile.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@
2020
package org.sonarsource.scanner.lib.internal.cache;
2121

2222
import java.nio.file.Path;
23+
import javax.annotation.CheckForNull;
24+
import javax.annotation.Nullable;
2325

2426
public class CachedFile {
2527

2628
private final Path pathInCache;
27-
private final boolean cacheHit;
29+
private final Boolean cacheHit;
2830

29-
public CachedFile(Path pathInCache, boolean cacheHit) {
31+
public CachedFile(Path pathInCache, @Nullable Boolean cacheHit) {
3032
this.pathInCache = pathInCache;
3133
this.cacheHit = cacheHit;
3234
}
@@ -35,7 +37,8 @@ public Path getPathInCache() {
3537
return pathInCache;
3638
}
3739

38-
public boolean isCacheHit() {
40+
@CheckForNull
41+
public Boolean getCacheHit() {
3942
return cacheHit;
4043
}
4144
}

lib/src/main/java/org/sonarsource/scanner/lib/internal/facade/AbstractScannerEngineFacade.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ public abstract class AbstractScannerEngineFacade implements ScannerEngineFacade
3030
private final Map<String, String> bootstrapProperties;
3131
private final boolean isSonarQubeCloud;
3232
private final String serverVersion;
33-
private final boolean wasEngineCacheHit;
33+
private final Boolean wasEngineCacheHit;
3434
private final JreCacheHit wasJreCacheHit;
3535

3636
protected AbstractScannerEngineFacade(Map<String, String> bootstrapProperties, boolean isSonarQubeCloud, @Nullable String serverVersion,
37-
boolean wasEngineCacheHit, @Nullable JreCacheHit wasJreCacheHit) {
37+
@Nullable Boolean wasEngineCacheHit, @Nullable JreCacheHit wasJreCacheHit) {
3838
this.bootstrapProperties = bootstrapProperties;
3939
this.isSonarQubeCloud = isSonarQubeCloud;
4040
this.serverVersion = serverVersion;
@@ -69,7 +69,9 @@ private void addStatsProperties(Map<String, String> allProps) {
6969
if (wasJreCacheHit != null) {
7070
allProps.put("sonar.scanner.wasJreCacheHit", wasJreCacheHit.name());
7171
}
72-
allProps.put("sonar.scanner.wasEngineCacheHit", String.valueOf(wasEngineCacheHit));
72+
if (wasEngineCacheHit != null) {
73+
allProps.put("sonar.scanner.wasEngineCacheHit", String.valueOf(wasEngineCacheHit));
74+
}
7375
}
7476

7577
protected abstract boolean doAnalyze(Map<String, String> allProps);

lib/src/main/java/org/sonarsource/scanner/lib/internal/facade/forked/JavaRunnerFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public JavaRunner createRunner(ScannerHttpClient scannerHttpClient, FileCache fi
8686
} else {
8787
var cachedFile = getJreFromServer(scannerHttpClient, fileCache, properties, true);
8888
if (cachedFile.isPresent()) {
89-
return new JavaRunner(cachedFile.get().getPathInCache(), cachedFile.get().isCacheHit() ? JreCacheHit.HIT : JreCacheHit.MISS);
89+
return new JavaRunner(cachedFile.get().getPathInCache(), Boolean.TRUE.equals(cachedFile.get().getCacheHit()) ? JreCacheHit.HIT : JreCacheHit.MISS);
9090
}
9191
}
9292
String javaHome = system.getEnvironmentVariable("JAVA_HOME");
@@ -145,7 +145,7 @@ private static Optional<CachedFile> getJreFromServer(ScannerHttpClient scannerHt
145145
var cachedFile = fileCache.getOrDownload(jreMetadata.get().getFilename(), jreMetadata.get().getSha256(), "SHA-256",
146146
new JreDownloader(scannerHttpClient, jreMetadata.get()));
147147
var extractedDirectory = extractArchive(cachedFile.getPathInCache());
148-
return Optional.of(new CachedFile(extractedDirectory.resolve(jreMetadata.get().javaPath), cachedFile.isCacheHit()));
148+
return Optional.of(new CachedFile(extractedDirectory.resolve(jreMetadata.get().javaPath), cachedFile.getCacheHit()));
149149
} catch (HashMismatchException e) {
150150
if (retry) {
151151
// A new JRE might have been published between the metadata fetch and the download

lib/src/main/java/org/sonarsource/scanner/lib/internal/facade/forked/NewScannerEngineFacade.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class NewScannerEngineFacade extends AbstractScannerEngineFacade {
2828

2929
private NewScannerEngineFacade(Map<String, String> bootstrapProperties, ScannerEngineLauncher launcher,
3030
boolean isSonarQubeCloud, @Nullable String serverVersion) {
31-
super(bootstrapProperties, isSonarQubeCloud, serverVersion, launcher.isEngineCacheHit(), launcher.getJreCacheHit());
31+
super(bootstrapProperties, isSonarQubeCloud, serverVersion, launcher.getEngineCacheHit(), launcher.getJreCacheHit());
3232
this.launcher = launcher;
3333
}
3434

lib/src/main/java/org/sonarsource/scanner/lib/internal/facade/forked/ScannerEngineLauncher.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.util.Optional;
3232
import java.util.Set;
3333
import java.util.stream.Collectors;
34+
import javax.annotation.CheckForNull;
3435
import org.slf4j.Logger;
3536
import org.slf4j.LoggerFactory;
3637
import org.sonarsource.scanner.lib.ScannerProperties;
@@ -156,8 +157,9 @@ private static String buildJsonProperties(Map<String, String> properties) {
156157
return new Gson().toJson(jsonObject);
157158
}
158159

159-
public boolean isEngineCacheHit() {
160-
return scannerEngineJar.isCacheHit();
160+
@CheckForNull
161+
public Boolean getEngineCacheHit() {
162+
return scannerEngineJar.getCacheHit();
161163
}
162164

163165
public JreCacheHit getJreCacheHit() {

lib/src/main/java/org/sonarsource/scanner/lib/internal/facade/forked/ScannerEngineLauncherFactory.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,25 @@
2121

2222
import com.google.gson.Gson;
2323
import java.io.IOException;
24+
import java.nio.file.Files;
2425
import java.nio.file.Path;
26+
import java.nio.file.Paths;
2527
import java.util.Collections;
2628
import java.util.Map;
2729
import javax.annotation.Nullable;
2830
import org.apache.commons.lang3.StringUtils;
2931
import org.slf4j.Logger;
3032
import org.slf4j.LoggerFactory;
33+
import org.sonarsource.scanner.lib.internal.MessageException;
3134
import org.sonarsource.scanner.lib.internal.cache.CachedFile;
3235
import org.sonarsource.scanner.lib.internal.cache.FileCache;
3336
import org.sonarsource.scanner.lib.internal.cache.HashMismatchException;
3437
import org.sonarsource.scanner.lib.internal.http.ScannerHttpClient;
3538
import org.sonarsource.scanner.lib.internal.util.ProcessWrapperFactory;
3639
import org.sonarsource.scanner.lib.internal.util.System2;
3740

41+
import static org.sonarsource.scanner.lib.ScannerProperties.SCANNER_ENGINE_JAR_PATH;
42+
3843
public class ScannerEngineLauncherFactory {
3944

4045
private static final Logger LOG = LoggerFactory.getLogger(ScannerEngineLauncherFactory.class);
@@ -53,15 +58,28 @@ public ScannerEngineLauncherFactory(System2 system) {
5358
public ScannerEngineLauncher createLauncher(ScannerHttpClient scannerHttpClient, FileCache fileCache, Map<String, String> properties) {
5459
JavaRunner javaRunner = javaRunnerFactory.createRunner(scannerHttpClient, fileCache, properties);
5560
jreSanityCheck(javaRunner);
56-
var scannerEngine = getScannerEngine(scannerHttpClient, fileCache, true);
61+
var scannerEngine = getScannerEngine(scannerHttpClient, fileCache, properties);
5762
return new ScannerEngineLauncher(javaRunner, scannerEngine);
5863
}
5964

6065
private static void jreSanityCheck(JavaRunner javaRunner) {
6166
javaRunner.execute(Collections.singletonList("--version"), null, LOG::debug);
6267
}
6368

64-
private static CachedFile getScannerEngine(ScannerHttpClient scannerHttpClient, FileCache fileCache, boolean retry) {
69+
private static CachedFile getScannerEngine(ScannerHttpClient scannerHttpClient, FileCache fileCache, Map<String, String> properties) {
70+
String scannerEngineJarPathPropValue = properties.get(SCANNER_ENGINE_JAR_PATH);
71+
if (scannerEngineJarPathPropValue != null) {
72+
var path = Paths.get(scannerEngineJarPathPropValue).toAbsolutePath();
73+
if (!Files.isRegularFile(path)) {
74+
throw new MessageException("Scanner Engine jar path '" + scannerEngineJarPathPropValue + "' does not exist. Please check property '" + SCANNER_ENGINE_JAR_PATH + "'.");
75+
}
76+
LOG.info("Using the configured Scanner Engine '{}'", path);
77+
return new CachedFile(path, null);
78+
}
79+
return provisionScannerEngine(scannerHttpClient, fileCache, true);
80+
}
81+
82+
private static CachedFile provisionScannerEngine(ScannerHttpClient scannerHttpClient, FileCache fileCache, boolean retry) {
6583
try {
6684
var scannerEngineMetadata = getScannerEngineMetadata(scannerHttpClient);
6785
return fileCache.getOrDownload(scannerEngineMetadata.getFilename(), scannerEngineMetadata.getSha256(), "SHA-256",
@@ -70,7 +88,7 @@ private static CachedFile getScannerEngine(ScannerHttpClient scannerHttpClient,
7088
if (retry) {
7189
// A new scanner-engine might have been published between the metadata fetch and the download
7290
LOG.warn("Failed to get the scanner-engine, retrying...");
73-
return getScannerEngine(scannerHttpClient, fileCache, false);
91+
return provisionScannerEngine(scannerHttpClient, fileCache, false);
7492
}
7593
throw e;
7694
}
@@ -81,7 +99,7 @@ private static ScannerEngineMetadata getScannerEngineMetadata(ScannerHttpClient
8199
String response = scannerHttpClient.callRestApi(API_PATH_ENGINE);
82100
return new Gson().fromJson(response, ScannerEngineMetadata.class);
83101
} catch (Exception e) {
84-
throw new IllegalStateException("Failed to get the scanner-engine metadata", e);
102+
throw new MessageException("Failed to get the scanner-engine metadata: " + e.getMessage(), e);
85103
}
86104
}
87105

lib/src/main/java/org/sonarsource/scanner/lib/internal/facade/inprocess/IsolatedLauncherFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ IsolatedLauncherAndClassloader createLauncher(final LegacyScannerEngineDownloade
7777
IsolatedLauncher objProxy = IsolatedLauncherProxy.create(cl, IsolatedLauncher.class, launcherImplClassName);
7878
tempCleaning.clean();
7979

80-
return new IsolatedLauncherAndClassloader(objProxy, cl, jarFiles.stream().allMatch(CachedFile::isCacheHit));
80+
return new IsolatedLauncherAndClassloader(objProxy, cl, jarFiles.stream().allMatch(CachedFile::getCacheHit));
8181
} catch (Exception e) {
8282
// Catch all other exceptions, which relates to reflection
8383
throw new ScannerException("Unable to execute SonarScanner analysis", e);

lib/src/main/java/org/sonarsource/scanner/lib/internal/facade/simulation/SimulationScannerEngineFacade.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class SimulationScannerEngineFacade extends AbstractScannerEngineFacade {
4040

4141
public SimulationScannerEngineFacade(Map<String, String> bootstrapProperties, boolean isSonarCloud,
4242
@Nullable String serverVersion) {
43-
super(bootstrapProperties, isSonarCloud, serverVersion, false, null);
43+
super(bootstrapProperties, isSonarCloud, serverVersion, null, null);
4444
}
4545

4646
@Override

lib/src/test/java/org/sonarsource/scanner/lib/internal/cache/FileCacheTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,14 @@ public void download(String filename, Path toFile) throws IOException {
126126
.hasFileName("sonar-foo-plugin-1.5.jar");
127127
assertThat(cachedFile.getPathInCache().getParent()).hasParent(cache.getDir());
128128
assertThat(read(cachedFile.getPathInCache())).isEqualTo("body");
129-
assertThat(cachedFile.isCacheHit()).isFalse();
129+
assertThat(cachedFile.getCacheHit()).isFalse();
130130

131131
var againFromCache = cache.getOrDownload("sonar-foo-plugin-1.5.jar", "ABCDE", HASH_ALGO, downloader);
132132
assertThat(againFromCache.getPathInCache()).isRegularFile()
133133
.hasFileName("sonar-foo-plugin-1.5.jar");
134134
assertThat(againFromCache.getPathInCache().getParent()).hasParent(cache.getDir());
135135
assertThat(read(againFromCache.getPathInCache())).isEqualTo("body");
136-
assertThat(againFromCache.isCacheHit()).isTrue();
136+
assertThat(againFromCache.getCacheHit()).isTrue();
137137
}
138138

139139
@Test

0 commit comments

Comments
 (0)