Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions src/main/java/org/sonarqube/gradle/ProjectProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,6 @@ public class ProjectProperties {
public final Boolean isRootProject;
public final List<String> compileClasspath;
public final List<String> testCompileClasspath;

/**
* Currently libraries field are only populated for Android projects. For other projects, the
* SonarPropertyComputer populates these fields with just the runtime Jars. Ultimately we should use
* the SonarResolverTask to compute everything and remove that logic from SonarPropertyComputer.
*/
public final List<String> mainLibraries;
public final List<String> testLibraries;

Expand Down
57 changes: 4 additions & 53 deletions src/main/java/org/sonarqube/gradle/SonarPropertyComputer.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@

import static java.util.stream.Collectors.groupingBy;
import static org.sonarqube.gradle.SonarUtils.appendProp;
import static org.sonarqube.gradle.SonarUtils.appendProps;
import static org.sonarqube.gradle.SonarUtils.computeReportPaths;
import static org.sonarqube.gradle.SonarUtils.exists;
import static org.sonarqube.gradle.SonarUtils.findProjectBaseDir;
import static org.sonarqube.gradle.SonarUtils.getSourceSets;
import static org.sonarqube.gradle.SonarUtils.isAndroidProject;
import static org.sonarqube.gradle.SonarUtils.nonEmptyOrNull;
import static org.sonarqube.gradle.SonarUtils.setMainClasspathProps;
import static org.sonarqube.gradle.SonarUtils.setTestClasspathProps;
import static org.sonarqube.gradle.SonarUtils.setMainBinariesProps;

public class SonarPropertyComputer {
private static final Logger LOGGER = Logging.getLogger(SonarPropertyComputer.class);
Expand Down Expand Up @@ -456,13 +456,11 @@ private static void configureJavaClasspath(Project project, Map<String, Object>
SourceSetContainer sourceSets = getSourceSets(project);
SourceSet main = sourceSets.getAt("main");
Collection<File> mainClassDirs = getJavaOutputDirs(main);
Collection<File> mainLibraries = getRuntimeJars();
setMainClasspathProps(properties, mainClassDirs, mainLibraries, addForGroovy);
setMainBinariesProps(properties, mainClassDirs, addForGroovy);

SourceSet test = sourceSets.getAt("test");
Collection<File> testClassDirs = getJavaOutputDirs(test);
Collection<File> testLibraries = getRuntimeJars();
setTestClasspathProps(properties, testClassDirs, testLibraries);
appendProps(properties, "sonar.java.test.binaries", exists(testClassDirs));
}

private static @Nullable Collection<File> getJavaSourceFiles(SourceSet sourceSet) {
Expand Down Expand Up @@ -522,53 +520,6 @@ private static InternalKotlinSourceSet of(Object rawSourceSet) {
}
}

/**
* Returns the collection of Java and Java FX runtime jars, if available.
*/
private static Collection<File> getRuntimeJars() {
List<File> libraries = new ArrayList<>(2);

File runtimeJar = getRuntimeJar();
if (runtimeJar != null) {
libraries.add(runtimeJar);
}

File fxRuntimeJar = getFxRuntimeJar();
if (fxRuntimeJar != null) {
libraries.add(fxRuntimeJar);
}

return libraries;
}

private static File getRuntimeJar() {
try {
final File javaBase = new File(System.getProperty("java.home")).getCanonicalFile();
File runtimeJar = new File(javaBase, "lib/rt.jar");
if (runtimeJar.exists()) {
return runtimeJar;
}
runtimeJar = new File(javaBase, "jre/lib/rt.jar");
return runtimeJar.exists() ? runtimeJar : null;
} catch (IOException e) {
throw new IllegalStateException(e);
}
}

private static File getFxRuntimeJar() {
try {
final File javaBase = new File(System.getProperty("java.home")).getCanonicalFile();
File runtimeJar = new File(javaBase, "lib/ext/jfxrt.jar");
if (runtimeJar.exists()) {
return runtimeJar;
}
runtimeJar = new File(javaBase, "jre/lib/ext/jfxrt.jar");
return runtimeJar.exists() ? runtimeJar : null;
} catch (IOException e) {
throw new IllegalStateException(e);
}
}

private void addGradleDefaults(final Project project, final Map<String, Object> properties) {
properties.put("sonar.projectName", project.getName());
properties.put("sonar.projectDescription", project.getDescription());
Expand Down
11 changes: 9 additions & 2 deletions src/main/java/org/sonarqube/gradle/SonarQubePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,10 @@ private static List<File> registerAndConfigureResolverTasks(Project topLevelProj
FileCollection testClassPath = getTestClassPath(target);
task.setTestCompileClasspath(testClassPath);

// Currently we only use the SonarResolverTask for Android projects to resolve libraries. Other projects use
// the SonarPropertyComputer, but ultimately the SonarResolverTask should be used for all project types.
if (isAndroidProject(target)) {
setAndroidLibrariesProperties(target, task);
} else {
setJavaLibrariesProperties(target, task);
}

DirectoryProperty buildDirectory = target.getLayout().getBuildDirectory();
Expand All @@ -146,6 +146,13 @@ private static void setAndroidLibrariesProperties(Project target, SonarResolverT
task.setTestLibraries(libraries.getTestLibraries().stream().reduce(target.files(), FileCollection::plus));
}

private static void setJavaLibrariesProperties(Project target, SonarResolverTask task) {
Collection<File> runtimeJars = SonarUtils.getRuntimeJars();
FileCollection libraries = target.files(runtimeJars);
task.setMainLibraries(libraries);
task.setTestLibraries(libraries);
}

private static Class<? extends SonarResolverTask> getCompatibleTaskType(GradleVersion version) {
if (version.compareTo(GradleVersion.version("8.5.0")) >= 0) {
return BuildFeaturesEnabledResolverTask.class;
Expand Down
43 changes: 33 additions & 10 deletions src/main/java/org/sonarqube/gradle/SonarUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.sonarqube.gradle;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
Expand All @@ -29,10 +30,12 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import javax.annotation.Nullable;
import org.gradle.api.Project;
Expand Down Expand Up @@ -187,22 +190,13 @@ static String findProjectBaseDir(Map<String, Object> properties) {
return rootBaseDir.toString();
}

static void setTestClasspathProps(Map<String, Object> properties, Collection<File> testClassDirs, Collection<File> testLibraries) {
appendProps(properties, "sonar.java.test.binaries", exists(testClassDirs));
appendProps(properties, "sonar.java.test.libraries", exists(testLibraries));
}

static void setMainClasspathProps(Map<String, Object> properties, Collection<File> mainClassDirs, Collection<File> mainLibraries, boolean addForGroovy) {
static void setMainBinariesProps(Map<String, Object> properties, Collection<File> mainClassDirs, boolean addForGroovy) {
appendProps(properties, "sonar.java.binaries", exists(mainClassDirs));
if (addForGroovy) {
appendProps(properties, "sonar.groovy.binaries", exists(mainClassDirs));
}
// Populate deprecated properties for backward compatibility
appendProps(properties, "sonar.binaries", exists(mainClassDirs));

appendProps(properties, "sonar.java.libraries", exists(mainLibraries));
// Populate deprecated properties for backward compatibility
appendProps(properties, "sonar.libraries", exists(mainLibraries));
}

static void populateJdkProperties(Map<String, Object> properties, JavaCompilerConfiguration config) {
Expand Down Expand Up @@ -414,4 +408,33 @@ public static String constructPrefixedProjectName(String projectPath) {
return result.toString();
}

/**
* Returns the collection of Java and Java FX runtime jars, if available.
*/
public static Collection<File> getRuntimeJars() {
try {
return Stream.of(getRuntimeJar(), getFxRuntimeJar()).filter(Objects::nonNull).collect(Collectors.toList());
} catch (IOException e) {
throw new IllegalStateException(e);
}
}

@Nullable
private static File getRuntimeJar() throws IOException {
final File javaBase = new File(System.getProperty("java.home")).getCanonicalFile();
return Stream.of(new File(javaBase, "lib/rt.jar"), new File(javaBase, "jre/lib/rt.jar"))
.filter(File::exists)
.findFirst()
.orElse(null);
}

@Nullable
private static File getFxRuntimeJar() throws IOException {
final File javaBase = new File(System.getProperty("java.home")).getCanonicalFile();
return Stream.of(new File(javaBase, "lib/ext/jfxrt.jar"), new File(javaBase, "jre/lib/ext/jfxrt.jar"))
.filter(File::exists)
.findFirst()
.orElse(null);
}

}
14 changes: 14 additions & 0 deletions src/test/java/org/sonarqube/gradle/SonarUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.mockito.Mockito;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.when;

class SonarUtilsTest {
Expand Down Expand Up @@ -89,4 +90,17 @@ void test_join_csv_without_duplicates(){
assertThat(SonarUtils.joinCsvStringsWithoutDuplicates(a, e)).isEqualTo("a,b,c");
}

@Test
void test_getRuntimeJars_throws_IllegalStateException_when_java_home_is_invalid() {
String originalJavaHome = System.getProperty("java.home");
try {
// Set java.home to a path with null character, which will cause an exception in getCanonicalFile()
System.setProperty("java.home", "/invalid\u0000path");
assertThatThrownBy(SonarUtils::getRuntimeJars)
.isInstanceOf(IllegalStateException.class);
} finally {
System.setProperty("java.home", originalJavaHome);
}
}

}
Loading