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
2 changes: 1 addition & 1 deletion org.sonarlint.eclipse.buildship/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundle_name
Bundle-SymbolicName: org.sonarlint.eclipse.buildship;singleton:=true
Bundle-Version: 11.30.0.qualifier
Bundle-Version: 12.0.0.qualifier
Bundle-Vendor: %bundle_vendor
Bundle-ClassPath: .
Require-Bundle: org.eclipse.core.runtime,
Expand Down
2 changes: 1 addition & 1 deletion org.sonarlint.eclipse.buildship/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>org.sonarsource.sonarlint.eclipse</groupId>
<artifactId>sonarlint-eclipse-parent</artifactId>
<version>11.30.0-SNAPSHOT</version>
<version>12.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion org.sonarlint.eclipse.cdt/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundle_name
Bundle-SymbolicName: org.sonarlint.eclipse.cdt;singleton:=true
Bundle-Version: 11.30.0.qualifier
Bundle-Version: 12.0.0.qualifier
Bundle-Vendor: %bundle_vendor
Bundle-ClassPath: .
Require-Bundle: org.eclipse.core.runtime,
Expand Down
2 changes: 1 addition & 1 deletion org.sonarlint.eclipse.cdt/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>org.sonarsource.sonarlint.eclipse</groupId>
<artifactId>sonarlint-eclipse-parent</artifactId>
<version>11.30.0-SNAPSHOT</version>
<version>12.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion org.sonarlint.eclipse.core.tests/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: SonarLint for Eclipse Tests
Bundle-SymbolicName: org.sonarlint.eclipse.core.tests;singleton:=true
Bundle-Version: 11.30.0.qualifier
Bundle-Version: 12.0.0.qualifier
Bundle-Vendor: SonarSource
Require-Bundle: org.eclipse.core.resources,
org.eclipse.core.runtime,
Expand Down
2 changes: 1 addition & 1 deletion org.sonarlint.eclipse.core.tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>org.sonarsource.sonarlint.eclipse</groupId>
<artifactId>sonarlint-eclipse-parent</artifactId>
<version>11.30.0-SNAPSHOT</version>
<version>12.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.HashMap;
import java.util.List;
import org.eclipse.core.runtime.preferences.ConfigurationScope;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.junit.Before;
import org.junit.Test;
import org.osgi.service.prefs.BackingStoreException;
Expand All @@ -37,9 +38,12 @@

public class SonarLintGlobalConfigurationTest extends SonarTestCase {

private static final String OLD_JRE_KEY = "java17Path";

@Before
public void clean() throws BackingStoreException {
ConfigurationScope.INSTANCE.getNode(SonarLintCorePlugin.UI_PLUGIN_ID).clear();
InstanceScope.INSTANCE.getNode(SonarLintCorePlugin.UI_PLUGIN_ID).clear();
}

@Test
Expand Down Expand Up @@ -120,4 +124,59 @@ public void testRulesConfigSerializationRoundTrip() {
tuple("ruleWithParams", true, expectedParams));

}

@Test
public void migrate_old_key_from_workspace_scope() throws BackingStoreException {
var workspaceNode = InstanceScope.INSTANCE.getNode(SonarLintCorePlugin.UI_PLUGIN_ID);
workspaceNode.put(OLD_JRE_KEY, "/path/to/jre");

SonarLintGlobalConfiguration.migrateJrePathPreference();

assertThat(workspaceNode.get(SonarLintGlobalConfiguration.PREF_JRE_PATH, null)).isEqualTo("/path/to/jre");
assertThat(workspaceNode.get(OLD_JRE_KEY, null)).isNull();
}

@Test
public void migrate_old_key_from_application_scope() throws BackingStoreException {
var appNode = ConfigurationScope.INSTANCE.getNode(SonarLintCorePlugin.UI_PLUGIN_ID);
appNode.put(OLD_JRE_KEY, "/path/to/jre");

SonarLintGlobalConfiguration.migrateJrePathPreference();

assertThat(appNode.get(SonarLintGlobalConfiguration.PREF_JRE_PATH, null)).isEqualTo("/path/to/jre");
assertThat(appNode.get(OLD_JRE_KEY, null)).isNull();
}

@Test
public void do_not_migrate_when_old_key_is_absent() throws BackingStoreException {
SonarLintGlobalConfiguration.migrateJrePathPreference();

assertThat(InstanceScope.INSTANCE.getNode(SonarLintCorePlugin.UI_PLUGIN_ID).get(SonarLintGlobalConfiguration.PREF_JRE_PATH, null)).isNull();
assertThat(ConfigurationScope.INSTANCE.getNode(SonarLintCorePlugin.UI_PLUGIN_ID).get(SonarLintGlobalConfiguration.PREF_JRE_PATH, null)).isNull();
}

@Test
public void do_not_migrate_when_old_key_is_blank() throws BackingStoreException {
var workspaceNode = InstanceScope.INSTANCE.getNode(SonarLintCorePlugin.UI_PLUGIN_ID);
workspaceNode.put(OLD_JRE_KEY, " ");

SonarLintGlobalConfiguration.migrateJrePathPreference();

assertThat(workspaceNode.get(SonarLintGlobalConfiguration.PREF_JRE_PATH, null)).isNull();
}

@Test
public void migrate_both_scopes_independently() throws BackingStoreException {
var workspaceNode = InstanceScope.INSTANCE.getNode(SonarLintCorePlugin.UI_PLUGIN_ID);
var appNode = ConfigurationScope.INSTANCE.getNode(SonarLintCorePlugin.UI_PLUGIN_ID);
workspaceNode.put(OLD_JRE_KEY, "/workspace/jre");
appNode.put(OLD_JRE_KEY, "/app/jre");

SonarLintGlobalConfiguration.migrateJrePathPreference();

assertThat(workspaceNode.get(SonarLintGlobalConfiguration.PREF_JRE_PATH, null)).isEqualTo("/workspace/jre");
assertThat(workspaceNode.get(OLD_JRE_KEY, null)).isNull();
assertThat(appNode.get(SonarLintGlobalConfiguration.PREF_JRE_PATH, null)).isEqualTo("/app/jre");
assertThat(appNode.get(OLD_JRE_KEY, null)).isNull();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* SonarLint for Eclipse
* Copyright (C) 2015-2025 SonarSource Sàrl
* sonarlint@sonarsource.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonarlint.eclipse.core.internal.utils;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import static org.assertj.core.api.Assertions.assertThat;

public class JavaRuntimeUtilsTest {

@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();

@Test
public void returns_empty_when_release_file_is_absent() throws IOException {
var dir = temporaryFolder.newFolder().toPath();
assertThat(JavaRuntimeUtils.getJavaMajorVersion(dir)).isEmpty();
}

@Test
public void returns_empty_when_release_file_has_no_java_version_line() throws IOException {
var dir = releaseFileWith("OS_NAME=\"Linux\"\nOS_VERSION=\"5.15\"\n");
assertThat(JavaRuntimeUtils.getJavaMajorVersion(dir)).isEmpty();
}

@Test
public void returns_empty_when_version_string_is_malformed() throws IOException {
var dir = releaseFileWithVersion("not-a-version");
assertThat(JavaRuntimeUtils.getJavaMajorVersion(dir)).isEmpty();
}

@Test
public void parses_modern_version_with_patch() throws IOException {
assertThat(JavaRuntimeUtils.getJavaMajorVersion(releaseFileWithVersion("21.0.1"))).hasValue(21);
}

@Test
public void parses_modern_version_without_minor() throws IOException {
assertThat(JavaRuntimeUtils.getJavaMajorVersion(releaseFileWithVersion("21"))).hasValue(21);
}

@Test
public void parses_java_17() throws IOException {
assertThat(JavaRuntimeUtils.getJavaMajorVersion(releaseFileWithVersion("17.0.9"))).hasValue(17);
}

@Test
public void parses_java_11() throws IOException {
assertThat(JavaRuntimeUtils.getJavaMajorVersion(releaseFileWithVersion("11.0.22"))).hasValue(11);
}

@Test
public void parses_legacy_java_8_version_format() throws IOException {
assertThat(JavaRuntimeUtils.getJavaMajorVersion(releaseFileWithVersion("1.8.0_382"))).hasValue(8);
}

@Test
public void ignores_unrelated_lines_around_java_version() throws IOException {
var dir = releaseFileWith(
"OS_NAME=\"Linux\"\n"
+ "JAVA_VERSION=\"21.0.1\"\n"
+ "IMPLEMENTOR=\"Eclipse Adoptium\"\n"
+ "JAVA_RUNTIME_VERSION=\"21.0.1+12\"\n");
assertThat(JavaRuntimeUtils.getJavaMajorVersion(dir)).hasValue(21);
}

@Test
public void detects_java_executable_on_unix() throws IOException {
var dir = temporaryFolder.newFolder().toPath();
var bin = Files.createDirectory(dir.resolve("bin"));
Files.createFile(bin.resolve("java"));

assertThat(JavaRuntimeUtils.checkForJavaExecutable(dir)).isTrue();
}

@Test
public void returns_false_when_executable_is_missing() throws IOException {
var dir = temporaryFolder.newFolder().toPath();
Files.createDirectory(dir.resolve("bin"));

assertThat(JavaRuntimeUtils.checkForJavaExecutable(dir)).isFalse();
}

private Path releaseFileWithVersion(String version) throws IOException {
return releaseFileWith("JAVA_VERSION=\"" + version + "\"\n");
}

private Path releaseFileWith(String content) throws IOException {
var dir = temporaryFolder.newFolder().toPath();
Files.writeString(dir.resolve("release"), content);
return dir;
}
}
4 changes: 2 additions & 2 deletions org.sonarlint.eclipse.core/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundle_name
Bundle-SymbolicName: org.sonarlint.eclipse.core;singleton:=true
Bundle-Version: 11.30.0.qualifier
Bundle-Version: 12.0.0.qualifier
Bundle-ClassPath: .
Bundle-Activator: org.sonarlint.eclipse.core.internal.SonarLintCorePlugin
Bundle-Vendor: %bundle_vendor
Expand Down Expand Up @@ -43,6 +43,6 @@ Require-Bundle: org.eclipse.equinox.security;resolution:=optional,
org.eclipse.jdt.annotation;resolution:=optional,
org.eclipse.text,
org.eclipse.wildwebdeveloper.embedder.node;resolution:=optional,
org.sonarsource.sonarlint.core.sonarlint-java-client-osgi;bundle-version="[10.47.0,10.48.0)"
org.sonarsource.sonarlint.core.sonarlint-java-client-osgi;bundle-version="[11.0.0,11.1.0)"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-11
2 changes: 1 addition & 1 deletion org.sonarlint.eclipse.core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.sonarsource.sonarlint.eclipse</groupId>
<artifactId>sonarlint-eclipse-parent</artifactId>
<version>11.30.0-SNAPSHOT</version>
<version>12.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,17 @@ protected IStatus run(IProgressMonitor monitor) {
SonarLintGlobalConfiguration.issuesOnlyNewCode(),
new LanguageSpecificRequirements(new JsTsRequirementsDto(NodeJsService.getNodeJsPath(), null), null),
false,
null)).join();
null)).get(1, TimeUnit.MINUTES);
} catch (TimeoutException e) {
SonarLintLogger.get().error("Timed out waiting for SonarLint backend initialization after 1 minute", e);
throw new IllegalStateException("Timed out waiting for SonarLint backend initialization", e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
SonarLintLogger.get().error("Interrupted while waiting for SonarLint backend initialization", e);
throw new IllegalStateException("Interrupted while waiting for SonarLint backend initialization", e);
} catch (ExecutionException e) {
SonarLintLogger.get().error("Error during SonarQube for IDE backend initialization", e);
throw new IllegalStateException("Unable to initialize the SonarLint Backend", e);
} catch (IOException e) {
throw new IllegalStateException("Unable to initialize the SonarLint Backend", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public class SonarLintGlobalConfiguration {
public static final String PREF_TEST_FILE_GLOB_PATTERNS_DEFAULT = ""; //$NON-NLS-1$
public static final String PREF_SKIP_CONFIRM_ANALYZE_MULTIPLE_FILES = "skipConfirmAnalyzeMultipleFiles"; //$NON-NLS-1$
public static final String PREF_NODEJS_PATH = "nodeJsPath"; //$NON-NLS-1$
public static final String PREF_JAVA17_PATH = "java17Path"; //$NON-NLS-1$
public static final String PREF_JRE_PATH = "jrePath"; //$NON-NLS-1$
Comment thread
damien-urruty-sonarsource marked this conversation as resolved.
private static final String PREF_TAINT_VULNERABILITY_DISPLAYED = "taintVulnerabilityDisplayed";
private static final String PREF_SECRETS_EVER_DETECTED = "secretsEverDetected";
private static final String PREF_USER_SURVEY_LAST_LINK = "userSurveyLastLink"; //$NON-NLS-1$
Expand Down Expand Up @@ -129,12 +129,30 @@ private SonarLintGlobalConfiguration() {
};

public static void init() {
migrateJrePathPreference();
var rootNode = getApplicationLevelPreferenceNode();
rootNode.addPreferenceChangeListener(applicationRootNodeChangeListener);
rootNode = getWorkspaceLevelPreferenceNode();
rootNode.addPreferenceChangeListener(workspaceRootNodeChangeListener);
}

/** Migrate the Java runtime path preference from the old versioned key to the version-agnostic {@link #PREF_JRE_PATH} */
public static void migrateJrePathPreference() {
var oldKey = "java17Path";
for (var node : new IEclipsePreferences[] {getWorkspaceLevelPreferenceNode(), getApplicationLevelPreferenceNode()}) {
var oldValue = node.get(oldKey, null);
if (oldValue != null && !oldValue.isBlank()) {
node.put(PREF_JRE_PATH, oldValue);
node.remove(oldKey);
try {
node.flush();
} catch (BackingStoreException e) {
SonarLintLogger.get().error("Could not migrate Java runtime path preference", e);
}
}
}
}

public static void stop() {
var rootNode = getApplicationLevelPreferenceNode();
rootNode.removePreferenceChangeListener(applicationRootNodeChangeListener);
Expand Down Expand Up @@ -358,8 +376,8 @@ public static Path getNodejsPath() {
}

@Nullable
public static Path getJava17Path() {
return getPathFromPreference(PREF_JAVA17_PATH, "Invalid Java 17+ path");
public static Path getJrePath() {
return getPathFromPreference(PREF_JRE_PATH, "Invalid Java 21+ path");
}

@Nullable
Expand Down
Loading
Loading