From 3ccd65380a64b5c583ed67159702a50a73ff6096 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Mon, 3 Mar 2025 08:30:27 +0100 Subject: [PATCH] IJPL-162853 move JavaVersion to `intellij.platform.util.kmp` and extract `current()` method to JVM-only part GitOrigin-RevId: 1eaa07494ff64fe8a30932d655ac7c1caccd5f53 --- .../uiDesigner/core/GridBagConverterTest.java | 4 +- .../uiDesigner/core/TextAreasTest.java | 4 +- .../impl/JavaAwareProjectJdkTableImpl.java | 4 +- .../daemon/JavadocHtmlLintInspectionTest.kt | 4 +- .../jps/incremental/java/JavaBuilder.java | 7 +- .../jps/model/JdkVersionDetectorTest.kt | 3 +- .../build/impl/compilation/CompiledClasses.kt | 6 +- .../com/intellij/idea/SystemHealthMonitor.kt | 6 +- .../fus/os/SystemRuntimeCollector.kt | 4 +- .../vfs/impl/local/NativeFileWatcherImpl.java | 4 +- .../src/com/intellij/util/JdkBundle.java | 2 +- .../execution/GeneralCommandLineTest.java | 4 +- .../vfs/local/LocalFileSystemTest.java | 6 +- .../platform/testFramework/io/DnsMock.kt | 4 +- .../testFramework/PlatformTestUtil.java | 3 +- .../intellij/util/lang/UrlClassLoader.java | 4 +- platform/util/api-dump-unreviewed.txt | 20 +- platform/util/kmp/api-dump.txt | 32 ++ .../src/com/intellij/util/JavaVersionShim.kt | 10 + .../src/com/intellij/util/lang/JavaVersion.kt | 301 ++++++++++++++++ .../com/intellij/util/JavaVersionJvm.kt | 48 +++ platform/util/src/com/intellij/Patches.java | 4 +- .../execution/process/UnixProcessManager.java | 4 +- .../execution/process/WinProcessManager.java | 4 +- .../openapi/application/ClassPathUtil.kt | 4 +- .../com/intellij/util/CurrentJavaVersion.kt | 13 + .../com/intellij/util/io/ByteBufferUtil.java | 6 +- .../com/intellij/util/lang/JavaVersion.java | 328 ------------------ .../util/lang/test/JavaVersionTest.kt | 3 +- .../test/UrlClassLoaderSplitPackageTest.kt | 1 + .../importing/GradleImportingTestCase.java | 6 +- .../incremental/groovy/InProcessGroovyc.java | 7 +- .../incremental/groovy/JpsGroovycRunner.java | 6 +- .../IdeaDecompilerPerformanceTest.kt | 4 +- .../javaFX/sceneBuilder/SceneBuilderImpl.java | 4 +- .../sceneBuilder/SceneBuilderEditor.java | 6 +- .../AbstractLocalInspectionTest.kt | 4 +- 37 files changed, 474 insertions(+), 410 deletions(-) create mode 100644 platform/util/kmp/src/com/intellij/util/JavaVersionShim.kt create mode 100644 platform/util/kmp/src/com/intellij/util/lang/JavaVersion.kt create mode 100644 platform/util/kmp/srcJvm/com/intellij/util/JavaVersionJvm.kt create mode 100644 platform/util/src/com/intellij/util/CurrentJavaVersion.kt delete mode 100644 platform/util/src/com/intellij/util/lang/JavaVersion.java diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GridBagConverterTest.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GridBagConverterTest.java index 36deb66da344..7f22f0afc799 100644 --- a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GridBagConverterTest.java +++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GridBagConverterTest.java @@ -2,7 +2,7 @@ package com.intellij.uiDesigner.core; import com.intellij.uiDesigner.compiler.GridBagConverter; -import com.intellij.util.lang.JavaVersion; +import com.intellij.util.CurrentJavaVersion; import junit.framework.TestCase; import javax.swing.*; @@ -518,7 +518,7 @@ public class GridBagConverterTest extends TestCase { applyConversionResults(panel, converter); - int textAreaWidth = JavaVersion.current().feature >= 9 ? 101 : 100; + int textAreaWidth = CurrentJavaVersion.currentJavaVersion().feature >= 9 ? 101 : 100; assertEquals(textAreaWidth, textArea.getPreferredSize().width); diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/TextAreasTest.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/TextAreasTest.java index b8b8b7450b9a..283d84883370 100644 --- a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/TextAreasTest.java +++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/TextAreasTest.java @@ -15,7 +15,7 @@ */ package com.intellij.uiDesigner.core; -import com.intellij.util.lang.JavaVersion; +import com.intellij.util.CurrentJavaVersion; import junit.framework.TestCase; import javax.swing.*; @@ -50,7 +50,7 @@ public final class TextAreasTest extends TestCase { panel.doLayout(); - int textAreaWidth = JavaVersion.current().feature >= 9 ? 101 : 100; + int textAreaWidth = CurrentJavaVersion.currentJavaVersion().feature >= 9 ? 101 : 100; assertFalse(UIManager.getLookAndFeel().getName().equals("Windows")); // This check fails for Windows LaF due to its default TextArea settings, so it's not expected here. By default it's Metal on Windows. diff --git a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaAwareProjectJdkTableImpl.java b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaAwareProjectJdkTableImpl.java index 2118354aba69..5827b7b7bfae 100644 --- a/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaAwareProjectJdkTableImpl.java +++ b/java/java-impl/src/com/intellij/openapi/projectRoots/impl/JavaAwareProjectJdkTableImpl.java @@ -9,9 +9,9 @@ import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.projectRoots.*; +import com.intellij.util.CurrentJavaVersion; import com.intellij.util.SystemProperties; import com.intellij.util.concurrency.annotations.RequiresEdt; -import com.intellij.util.lang.JavaVersion; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; @@ -79,7 +79,7 @@ public final class JavaAwareProjectJdkTableImpl extends ProjectJdkTableImpl { } } - String versionName = JdkVersionDetector.formatVersionString(JavaVersion.current()); + String versionName = JdkVersionDetector.formatVersionString(CurrentJavaVersion.currentJavaVersion()); myInternalJdk = JavaSdk.getInstance().createJdk(versionName, javaHome.toAbsolutePath().toString(), !JdkUtil.checkForJdk(javaHome)); } return myInternalJdk; diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/JavadocHtmlLintInspectionTest.kt b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/JavadocHtmlLintInspectionTest.kt index 94ec475ba9e5..3917d49e6aae 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/JavadocHtmlLintInspectionTest.kt +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/JavadocHtmlLintInspectionTest.kt @@ -10,14 +10,14 @@ import com.intellij.testFramework.IdeaTestUtil import com.intellij.testFramework.LightProjectDescriptor import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase -import com.intellij.util.lang.JavaVersion +import com.intellij.util.currentJavaVersion import java.io.File private val DESCRIPTOR = object : DefaultLightProjectDescriptor() { override fun getSdk(): Sdk { val jreHome = File(System.getProperty("java.home")) val jdkHome = if (jreHome.name == "jre") jreHome.parentFile else jreHome - return IdeaTestUtil.createMockJdk("java version \"{${JavaVersion.current()}}\"", jdkHome.path) + return IdeaTestUtil.createMockJdk("java version \"{${currentJavaVersion()}}\"", jdkHome.path) } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 90560f21de4e..86e65945cec9 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -10,6 +10,7 @@ import com.intellij.openapi.util.io.FileFilters; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.Strings; +import com.intellij.util.CurrentJavaVersion; import com.intellij.util.ExceptionUtil; import com.intellij.util.concurrency.Semaphore; import com.intellij.util.containers.FileCollectionFactory; @@ -453,7 +454,7 @@ public final class JavaBuilder extends ModuleLevelBuilder { forkSdk = null; } - final int compilerSdkVersion = forkSdk == null ? JavaVersion.current().feature : forkSdk.getSecond(); + final int compilerSdkVersion = forkSdk == null ? CurrentJavaVersion.currentJavaVersion().feature : forkSdk.getSecond(); final Pair, Iterable> vm_compilerOptions = getCompilationOptions(compilerSdkVersion, context, chunk, profile, compilingTool); final Iterable vmOptions = vm_compilerOptions.first; @@ -698,7 +699,7 @@ public final class JavaBuilder extends ModuleLevelBuilder { if (!isJavac(compilingTool)) { return false; // applicable to javac only } - final int compilerSdkVersion = JavaVersion.current().feature; + final int compilerSdkVersion = CurrentJavaVersion.currentJavaVersion().feature; if (preferTargetJdkCompiler(context)) { final Pair, Integer> sdkVersionPair = getAssociatedSdk(chunk); @@ -972,7 +973,7 @@ public final class JavaBuilder extends ModuleLevelBuilder { } public static void addCompilationOptions(List options, CompileContext context, ModuleChunk chunk, @Nullable ProcessorConfigProfile profile) { - addCompilationOptions(JavaVersion.current().feature, JavaBuilderUtil.findCompilingTool(JavacCompilerTool.ID), options, context, chunk, profile, false); + addCompilationOptions(CurrentJavaVersion.currentJavaVersion().feature, JavaBuilderUtil.findCompilingTool(JavacCompilerTool.ID), options, context, chunk, profile, false); } private static void addCompilationOptions( diff --git a/jps/model-impl/testSrc/org/jetbrains/jps/model/JdkVersionDetectorTest.kt b/jps/model-impl/testSrc/org/jetbrains/jps/model/JdkVersionDetectorTest.kt index cb8fb359f751..e957864278d4 100644 --- a/jps/model-impl/testSrc/org/jetbrains/jps/model/JdkVersionDetectorTest.kt +++ b/jps/model-impl/testSrc/org/jetbrains/jps/model/JdkVersionDetectorTest.kt @@ -3,6 +3,7 @@ package org.jetbrains.jps.model import com.intellij.openapi.util.SystemInfoRt import com.intellij.util.SystemProperties +import com.intellij.util.currentJavaVersion import com.intellij.util.lang.JavaVersion import com.intellij.util.system.CpuArch import org.assertj.core.api.Assertions.assertThat @@ -13,7 +14,7 @@ class JdkVersionDetectorTest { @Test fun detectJdkVersion() { val jdkHome = SystemProperties.getJavaHome() val jdkVersion = JdkVersionDetector.getInstance().detectJdkVersionInfo(jdkHome) - assertThat(jdkVersion?.version?.trim()).isEqualTo(JavaVersion.current().trim()) + assertThat(jdkVersion?.version?.trim()).isEqualTo(currentJavaVersion().trim()) assertThat(jdkVersion?.arch).isEqualTo(CpuArch.CURRENT) if (SystemInfoRt.isMac && jdkHome.endsWith("/Contents/Home")) { diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/compilation/CompiledClasses.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/compilation/CompiledClasses.kt index 1c750e43247f..4baf173a2cce 100644 --- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/compilation/CompiledClasses.kt +++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/compilation/CompiledClasses.kt @@ -3,7 +3,7 @@ package org.jetbrains.intellij.build.impl.compilation import com.intellij.openapi.util.io.NioFiles import com.intellij.util.io.Decompressor -import com.intellij.util.lang.JavaVersion +import com.intellij.util.currentJavaVersion import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.trace.Span @@ -209,8 +209,8 @@ internal suspend fun doCompile( context: CompilationContext, handleCompilationFailureBeforeRetry: (suspend (successMessage: String) -> String)?, ) { - check(JavaVersion.current().isAtLeast(17)) { - "Build script must be executed under Java 17 to compile intellij project but it's executed under Java ${JavaVersion.current()}" + check(currentJavaVersion().isAtLeast(17)) { + "Build script must be executed under Java 17 to compile intellij project but it's executed under Java ${currentJavaVersion()}" } check(isCompilationRequired(context.options)) { "Unexpected compilation request, unable to proceed" diff --git a/platform/platform-impl/bootstrap/src/com/intellij/idea/SystemHealthMonitor.kt b/platform/platform-impl/bootstrap/src/com/intellij/idea/SystemHealthMonitor.kt index b60f6a9d470f..4c055acc7f57 100644 --- a/platform/platform-impl/bootstrap/src/com/intellij/idea/SystemHealthMonitor.kt +++ b/platform/platform-impl/bootstrap/src/com/intellij/idea/SystemHealthMonitor.kt @@ -37,7 +37,7 @@ import com.intellij.platform.ide.progress.ModalTaskOwner import com.intellij.platform.ide.progress.TaskCancellation import com.intellij.platform.ide.progress.runWithModalProgressBlocking import com.intellij.util.SystemProperties -import com.intellij.util.lang.JavaVersion +import com.intellij.util.currentJavaVersion import com.intellij.util.system.CpuArch import com.intellij.util.ui.IoErrorText import kotlinx.coroutines.* @@ -180,7 +180,7 @@ internal object SystemHealthMonitor { } jreHome = jreHome.removeSuffix("/Contents/Home") showNotification("bundled.jre.version.message", suppressable = false, switchAction, - JavaVersion.current(), System.getProperty("java.vendor"), jreHome) + currentJavaVersion(), System.getProperty("java.vendor"), jreHome) } // when can't detect a JBR version, give a user the benefit of the doubt @@ -191,7 +191,7 @@ internal object SystemHealthMonitor { // when can't detect a JBR version, give a user the benefit of the doubt val jbrVersion = JdkVersionDetector.getInstance().detectJdkVersionInfo(PathManager.getBundledRuntimePath()) - return jbrVersion == null || JavaVersion.current() >= jbrVersion.version + return jbrVersion == null || currentJavaVersion() >= jbrVersion.version } private suspend fun isJbrOperational(): Boolean { diff --git a/platform/platform-impl/internal/src/com/intellij/internal/statistic/collectors/fus/os/SystemRuntimeCollector.kt b/platform/platform-impl/internal/src/com/intellij/internal/statistic/collectors/fus/os/SystemRuntimeCollector.kt index fe20ea4cdbf9..d33806fd2fa6 100644 --- a/platform/platform-impl/internal/src/com/intellij/internal/statistic/collectors/fus/os/SystemRuntimeCollector.kt +++ b/platform/platform-impl/internal/src/com/intellij/internal/statistic/collectors/fus/os/SystemRuntimeCollector.kt @@ -19,7 +19,7 @@ import com.intellij.internal.statistic.utils.StatisticsUtil import com.intellij.openapi.application.PathManager import com.intellij.openapi.util.SystemInfo import com.intellij.openapi.util.Version -import com.intellij.util.lang.JavaVersion +import com.intellij.util.currentJavaVersion import com.intellij.util.system.CpuArch import com.intellij.util.ui.UIUtil import com.sun.management.OperatingSystemMXBean @@ -90,7 +90,7 @@ class SystemRuntimeCollector : ApplicationUsagesCollector() { if (SystemInfo.isMac) result += RENDERING.metric(getRenderingPipelineName()) result += JVM.metric( - Version(1, JavaVersion.current().feature, 0), + Version(1, currentJavaVersion().feature, 0), CpuArch.CURRENT.name.lowercase(Locale.ENGLISH), getJavaVendor()) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/NativeFileWatcherImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/NativeFileWatcherImpl.java index 8ffbe5232791..3d32bbb089e9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/NativeFileWatcherImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/NativeFileWatcherImpl.java @@ -18,11 +18,11 @@ import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.openapi.vfs.local.FileWatcherNotificationSink; import com.intellij.openapi.vfs.local.PluggableFileWatcher; import com.intellij.openapi.vfs.newvfs.ManagingFS; +import com.intellij.util.CurrentJavaVersion; import com.intellij.util.SmartList; import com.intellij.util.TimeoutUtil; import com.intellij.util.io.BaseDataReader; import com.intellij.util.io.BaseOutputReader; -import com.intellij.util.lang.JavaVersion; import com.intellij.util.system.CpuArch; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -312,7 +312,7 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher { @ReviseWhenPortedToJDK(value = "21", description = "drop normalization") private final class MyProcessHandler extends OSProcessHandler { private final BufferedWriter myWriter; - private final boolean myNormalizePaths = SystemInfo.isMac && !JavaVersion.current().isAtLeast(21); + private final boolean myNormalizePaths = SystemInfo.isMac && !CurrentJavaVersion.currentJavaVersion().isAtLeast(21); private WatcherOp myLastOp; private final List myLines = new ArrayList<>(); diff --git a/platform/platform-impl/src/com/intellij/util/JdkBundle.java b/platform/platform-impl/src/com/intellij/util/JdkBundle.java index 3c6d6d08720a..ee1993aea731 100644 --- a/platform/platform-impl/src/com/intellij/util/JdkBundle.java +++ b/platform/platform-impl/src/com/intellij/util/JdkBundle.java @@ -136,7 +136,7 @@ public final class JdkBundle { JdkVersionInfo versionInfo; if (boot) { - versionInfo = new JdkVersionInfo(JavaVersion.current(), null, CpuArch.CURRENT, null); + versionInfo = new JdkVersionInfo(CurrentJavaVersion.currentJavaVersion(), null, CpuArch.CURRENT, null); } else { versionInfo = JdkVersionDetector.getInstance().detectJdkVersionInfo(actualHome.getPath()); diff --git a/platform/platform-tests/testSrc/com/intellij/execution/GeneralCommandLineTest.java b/platform/platform-tests/testSrc/com/intellij/execution/GeneralCommandLineTest.java index bd0ce43bc7d8..7bf7cacd8a8d 100644 --- a/platform/platform-tests/testSrc/com/intellij/execution/GeneralCommandLineTest.java +++ b/platform/platform-tests/testSrc/com/intellij/execution/GeneralCommandLineTest.java @@ -17,7 +17,7 @@ import com.intellij.openapi.util.io.NioFiles; import com.intellij.openapi.util.text.StringUtil; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.rules.TempDirectory; -import com.intellij.util.lang.JavaVersion; +import com.intellij.util.CurrentJavaVersion; import org.assertj.core.api.Assertions; import org.intellij.lang.annotations.MagicConstant; import org.jetbrains.annotations.NotNull; @@ -385,7 +385,7 @@ public class GeneralCommandLineTest { public void unicodeEnvironment() throws Exception { // on Unix, JRE uses "file.encoding" ("sun.jnu.encoding" in 18+) to encode and decode environment; on Windows, JRE uses wide characters var uni = SystemInfo.isWindows ? IoTestUtil.getUnicodeName() : - JavaVersion.current().isAtLeast(18) ? IoTestUtil.getUnicodeName(System.getProperty("sun.jnu.encoding")) : + CurrentJavaVersion.currentJavaVersion().isAtLeast(18) ? IoTestUtil.getUnicodeName(System.getProperty("sun.jnu.encoding")) : IoTestUtil.getUnicodeName(System.getProperty("file.encoding")); assumeTrue(uni != null); diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java index f01438640a95..df030d88bc12 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java @@ -33,8 +33,8 @@ import com.intellij.testFramework.TestLoggerKt; import com.intellij.testFramework.fixtures.BareTestFixtureTestCase; import com.intellij.testFramework.rules.TempDirectory; import com.intellij.tools.ide.metrics.benchmark.Benchmark; +import com.intellij.util.CurrentJavaVersion; import com.intellij.util.SystemProperties; -import com.intellij.util.lang.JavaVersion; import com.intellij.util.messages.MessageBusConnection; import org.jetbrains.annotations.NotNull; import org.junit.After; @@ -1021,7 +1021,7 @@ public class LocalFileSystemTest extends BareTestFixtureTestCase { @Test public void canonicallyCasedHardLink() throws IOException { - assumeTrue("Requires JRE 21+", JavaVersion.current().isAtLeast(21)); + assumeTrue("Requires JRE 21+", CurrentJavaVersion.currentJavaVersion().isAtLeast(21)); var original = tempDir.newFile("original").toPath(); var hardLink = Files.createLink(original.resolveSibling("hardLink"), original); assertThat(myFS.refreshAndFindFileByNioFile(hardLink).getName()).isEqualTo(hardLink.getFileName().toString()); @@ -1030,7 +1030,7 @@ public class LocalFileSystemTest extends BareTestFixtureTestCase { @Test public void canonicallyCasedDecomposedName() { - assumeTrue("Requires JRE 21+", JavaVersion.current().isAtLeast(21)); + assumeTrue("Requires JRE 21+", CurrentJavaVersion.currentJavaVersion().isAtLeast(21)); @SuppressWarnings({"NonAsciiCharacters", "SpellCheckingInspection"}) var name = "schön"; var nfdName = Normalizer.normalize(name, Normalizer.Form.NFD); var nfcName = Normalizer.normalize(name, Normalizer.Form.NFC); diff --git a/platform/testFramework/src/com/intellij/platform/testFramework/io/DnsMock.kt b/platform/testFramework/src/com/intellij/platform/testFramework/io/DnsMock.kt index 1e28270115d2..bf0ac8ceb4a1 100644 --- a/platform/testFramework/src/com/intellij/platform/testFramework/io/DnsMock.kt +++ b/platform/testFramework/src/com/intellij/platform/testFramework/io/DnsMock.kt @@ -2,7 +2,7 @@ package com.intellij.platform.testFramework.io import com.intellij.openapi.util.io.FileUtil -import com.intellij.util.lang.JavaVersion +import com.intellij.util.currentJavaVersion import org.junit.rules.ExternalResource import java.io.File import java.net.InetAddress @@ -20,7 +20,7 @@ class DnsMock : ExternalResource() { } private val delegate: DnsMockDelegate = - if (JavaVersion.current().isAtLeast(21)) + if (currentJavaVersion().isAtLeast(21)) DnsMockJdk21 else DnsMockJdk17 diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java index 86e4ea12ede2..7fbbdab0dda9 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java @@ -74,7 +74,6 @@ import com.intellij.util.concurrency.ThreadingAssertions; import com.intellij.util.concurrency.annotations.RequiresEdt; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.io.Decompressor; -import com.intellij.util.lang.JavaVersion; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.tree.TreeUtil; import junit.framework.AssertionFailedError; @@ -698,7 +697,7 @@ public final class PlatformTestUtil { public static @NotNull URL getRtJarURL() { String home = SystemProperties.getJavaHome(); try { - return JavaVersion.current().feature >= 9 ? new URL("jrt:" + home) : new File(home + "/lib/rt.jar").toURI().toURL(); + return CurrentJavaVersion.currentJavaVersion().feature >= 9 ? new URL("jrt:" + home) : new File(home + "/lib/rt.jar").toURI().toURL(); } catch (MalformedURLException e) { throw new RuntimeException(e); diff --git a/platform/util-class-loader/src/com/intellij/util/lang/UrlClassLoader.java b/platform/util-class-loader/src/com/intellij/util/lang/UrlClassLoader.java index fb6c7ea860eb..a8e5f86e2517 100644 --- a/platform/util-class-loader/src/com/intellij/util/lang/UrlClassLoader.java +++ b/platform/util-class-loader/src/com/intellij/util/lang/UrlClassLoader.java @@ -388,7 +388,9 @@ public class UrlClassLoader extends ClassLoader implements ClassPath.ClassDataCo private static boolean isNotExcludedLangClasses(String fileNameWithoutExtension) { // these two classes from com.intellij.util.lang are located in intellij.platform.util module, // which shouldn't be loaded by appClassLoader (IDEA-331043) - return !fileNameWithoutExtension.endsWith("/CompoundRuntimeException") && !fileNameWithoutExtension.endsWith("/JavaVersion"); + return !fileNameWithoutExtension.endsWith("/CompoundRuntimeException") && + !fileNameWithoutExtension.endsWith("/JavaVersion") && + !fileNameWithoutExtension.endsWith("/JavaVersion$Companion"); } /** diff --git a/platform/util/api-dump-unreviewed.txt b/platform/util/api-dump-unreviewed.txt index 1f0bf62611e1..11518776aaa2 100644 --- a/platform/util/api-dump-unreviewed.txt +++ b/platform/util/api-dump-unreviewed.txt @@ -2148,6 +2148,8 @@ f:com.intellij.util.CoroutineScopeKt - sf:asDisposable(kotlinx.coroutines.CoroutineScope):com.intellij.openapi.Disposable - sf:attachAsChildTo(com.intellij.openapi.Disposable,kotlinx.coroutines.CoroutineScope):V - sf:disposeOnCompletion(com.intellij.openapi.Disposable,kotlinx.coroutines.CoroutineScope):V +f:com.intellij.util.CurrentJavaVersion +- sf:currentJavaVersion():com.intellij.util.lang.JavaVersion f:com.intellij.util.DefaultBundleService - ():V - compute(java.util.function.Supplier):java.lang.Object @@ -5430,24 +5432,6 @@ f:com.intellij.util.lang.CompoundRuntimeException - printStackTrace(java.io.PrintStream):V - printStackTrace(java.io.PrintWriter):V - s:throwIfNotEmpty(java.util.List):V -f:com.intellij.util.lang.JavaVersion -- java.lang.Comparable -- f:build:I -- f:ea:Z -- f:feature:I -- f:minor:I -- f:update:I -- compareTo(com.intellij.util.lang.JavaVersion):I -- s:compose(I):com.intellij.util.lang.JavaVersion -- s:compose(I,I,I,I,Z):com.intellij.util.lang.JavaVersion -- s:current():com.intellij.util.lang.JavaVersion -- equals(java.lang.Object):Z -- hashCode():I -- isAtLeast(I):Z -- s:parse(java.lang.String):com.intellij.util.lang.JavaVersion -- toFeatureMinorUpdateString():java.lang.String -- toFeatureString():java.lang.String -- s:tryParse(java.lang.String):com.intellij.util.lang.JavaVersion e:com.intellij.util.system.CpuArch - java.lang.Enum - sf:ARM32:com.intellij.util.system.CpuArch diff --git a/platform/util/kmp/api-dump.txt b/platform/util/kmp/api-dump.txt index e69de29bb2d1..68decba48b53 100644 --- a/platform/util/kmp/api-dump.txt +++ b/platform/util/kmp/api-dump.txt @@ -0,0 +1,32 @@ +f:com.intellij.util.lang.JavaVersion +- java.lang.Comparable +- sf:Companion:com.intellij.util.lang.JavaVersion$Companion +- f:build:I +- f:ea:Z +- f:feature:I +- f:minor:I +- f:update:I +- compareTo(com.intellij.util.lang.JavaVersion):I +- sf:compose(I):com.intellij.util.lang.JavaVersion +- sf:compose(I,I):com.intellij.util.lang.JavaVersion +- sf:compose(I,I,I):com.intellij.util.lang.JavaVersion +- sf:compose(I,I,I,I):com.intellij.util.lang.JavaVersion +- sf:compose(I,I,I,I,Z):com.intellij.util.lang.JavaVersion +- sf:current():com.intellij.util.lang.JavaVersion +- equals(java.lang.Object):Z +- hashCode():I +- f:isAtLeast(I):Z +- sf:parse(java.lang.String):com.intellij.util.lang.JavaVersion +- f:toFeatureMinorUpdateString():java.lang.String +- f:toFeatureString():java.lang.String +- sf:tryParse(java.lang.String):com.intellij.util.lang.JavaVersion +f:com.intellij.util.lang.JavaVersion$Companion +- f:compose(I):com.intellij.util.lang.JavaVersion +- f:compose(I,I):com.intellij.util.lang.JavaVersion +- f:compose(I,I,I):com.intellij.util.lang.JavaVersion +- f:compose(I,I,I,I):com.intellij.util.lang.JavaVersion +- f:compose(I,I,I,I,Z):com.intellij.util.lang.JavaVersion +- bs:compose$default(com.intellij.util.lang.JavaVersion$Companion,I,I,I,I,Z,I,java.lang.Object):com.intellij.util.lang.JavaVersion +- f:current():com.intellij.util.lang.JavaVersion +- f:parse(java.lang.String):com.intellij.util.lang.JavaVersion +- f:tryParse(java.lang.String):com.intellij.util.lang.JavaVersion diff --git a/platform/util/kmp/src/com/intellij/util/JavaVersionShim.kt b/platform/util/kmp/src/com/intellij/util/JavaVersionShim.kt new file mode 100644 index 000000000000..83231fa493a1 --- /dev/null +++ b/platform/util/kmp/src/com/intellij/util/JavaVersionShim.kt @@ -0,0 +1,10 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.util + +import com.intellij.util.lang.JavaVersion +import fleet.util.multiplatform.linkToActual + +/** + * see implementation [com.intellij.util.currentJavaVersionPlatformSpecificJvm] + */ +internal fun currentJavaVersionPlatformSpecific(): JavaVersion = linkToActual() diff --git a/platform/util/kmp/src/com/intellij/util/lang/JavaVersion.kt b/platform/util/kmp/src/com/intellij/util/lang/JavaVersion.kt new file mode 100644 index 000000000000..e2aa3891215e --- /dev/null +++ b/platform/util/kmp/src/com/intellij/util/lang/JavaVersion.kt @@ -0,0 +1,301 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +@file:ApiStatus.Internal +@file:JvmName("JavaVersionConstructor") + +package com.intellij.util.lang + +import com.intellij.util.currentJavaVersionPlatformSpecific +import org.jetbrains.annotations.ApiStatus + +/** + * + * A class representing a version of some Java platform - e.g. the runtime the class is loaded into, or some installed JRE. + * + * + * Based on [JEP 322 "Time-Based Release Versioning"](http://openjdk.org/jeps/322) (Java 10+), but also supports JEP 223 + * "New Version-String Scheme" (Java 9), as well as earlier version's formats. + * + * + * See [.parse] for examples of supported version strings. + * + * @implNote the class is used in bootstrap - please use only JDK API + */ +class JavaVersion internal constructor( + /** + * The major version. + * Corresponds to the first number of the 9+ format (**9**.0.1) / the second number of the 1.x format (1.**8**.0_60). + */ + @JvmField + val feature: Int, + + /** + * The minor version. + * Corresponds to the second number of the 9+ format (9.**0**.1) / the third number of 1.x the format (1.8.**0**_60). + * Was used in version strings prior to 1.5, in newer strings is always `0`. + */ + @JvmField + val minor: Int, + + /** + * The patch version. + * Corresponds to the third number of the 9+ format (9.0.**1**) / the number after an underscore of the 1.x format (1.8.0_**60**). + */ + @JvmField + val update: Int, + + /** + * The build number. + * Corresponds to a number prefixed by the "plus" sign in the 9+ format (9.0.1+**7**) / + * by "-b" string in the 1.x format (1.8.0_60-b**12**). + */ + @JvmField + val build: Int, + + /** + * `true` if the platform is an early access release, `false` otherwise (or when not known). + */ + @JvmField + val ea: Boolean, +) : Comparable { + init { + require(feature >= 0) + require(minor >= 0) + require(update >= 0) + require(build >= 0) + } + + override fun compareTo(o: JavaVersion): Int { + var diff = feature - o.feature + if (diff != 0) return diff + diff = minor - o.minor + if (diff != 0) return diff + diff = update - o.update + if (diff != 0) return diff + diff = build - o.build + if (diff != 0) return diff + return (if (ea) 0 else 1) - (if (o.ea) 0 else 1) + } + + fun isAtLeast(feature: Int): Boolean { + return this.feature >= feature + } + + override fun equals(o: Any?): Boolean { + if (this === o) return true + if (o !is JavaVersion) return false + val other = o + return feature == other.feature && minor == other.minor && update == other.update && build == other.build && ea == other.ea + } + + override fun hashCode(): Int { + var hash = feature + hash = 31 * hash + minor + hash = 31 * hash + update + hash = 31 * hash + build + hash = 31 * hash + (if (ea) 1231 else 1237) + return hash + } + + /** + * @return feature version string, e.g. **1.8** or **11** + */ + fun toFeatureString(): String { + return formatVersionTo(true, true) + } + + /** + * @return feature, minor and update components of the version string, e.g. + * **1.8.0_242** or **11.0.5** + */ + fun toFeatureMinorUpdateString(): String { + return formatVersionTo(false, true) + } + + override fun toString(): String { + return formatVersionTo(false, false) + } + + private fun formatVersionTo(upToFeature: Boolean, upToUpdate: Boolean): String { + val sb = StringBuilder() + if (feature > 8) { + sb.append(feature) + if (!upToFeature) { + if (minor > 0 || update > 0) sb.append('.').append(minor) + if (update > 0) sb.append('.').append(update) + if (!upToUpdate) { + if (ea) sb.append("-ea") + if (build > 0) sb.append('+').append(build) + } + } + } + else { + sb.append("1.").append(feature) + if (!upToFeature) { + if (minor > 0 || update > 0 || ea || build > 0) sb.append('.').append(minor) + if (update > 0) sb.append('_').append(update) + if (!upToUpdate) { + if (ea) sb.append("-ea") + if (build > 0) sb.append("-b").append(build) + } + } + } + return sb.toString() + } + + companion object { + /** + * Composes a version object out of given parameters. + * + * @throws IllegalArgumentException when any of the numbers is negative + */ + @JvmStatic + @JvmOverloads + @Throws(IllegalArgumentException::class) + fun compose(feature: Int, minor: Int = 0, update: Int = 0, build: Int = 0, ea: Boolean = false): JavaVersion = + JavaVersion(feature, minor, update, build, ea) + + /** + * Returns the version of a Java runtime the class is loaded into. + * The method attempts to parse `"java.runtime.version"` system property first (usually, it is more complete), + * and falls back to `"java.version"` if the former is invalid or differs in [.feature] or [.minor] numbers. + */ + @Deprecated("Use CurrentJavaVersion.current() instead", ReplaceWith("com.intellij.util.lang.CurrentJavaVersion.current()")) + @JvmStatic + fun current(): JavaVersion = currentJavaVersionPlatformSpecific() + + private const val MAX_ACCEPTED_VERSION = 50 // sanity check + + /** + * + * Parses a Java version string. + * + * + * Supports various sources, including (but not limited to):

+ * - `"java.*version"` system properties (a version number without any decoration)

+ * - values of Java compiler -source/-target/--release options ("$MAJOR", "1.$MAJOR")

+ * - output of "`java -version`" (usually "java version \"$VERSION\"")

+ * - a second line of the above command (something like to "Java(TM) SE Runtime Environment (build $VERSION)")

+ * - output of "`java --full-version`" ("java $VERSION")

+ * - a line of "release" file ("JAVA_VERSION=\"$VERSION\"") + * + * + * See com.intellij.util.lang.JavaVersionTest for examples. + * + * @throws IllegalArgumentException if failed to recognize the number. + */ + @JvmStatic + @Throws(IllegalArgumentException::class) + fun parse(versionString: String): JavaVersion { + // trimming + var str = versionString.trim { it <= ' ' } + val trimmingMap = mutableMapOf() // "substring to detect" to "substring from which to trim" + trimmingMap.put("Runtime Environment", "(build ") + trimmingMap.put("OpenJ9", "version ") + trimmingMap.put("GraalVM", "Java ") + for (keyToDetect in trimmingMap.keys) { + if (str.contains(keyToDetect)) { + val p = str.indexOf(trimmingMap[keyToDetect]!!) + if (p > 0) str = str.substring(p) + } + } + + // partitioning + val numbers = mutableListOf() + val separators = mutableListOf() + val length = str.length + var p = 0 + var number = false + while (p < length) { + val start = p + while (p < length && Character.isDigit(str[p]) == number) p++ + val part = str.substring(start, p) + (if (number) numbers else separators).add(part) + number = !number + } + + // parsing + if (!numbers.isEmpty() && !separators.isEmpty()) { + try { + var feature = numbers[0].toInt() + var minor = 0 + var update = 0 + var build = 0 + var ea = false + + if (feature >= 5 && feature < MAX_ACCEPTED_VERSION) { + // Java 9+; Java 5+ (short format) + p = 1 + while (p < separators.size && "." == separators[p]) p++ + if (p > 1 && numbers.size > 2) { + minor = numbers[1].toInt() + update = numbers[2].toInt() + } + if (p < separators.size) { + val s = separators[p] + if (!s.isEmpty() && s[0] == '-') { + ea = startsWithWord(s, "-ea") || startsWithWord(s, "-internal") + if (p < numbers.size && s[s.length - 1] == '+') { + build = numbers[p].toInt() + } + p++ + } + if (build == 0 && p < separators.size && p < numbers.size && "+" == separators[p]) { + build = numbers[p].toInt() + } + } + return JavaVersion(feature, minor, update, build, ea) + } + else if (feature == 1 && numbers.size > 1 && separators.size > 1 && "." == separators[1]) { + // Java 1.0 .. 1.4; Java 5+ (prefixed format) + feature = numbers[1].toInt() + if (feature <= MAX_ACCEPTED_VERSION) { + if (numbers.size > 2 && separators.size > 2 && "." == separators[2]) { + minor = numbers[2].toInt() + if (numbers.size > 3 && separators.size > 3 && "_" == separators[3]) { + update = numbers[3].toInt() + if (separators.size > 4) { + val s = separators[4] + if (!s.isEmpty() && s[0] == '-') { + ea = startsWithWord(s, "-ea") || startsWithWord(s, "-internal") + } + p = 4 + while (p < separators.size && !separators[p].endsWith("-b")) p++ + if (p < numbers.size) { + build = numbers[p].toInt() + } + } + } + } + return JavaVersion(feature, minor, update, build, ea) + } + } + } + catch (_: NumberFormatException) { + } + } + + throw IllegalArgumentException(versionString) + } + + private fun startsWithWord(s: String, word: String): Boolean { + return s.startsWith(word) && (s.length == word.length || !Character.isLetterOrDigit(s[word.length])) + } + + /** + * A safe version of [.parse] - returns `null` when unable to parse a version string. + */ + @JvmStatic + fun tryParse(versionString: String?): JavaVersion? { + if (versionString != null) { + try { + return parse(versionString) + } + catch (_: IllegalArgumentException) { + } + } + + return null + } + } +} + diff --git a/platform/util/kmp/srcJvm/com/intellij/util/JavaVersionJvm.kt b/platform/util/kmp/srcJvm/com/intellij/util/JavaVersionJvm.kt new file mode 100644 index 000000000000..ff673fb86dc5 --- /dev/null +++ b/platform/util/kmp/srcJvm/com/intellij/util/JavaVersionJvm.kt @@ -0,0 +1,48 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.util + +import com.intellij.util.lang.JavaVersion +import fleet.util.multiplatform.Actual +import org.jetbrains.annotations.ApiStatus + +private var current: JavaVersion? = null + +/** + * actual for [com.intellij.util.currentJavaVersionPlatformSpecific] + */ +@Actual("currentJavaVersionPlatformSpecific") +@ApiStatus.Internal +fun currentJavaVersionPlatformSpecificJvm(): JavaVersion { + current?.let { return it } + + val fallback = JavaVersion.parse(System.getProperty("java.version")) + val rt = rtVersion() ?: try { + JavaVersion.parse(System.getProperty("java.runtime.version")) + } + catch (_: Throwable) { + null + } + val version = rt.takeIf { rt != null && rt.feature == fallback.feature && rt.minor == fallback.minor } ?: fallback + return version.also { current = it } +} + +/** + * Attempts to use Runtime.version() method available since Java 9. + */ +// @ReviseWhenPortedToJDK("9") TODO make ReviseWhenPortedToJDK kmp-compatible +private fun rtVersion(): JavaVersion? { + try { + val version = Runtime::class.java.getMethod("version").invoke(null) + val major = version.javaClass.getMethod("major").invoke(version) as Int + val minor = version.javaClass.getMethod("minor").invoke(version) as Int + val security = version.javaClass.getMethod("security").invoke(version) as Int + val buildOpt = version.javaClass.getMethod("build").invoke(version) + val build = buildOpt.javaClass.getMethod("orElse", Any::class.java).invoke(buildOpt, 0) as Int + val preOpt = version.javaClass.getMethod("pre").invoke(version) + val ea = preOpt.javaClass.getMethod("isPresent").invoke(preOpt) as Boolean + return JavaVersion.compose(major, minor, security, build, ea) + } + catch (_: Throwable) { + return null + } +} diff --git a/platform/util/src/com/intellij/Patches.java b/platform/util/src/com/intellij/Patches.java index 2d2217db9b4c..d17bcf0fa1b1 100644 --- a/platform/util/src/com/intellij/Patches.java +++ b/platform/util/src/com/intellij/Patches.java @@ -3,7 +3,7 @@ package com.intellij; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.SystemInfoRt; -import com.intellij.util.lang.JavaVersion; +import com.intellij.util.CurrentJavaVersion; public final class Patches { /** @@ -44,5 +44,5 @@ public final class Patches { * JDK-8220231 */ @ReviseWhenPortedToJDK("13") - public static final boolean TEXT_LAYOUT_IS_SLOW = JavaVersion.current().feature == 12 && !SystemInfo.isJetBrainsJvm; + public static final boolean TEXT_LAYOUT_IS_SLOW = CurrentJavaVersion.currentJavaVersion().feature == 12 && !SystemInfo.isJetBrainsJvm; } diff --git a/platform/util/src/com/intellij/execution/process/UnixProcessManager.java b/platform/util/src/com/intellij/execution/process/UnixProcessManager.java index 64bcf171829e..773b5dcdbe39 100644 --- a/platform/util/src/com/intellij/execution/process/UnixProcessManager.java +++ b/platform/util/src/com/intellij/execution/process/UnixProcessManager.java @@ -7,9 +7,9 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.SystemInfoRt; +import com.intellij.util.CurrentJavaVersion; import com.intellij.util.Processor; import com.intellij.util.ReflectionUtil; -import com.intellij.util.lang.JavaVersion; import com.sun.jna.Library; import com.sun.jna.Native; import org.jetbrains.annotations.NonNls; @@ -62,7 +62,7 @@ public final class UnixProcessManager { @ReviseWhenPortedToJDK("9") public static int getProcessId(@NotNull Process process) { try { - if (JavaVersion.current().feature >= 9 && + if (CurrentJavaVersion.currentJavaVersion().feature >= 9 && ("java.lang.ProcessImpl".equals(process.getClass().getName()) || "com.pty4j.unix.UnixPtyProcess".equals(process.getClass().getName()) ) diff --git a/platform/util/src/com/intellij/execution/process/WinProcessManager.java b/platform/util/src/com/intellij/execution/process/WinProcessManager.java index 1d73a7b48dcb..f300f6a269d8 100644 --- a/platform/util/src/com/intellij/execution/process/WinProcessManager.java +++ b/platform/util/src/com/intellij/execution/process/WinProcessManager.java @@ -6,8 +6,8 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.CurrentJavaVersion; import com.intellij.util.ReflectionUtil; -import com.intellij.util.lang.JavaVersion; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.WinNT; @@ -28,7 +28,7 @@ public final class WinProcessManager { String processClassName = process.getClass().getName(); if (processClassName.equals("java.lang.Win32Process") || processClassName.equals("java.lang.ProcessImpl")) { try { - if (JavaVersion.current().feature >= 9) { + if (CurrentJavaVersion.currentJavaVersion().feature >= 9) { return ((Long)Process.class.getMethod("pid").invoke(process)).intValue(); } else { diff --git a/platform/util/src/com/intellij/openapi/application/ClassPathUtil.kt b/platform/util/src/com/intellij/openapi/application/ClassPathUtil.kt index bc964e48374a..4af42e1fdbdc 100644 --- a/platform/util/src/com/intellij/openapi/application/ClassPathUtil.kt +++ b/platform/util/src/com/intellij/openapi/application/ClassPathUtil.kt @@ -1,10 +1,11 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.openapi.application import com.fasterxml.aalto.`in`.ReaderConfig import com.intellij.diagnostic.LoadingState import com.intellij.openapi.util.SystemInfoRt import com.intellij.openapi.util.text.Strings +import com.intellij.util.lang.JavaVersion import com.intellij.util.lang.UrlClassLoader import com.sun.jna.TypeMapper import com.sun.jna.platform.FileUtils @@ -42,6 +43,7 @@ object ClassPathUtil { return arrayOf( LoadingState::class.java, // module 'intellij.platform.diagnostic' PathManager::class.java, // module 'intellij.platform.util' + JavaVersion::class.java, // module 'intellij.platform.util.kmp' Strings::class.java, // module 'intellij.platform.util.base' classLoader.loadClass("com.intellij.util.xml.dom.XmlDomReader"), // module 'intellij.platform.util.xmlDom' SystemInfoRt::class.java, // module 'intellij.platform.util.rt' diff --git a/platform/util/src/com/intellij/util/CurrentJavaVersion.kt b/platform/util/src/com/intellij/util/CurrentJavaVersion.kt new file mode 100644 index 000000000000..717663f780bd --- /dev/null +++ b/platform/util/src/com/intellij/util/CurrentJavaVersion.kt @@ -0,0 +1,13 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +@file:JvmName("CurrentJavaVersion") + +package com.intellij.util + +import com.intellij.util.lang.JavaVersion + +/** + * Returns the version of a Java runtime the class is loaded into. + * The method attempts to parse `"java.runtime.version"` system property first (usually, it is more complete), + * and falls back to `"java.version"` if the former is invalid or differs in [.feature] or [.minor] numbers. + */ +fun currentJavaVersion(): JavaVersion = currentJavaVersionPlatformSpecificJvm() \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/io/ByteBufferUtil.java b/platform/util/src/com/intellij/util/io/ByteBufferUtil.java index 8f75f57b29db..6ecdb559b5e7 100644 --- a/platform/util/src/com/intellij/util/io/ByteBufferUtil.java +++ b/platform/util/src/com/intellij/util/io/ByteBufferUtil.java @@ -3,9 +3,9 @@ package com.intellij.util.io; import com.intellij.ReviseWhenPortedToJDK; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.util.CurrentJavaVersion; import com.intellij.util.ReflectionUtil; import com.intellij.util.containers.Unsafe; -import com.intellij.util.lang.JavaVersion; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -22,7 +22,7 @@ public final class ByteBufferUtil { private static @Nullable MethodHandle findInvokeCleaner() { MethodHandle invokeCleaner = null; try { - if (JavaVersion.current().feature >= 9) { + if (CurrentJavaVersion.currentJavaVersion().feature >= 9) { Object unsafe = ReflectionUtil.getUnsafe(); MethodType type = MethodType.methodType(void.class, ByteBuffer.class); invokeCleaner = MethodHandles.publicLookup().findVirtual(unsafe.getClass(), "invokeCleaner", type).bindTo(unsafe); @@ -37,7 +37,7 @@ public final class ByteBufferUtil { private static @Nullable MethodHandle findAddress() { MethodHandle address = null; try { - if (JavaVersion.current().feature >= 9) { + if (CurrentJavaVersion.currentJavaVersion().feature >= 9) { Class directBufferClass = Class.forName("sun.nio.ch.DirectBuffer"); address = MethodHandles.lookup().findVirtual(directBufferClass, "address", diff --git a/platform/util/src/com/intellij/util/lang/JavaVersion.java b/platform/util/src/com/intellij/util/lang/JavaVersion.java deleted file mode 100644 index 0363f30b82bd..000000000000 --- a/platform/util/src/com/intellij/util/lang/JavaVersion.java +++ /dev/null @@ -1,328 +0,0 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.util.lang; - -import com.intellij.ReviseWhenPortedToJDK; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - *

A class representing a version of some Java platform - e.g. the runtime the class is loaded into, or some installed JRE.

- * - *

Based on JEP 322 "Time-Based Release Versioning" (Java 10+), but also supports JEP 223 - * "New Version-String Scheme" (Java 9), as well as earlier version's formats.

- * - *

See {@link #parse(String)} for examples of supported version strings.

- * - * @implNote the class is used in bootstrap - please use only JDK API - */ -@SuppressWarnings("DuplicatedCode") -public final class JavaVersion implements Comparable { - /** - * The major version. - * Corresponds to the first number of the 9+ format (9.0.1) / the second number of the 1.x format (1.8.0_60). - */ - public final int feature; - - /** - * The minor version. - * Corresponds to the second number of the 9+ format (9.0.1) / the third number of 1.x the format (1.8.0_60). - * Was used in version strings prior to 1.5, in newer strings is always {@code 0}. - */ - public final int minor; - - /** - * The patch version. - * Corresponds to the third number of the 9+ format (9.0.1) / the number after an underscore of the 1.x format (1.8.0_60). - */ - public final int update; - - /** - * The build number. - * Corresponds to a number prefixed by the "plus" sign in the 9+ format (9.0.1+7) / - * by "-b" string in the 1.x format (1.8.0_60-b12). - */ - public final int build; - - /** - * {@code true} if the platform is an early access release, {@code false} otherwise (or when not known). - */ - public final boolean ea; - - private JavaVersion(int feature, int minor, int update, int build, boolean ea) { - this.feature = feature; - this.minor = minor; - this.update = update; - this.build = build; - this.ea = ea; - } - - @Override - public int compareTo(@NotNull JavaVersion o) { - int diff = feature - o.feature; - if (diff != 0) return diff; - diff = minor - o.minor; - if (diff != 0) return diff; - diff = update - o.update; - if (diff != 0) return diff; - diff = build - o.build; - if (diff != 0) return diff; - return (ea ? 0 : 1) - (o.ea ? 0 : 1); - } - - public boolean isAtLeast(int feature) { - return this.feature >= feature; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof JavaVersion)) return false; - JavaVersion other = (JavaVersion)o; - return feature == other.feature && - minor == other.minor && - update == other.update && - build == other.build && - ea == other.ea; - } - - @Override - public int hashCode() { - int hash = feature; - hash = 31 * hash + minor; - hash = 31 * hash + update; - hash = 31 * hash + build; - hash = 31 * hash + (ea ? 1231 : 1237); - return hash; - } - - /** - * @return feature version string, e.g. 1.8 or 11 - */ - public @NotNull String toFeatureString() { - return formatVersionTo(true, true); - } - - /** - * @return feature, minor and update components of the version string, e.g. - * 1.8.0_242 or 11.0.5 - */ - public @NotNull String toFeatureMinorUpdateString() { - return formatVersionTo(false, true); - } - - @Override - public String toString() { - return formatVersionTo(false, false); - } - - private String formatVersionTo(boolean upToFeature, boolean upToUpdate) { - StringBuilder sb = new StringBuilder(); - if (feature > 8) { - sb.append(feature); - if (!upToFeature) { - if (minor > 0 || update > 0) sb.append('.').append(minor); - if (update > 0) sb.append('.').append(update); - if (!upToUpdate) { - if (ea) sb.append("-ea"); - if (build > 0) sb.append('+').append(build); - } - } - } - else { - sb.append("1.").append(feature); - if (!upToFeature) { - if (minor > 0 || update > 0 || ea || build > 0) sb.append('.').append(minor); - if (update > 0) sb.append('_').append(update); - if (!upToUpdate) { - if (ea) sb.append("-ea"); - if (build > 0) sb.append("-b").append(build); - } - } - } - return sb.toString(); - } - - /** - * Composes a version object out of given parameters. - * - * @throws IllegalArgumentException when any of the numbers is negative - */ - public static @NotNull JavaVersion compose(int feature, int minor, int update, int build, boolean ea) throws IllegalArgumentException { - if (feature < 0) throw new IllegalArgumentException(); - if (minor < 0) throw new IllegalArgumentException(); - if (update < 0) throw new IllegalArgumentException(); - if (build < 0) throw new IllegalArgumentException(); - return new JavaVersion(feature, minor, update, build, ea); - } - - public static @NotNull JavaVersion compose(int feature) { - return compose(feature, 0, 0, 0, false); - } - - private static JavaVersion current; - - /** - * Returns the version of a Java runtime the class is loaded into. - * The method attempts to parse {@code "java.runtime.version"} system property first (usually, it is more complete), - * and falls back to {@code "java.version"} if the former is invalid or differs in {@link #feature} or {@link #minor} numbers. - */ - public static @NotNull JavaVersion current() { - if (current == null) { - JavaVersion fallback = parse(System.getProperty("java.version")); - JavaVersion rt = rtVersion(); - if (rt == null) { - try { rt = parse(System.getProperty("java.runtime.version")); } - catch (Throwable ignored) { } - } - current = rt != null && rt.feature == fallback.feature && rt.minor == fallback.minor ? rt : fallback; - } - return current; - } - - /** - * Attempts to use Runtime.version() method available since Java 9. - */ - @ReviseWhenPortedToJDK("9") - private static @Nullable JavaVersion rtVersion() { - try { - Object version = Runtime.class.getMethod("version").invoke(null); - int major = (Integer)version.getClass().getMethod("major").invoke(version); - int minor = (Integer)version.getClass().getMethod("minor").invoke(version); - int security = (Integer)version.getClass().getMethod("security").invoke(version); - Object buildOpt = version.getClass().getMethod("build").invoke(version); - int build = (Integer)buildOpt.getClass().getMethod("orElse", Object.class).invoke(buildOpt, Integer.valueOf(0)); - Object preOpt = version.getClass().getMethod("pre").invoke(version); - boolean ea = (Boolean)preOpt.getClass().getMethod("isPresent").invoke(preOpt); - return new JavaVersion(major, minor, security, build, ea); - } - catch (Throwable ignored) { - return null; - } - } - - private static final int MAX_ACCEPTED_VERSION = 50; // sanity check - - /** - *

Parses a Java version string.

- * - *

Supports various sources, including (but not limited to):
- * - {@code "java.*version"} system properties (a version number without any decoration)
- * - values of Java compiler -source/-target/--release options ("$MAJOR", "1.$MAJOR")
- * - output of "{@code java -version}" (usually "java version \"$VERSION\"")
- * - a second line of the above command (something like to "Java(TM) SE Runtime Environment (build $VERSION)")
- * - output of "{@code java --full-version}" ("java $VERSION")
- * - a line of "release" file ("JAVA_VERSION=\"$VERSION\"")

- * - *

See com.intellij.util.lang.JavaVersionTest for examples.

- * - * @throws IllegalArgumentException if failed to recognize the number. - */ - public static @NotNull JavaVersion parse(@NotNull String versionString) throws IllegalArgumentException { - // trimming - String str = versionString.trim(); - Map trimmingMap = new HashMap<>(); // "substring to detect" to "substring from which to trim" - trimmingMap.put("Runtime Environment", "(build "); - trimmingMap.put("OpenJ9", "version "); - trimmingMap.put("GraalVM", "Java "); - for (String keyToDetect : trimmingMap.keySet()) { - if (str.contains(keyToDetect)) { - int p = str.indexOf(trimmingMap.get(keyToDetect)); - if (p > 0) str = str.substring(p); - } - } - - // partitioning - List numbers = new ArrayList<>(), separators = new ArrayList<>(); - int length = str.length(), p = 0; - boolean number = false; - while (p < length) { - int start = p; - while (p < length && Character.isDigit(str.charAt(p)) == number) p++; - String part = str.substring(start, p); - (number ? numbers : separators).add(part); - number = !number; - } - - // parsing - if (!numbers.isEmpty() && !separators.isEmpty()) { - try { - int feature = Integer.parseInt(numbers.get(0)), minor = 0, update = 0, build = 0; - boolean ea = false; - - if (feature >= 5 && feature < MAX_ACCEPTED_VERSION) { - // Java 9+; Java 5+ (short format) - p = 1; - while (p < separators.size() && ".".equals(separators.get(p))) p++; - if (p > 1 && numbers.size() > 2) { - minor = Integer.parseInt(numbers.get(1)); - update = Integer.parseInt(numbers.get(2)); - } - if (p < separators.size()) { - String s = separators.get(p); - if (s != null && !s.isEmpty() && s.charAt(0) == '-') { - ea = startsWithWord(s, "-ea") || startsWithWord(s, "-internal"); - if (p < numbers.size() && s.charAt(s.length() - 1) == '+') { - build = Integer.parseInt(numbers.get(p)); - } - p++; - } - if (build == 0 && p < separators.size() && p < numbers.size() && "+".equals(separators.get(p))) { - build = Integer.parseInt(numbers.get(p)); - } - } - return new JavaVersion(feature, minor, update, build, ea); - } - else if (feature == 1 && numbers.size() > 1 && separators.size() > 1 && ".".equals(separators.get(1))) { - // Java 1.0 .. 1.4; Java 5+ (prefixed format) - feature = Integer.parseInt(numbers.get(1)); - if (feature <= MAX_ACCEPTED_VERSION) { - if (numbers.size() > 2 && separators.size() > 2 && ".".equals(separators.get(2))) { - minor = Integer.parseInt(numbers.get(2)); - if (numbers.size() > 3 && separators.size() > 3 && "_".equals(separators.get(3))) { - update = Integer.parseInt(numbers.get(3)); - if (separators.size() > 4) { - String s = separators.get(4); - if (s != null && !s.isEmpty() && s.charAt(0) == '-') { - ea = startsWithWord(s, "-ea") || startsWithWord(s, "-internal"); - } - p = 4; - while (p < separators.size() && !separators.get(p).endsWith("-b")) p++; - if (p < numbers.size()) { - build = Integer.parseInt(numbers.get(p)); - } - } - } - } - return new JavaVersion(feature, minor, update, build, ea); - } - } - } - catch (NumberFormatException ignored) { } - } - - throw new IllegalArgumentException(versionString); - } - - private static boolean startsWithWord(String s, String word) { - return s.startsWith(word) && (s.length() == word.length() || !Character.isLetterOrDigit(s.charAt(word.length()))); - } - - /** - * A safe version of {@link #parse(String)} - returns {@code null} when unable to parse a version string. - */ - public static @Nullable JavaVersion tryParse(String versionString) { - if (versionString != null) { - try { - return parse(versionString); - } - catch (IllegalArgumentException ignored) { } - } - - return null; - } -} diff --git a/platform/util/testSrc/com/intellij/util/lang/test/JavaVersionTest.kt b/platform/util/testSrc/com/intellij/util/lang/test/JavaVersionTest.kt index d7010dab22fd..d396ba0e8ccf 100644 --- a/platform/util/testSrc/com/intellij/util/lang/test/JavaVersionTest.kt +++ b/platform/util/testSrc/com/intellij/util/lang/test/JavaVersionTest.kt @@ -1,6 +1,7 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.util.lang.test +import com.intellij.util.currentJavaVersion import com.intellij.util.lang.JavaVersion import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatExceptionOfType @@ -54,7 +55,7 @@ class JavaVersionTest { @Test fun ibmRt(): Unit = doFailTest("pxa6480sr3fp10-20160720_02 (SR3 FP10)") @Test fun current() { - val current = JavaVersion.current() + val current = currentJavaVersion() assertThat(current.feature).isGreaterThanOrEqualTo(8) assertThat(current.minor).isEqualTo(0) assertThat(current.build).isGreaterThan(0) diff --git a/platform/util/testSrc/com/intellij/util/lang/test/UrlClassLoaderSplitPackageTest.kt b/platform/util/testSrc/com/intellij/util/lang/test/UrlClassLoaderSplitPackageTest.kt index c497486570e1..c4665c20da97 100644 --- a/platform/util/testSrc/com/intellij/util/lang/test/UrlClassLoaderSplitPackageTest.kt +++ b/platform/util/testSrc/com/intellij/util/lang/test/UrlClassLoaderSplitPackageTest.kt @@ -25,6 +25,7 @@ class UrlClassLoaderSplitPackageTest { val knownClassesFromOtherModules = setOf( "CompoundRuntimeException", "JavaVersion", + "JavaVersion\$Companion", ) val project = IntelliJProjectConfiguration.loadIntelliJProject(PathManager.getHomePath()) project.modules.filterNot { it.name in platformLoaderModules }.forEach { module -> diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleImportingTestCase.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleImportingTestCase.java index 11f0a5e5e83a..e556e14da444 100644 --- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleImportingTestCase.java +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleImportingTestCase.java @@ -42,8 +42,8 @@ import com.intellij.testFramework.ExtensionTestUtil; import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.RunAll; import com.intellij.testFramework.UsefulTestCase; +import com.intellij.util.CurrentJavaVersion; import com.intellij.util.SmartList; -import com.intellij.util.lang.JavaVersion; import org.gradle.StartParameter; import org.gradle.util.GradleVersion; import org.gradle.wrapper.PathAssembler; @@ -291,8 +291,8 @@ public abstract class GradleImportingTestCase extends JavaExternalSystemImportin @NotNull GradleVersion gradleVersion, @NotNull JavaVersionRestriction javaVersionRestriction ) { - if (GradleJvmSupportMatrix.isSupported(gradleVersion, JavaVersion.current()) && - !javaVersionRestriction.isRestricted(gradleVersion, JavaVersion.current())) { + if (GradleJvmSupportMatrix.isSupported(gradleVersion, CurrentJavaVersion.currentJavaVersion()) && + !javaVersionRestriction.isRestricted(gradleVersion, CurrentJavaVersion.currentJavaVersion())) { return IdeaTestUtil.requireRealJdkHome(); } // fix exception of FJP at JavaHomeFinder.suggestHomePaths => ... => EnvironmentUtil.getEnvironmentMap => CompletableFuture. diff --git a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/InProcessGroovyc.java b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/InProcessGroovyc.java index 3ca074a27e86..fd3ba91d6fe9 100644 --- a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/InProcessGroovyc.java +++ b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/InProcessGroovyc.java @@ -7,11 +7,8 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.ConcurrencyUtil; -import com.intellij.util.PathUtilRt; -import com.intellij.util.SystemProperties; +import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.lang.JavaVersion; import com.intellij.util.lang.UrlClassLoader; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -219,7 +216,7 @@ public final class InProcessGroovyc implements GroovycFlavor { } private static @Nullable ClassLoader getPlatformLoaderParentIfOnJdk9() { - if (JavaVersion.current().feature >= 9) { + if (CurrentJavaVersion.currentJavaVersion().feature >= 9) { // on Java 8, 'tools.jar' is on a classpath; on Java 9, its classes are available via the platform loader try { return (ClassLoader)ClassLoader.class.getMethod("getPlatformClassLoader").invoke(null); diff --git a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/JpsGroovycRunner.java b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/JpsGroovycRunner.java index 49e9f464daaf..351bba502bf1 100644 --- a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/JpsGroovycRunner.java +++ b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/JpsGroovycRunner.java @@ -7,9 +7,9 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.CurrentJavaVersion; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; -import com.intellij.util.lang.JavaVersion; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.groovy.compiler.rt.GroovyRtConstants; @@ -148,7 +148,7 @@ public abstract class JpsGroovycRunner toCompilePaths = getPathsToCompile(toCompile); JpsSdk jdk = GroovyBuilder.getJdk(chunk); - int version = jdk != null ? JpsJavaSdkType.getJavaVersion(jdk) : JavaVersion.current().feature; + int version = jdk != null ? JpsJavaSdkType.getJavaVersion(jdk) : CurrentJavaVersion.currentJavaVersion().feature; boolean inProcess = shouldRunGroovycInProcess(version); boolean mayDependOnUtilJar = version >= 6; // Optimized classloader is in fact a UrlClassLoader that refers to jar archives in the SDK distribution @@ -205,7 +205,7 @@ public abstract class JpsGroovycRunner= 9 + val jrt = currentJavaVersion().feature >= 9 val base = if (jrt) "jrt://${SystemProperties.getJavaHome()}!/java.desktop/" else "jar://${SystemProperties.getJavaHome()}/lib/rt.jar!/" val file = VirtualFileManager.getInstance().findFileByUrl(base + "javax/swing/JTable.class")!! Benchmark.newBenchmark("decompiling JTable.class") { decompiler.getText(file) }.start() diff --git a/plugins/javaFX/sceneBuilder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java b/plugins/javaFX/sceneBuilder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java index 29bca7577803..a9796ff856bc 100644 --- a/plugins/javaFX/sceneBuilder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java +++ b/plugins/javaFX/sceneBuilder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java @@ -27,8 +27,8 @@ import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.psi.util.PsiUtilCore; +import com.intellij.util.CurrentJavaVersion; import com.intellij.util.Query; -import com.intellij.util.lang.JavaVersion; import com.intellij.util.xml.NanoXmlBuilder; import com.intellij.util.xml.NanoXmlUtil; import com.oracle.javafx.scenebuilder.kit.editor.EditorController; @@ -155,7 +155,7 @@ public class SceneBuilderImpl implements SceneBuilder { // Take custom components from libraries, but not from the project modules, because org.jetbrains.plugins.javaFX.sceneBuilder.SceneBuilder instantiates the components' classes. // Modules might be not compiled or may change since last compile, it's too expensive to keep track of that. final GlobalSearchScope scope = ProjectScope.getLibrariesScope(nodeClass.getProject()); - final JavaSdkVersion ideJdkVersion = JavaSdkVersion.fromJavaVersion(JavaVersion.current()); + final JavaSdkVersion ideJdkVersion = JavaSdkVersion.fromJavaVersion(CurrentJavaVersion.currentJavaVersion()); final LanguageLevel ideLanguageLevel = ideJdkVersion != null ? ideJdkVersion.getMaxLanguageLevel() : null; final Query query = ClassInheritorsSearch.search(nodeClass, scope, true, true, false); final Set result = new HashSet<>(); diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditor.java index 7543fbc9121e..d487edc3fd7e 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditor.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditor.java @@ -23,9 +23,9 @@ import com.intellij.ui.EditorNotificationPanel; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.SideBorder; import com.intellij.ui.components.panels.NonOpaquePanel; +import com.intellij.util.CurrentJavaVersion; import com.intellij.util.download.DownloadableFileService; import com.intellij.util.download.FileDownloader; -import com.intellij.util.lang.JavaVersion; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -106,7 +106,7 @@ public final class SceneBuilderEditor extends UserDataHolderBase implements File myErrorNotification.clear(); myErrorStack.setText(""); - if (JavaVersion.current().feature > 11 && + if (CurrentJavaVersion.currentJavaVersion().feature > 11 && e instanceof NoClassDefFoundError && !SceneBuilderUtil.getSceneBuilder11Path().toFile().isFile()) { myErrorNotification.setText(JavaFXBundle.message("javafx.scene.builder.editor.failed.to.open.file.error")); @@ -142,7 +142,7 @@ public final class SceneBuilderEditor extends UserDataHolderBase implements File myLayout.show(myPanel, ERROR_CARD); return; } - if (JavaVersion.current().feature > 11) { + if (CurrentJavaVersion.currentJavaVersion().feature > 11) { try { Class.forName(JavaFxCommonNames.JAVAFX_SCENE_NODE); } diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/AbstractLocalInspectionTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/AbstractLocalInspectionTest.kt index a98ac41b5235..a2da31a6f84d 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/AbstractLocalInspectionTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/AbstractLocalInspectionTest.kt @@ -23,7 +23,7 @@ import com.intellij.testFramework.PlatformTestUtil.dispatchAllEventsInIdeEventQu import com.intellij.testFramework.PsiTestUtil import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl import com.intellij.util.io.write -import com.intellij.util.lang.JavaVersion +import com.intellij.util.currentJavaVersion import org.jdom.Element import org.jetbrains.kotlin.idea.base.test.IgnoreTests import org.jetbrains.kotlin.idea.base.test.InTextDirectivesUtils @@ -109,7 +109,7 @@ abstract class AbstractLocalInspectionTest : KotlinLightCodeInsightFixtureTestCa withCustomCompilerOptions(fileText, project, module) { val minJavaVersion = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// MIN_JAVA_VERSION: ")?.toInt() - if (minJavaVersion != null && !JavaVersion.current().isAtLeast(minJavaVersion)) { + if (minJavaVersion != null && !currentJavaVersion().isAtLeast(minJavaVersion)) { return@withCustomCompilerOptions }