diff --git a/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java b/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java index 77c828faa59e..77ba081951e7 100644 --- a/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java +++ b/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java @@ -31,7 +31,6 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.JBColor; import com.intellij.ui.ListCellRendererWrapper; import com.intellij.ui.components.JBLabel; -import com.intellij.util.Consumer; import com.intellij.util.JdkBundle; import com.intellij.util.JdkBundleList; import org.jetbrains.annotations.NonNls; @@ -42,7 +41,6 @@ import javax.swing.*; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import java.io.*; -import java.util.List; import java.util.Locale; /** @@ -144,15 +142,31 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware { public void contentsChanged(ListDataEvent e) { if (myComboBox.getSelectedItem() == null) { FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, false, false, false, false) { + JdkBundle selectedBundle; + @Override public boolean isFileSelectable(final VirtualFile file) { + selectedBundle = null; if (!super.isFileSelectable(file)) return false; - JdkBundle bundle = JdkBundle.createBundle(new File(file.getPath()), false, false); + // allow selection of JDK of any arch, so that to warn about possible arch mismatch during validation + JdkBundle bundle = JdkBundle.createBundle(new File(file.getPath()), false, false, false); if (bundle == null) return false; Version version = bundle.getVersion(); - + selectedBundle = bundle; return version != null && !version.lessThan(JDK8_VERSION.major, JDK8_VERSION.minor, JDK8_VERSION.bugfix); } + + @Override + public void validateSelectedFiles(VirtualFile[] files) throws Exception { + super.validateSelectedFiles(files); + assert files.length == 1; + if (selectedBundle == null) { + throw new Exception("Invalid JDK bundle!"); + } + if (selectedBundle.getBitness() != (SystemInfo.is64Bit ? Bitness.x64 : Bitness.x32)) { + throw new Exception("JDK arch mismatch! Expected: " + SystemInfo.OS_ARCH); + } + } }; FileChooser.chooseFiles(descriptor, null, null, files -> { diff --git a/platform/lang-impl/src/com/intellij/util/JdkBundle.java b/platform/lang-impl/src/com/intellij/util/JdkBundle.java index 2ac187193acc..828b64378052 100644 --- a/platform/lang-impl/src/com/intellij/util/JdkBundle.java +++ b/platform/lang-impl/src/com/intellij/util/JdkBundle.java @@ -20,9 +20,7 @@ import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.util.ExecUtil; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.Version; +import com.intellij.openapi.util.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -48,6 +46,7 @@ public class JdkBundle { @Nullable private Pair myVersionUpdate; private boolean myBoot; private boolean myBundled; + private volatile Bitness bitness; JdkBundle(@NotNull File bundleAsFile, @NotNull String bundleName, @@ -59,15 +58,17 @@ public class JdkBundle { myBundled = bundled; } - - @Nullable public static JdkBundle createBundle(@NotNull File jvm, boolean boot, boolean bundled) { + return createBundle(jvm, boot, bundled, true); + } + + public static JdkBundle createBundle(@NotNull File jvm, boolean boot, boolean bundled, boolean matchArch) { String homeSubPath = SystemInfo.isMac ? "Contents/Home" : ""; - return createBundle(jvm, homeSubPath, boot, bundled); + return createBundle(jvm, homeSubPath, boot, bundled, matchArch); } @Nullable - static JdkBundle createBundle(@NotNull File jvm, @NotNull String homeSubPath, boolean boot, boolean bundled) { + static JdkBundle createBundle(@NotNull File jvm, @NotNull String homeSubPath, boolean boot, boolean bundled, boolean matchArch) { File javaHome = SystemInfo.isMac ? new File(jvm, homeSubPath) : jvm; if (bundled) javaHome = new File(PathManager.getHomePath(), javaHome.getPath()); @@ -82,8 +83,11 @@ public class JdkBundle { File absJvmLocation = bundled ? new File(PathManager.getHomePath(), jvm.getPath()) : jvm; Pair, Pair> nameArchVersionAndUpdate = getJDKNameArchVersionAndUpdate(absJvmLocation, homeSubPath); - if (nameArchVersionAndUpdate.first.second == null || (nameArchVersionAndUpdate.first.second != SystemInfo.is64Bit)) { - return null; // Skip unknown or incompatible arch + if (nameArchVersionAndUpdate.first.second == null) { + return null; // Skip unknown arch + } + if (matchArch && nameArchVersionAndUpdate.first.second != SystemInfo.is64Bit) { + return null; // Skip incompatible arch } if (SystemInfo.isMac && nameArchVersionAndUpdate.second != null && nameArchVersionAndUpdate.second.first.isOrGreaterThan(1, 7) && @@ -91,7 +95,10 @@ public class JdkBundle { return null; // Skip jre } - return new JdkBundle(jvm, nameArchVersionAndUpdate.first.first, nameArchVersionAndUpdate.second, boot, bundled); + JdkBundle bundle = new JdkBundle(jvm, nameArchVersionAndUpdate.first.first, nameArchVersionAndUpdate.second, boot, bundled); + // init already computed bitness + bundle.bitness = nameArchVersionAndUpdate.first.second == SystemInfo.is64Bit ? Bitness.x64 : Bitness.x32; + return bundle; } @Nullable @@ -106,7 +113,7 @@ public class JdkBundle { bootJDK = bootJDK.getParentFile().getParentFile(); return createBundle(bootJDK, true, false); } - return createBundle(bootJDK, "", true, false); + return createBundle(bootJDK, "", true, false, true); } @NotNull @@ -142,6 +149,16 @@ public class JdkBundle { return myBoot; } + public Bitness getBitness() { + if (bitness == null) { + String homeSubPath = SystemInfo.isMac ? "Contents/Home" : ""; + Pair, Pair> nameArchVersionAndUpdate = getJDKNameArchVersionAndUpdate(getAbsoluteLocation(), homeSubPath); + assert nameArchVersionAndUpdate.first.second != null; + bitness = nameArchVersionAndUpdate.first.second == SystemInfo.is64Bit ? Bitness.x64 : Bitness.x32; + } + return bitness; + } + @NotNull public String getBundleName() { return myBundleName; diff --git a/platform/platform-tests/testSrc/com/intellij/util/JdkBundleTest.java b/platform/platform-tests/testSrc/com/intellij/util/JdkBundleTest.java index c78cf9e25ab2..564cb34a4ec8 100644 --- a/platform/platform-tests/testSrc/com/intellij/util/JdkBundleTest.java +++ b/platform/platform-tests/testSrc/com/intellij/util/JdkBundleTest.java @@ -124,7 +124,7 @@ public class JdkBundleTest { boolean macNonStandardJDK = SystemInfo.isMac && !new File(bootJDK, "Contents/Home").exists(); JdkBundle bundle = macNonStandardJDK - ? JdkBundle.createBundle(homeJDK, "", true, false) : // the test is run under jdk with non-standard layout + ? JdkBundle.createBundle(homeJDK, "", true, false, true) : // the test is run under jdk with non-standard layout JdkBundle.createBundle(bootJDK, true, false); assertNotNull(bundle);