Warn about JDK arch mismatch in Switch IDE Boot JDK.

In order to give user a hint why he/she can't select a valid JDK (which actually doesn't match the bitness of the running IDEA), a warning dialog will popup.
This commit is contained in:
Anton Tarasov
2016-07-08 11:39:59 +03:00
parent 65150bf9be
commit 26b66bb2fc
3 changed files with 47 additions and 16 deletions
@@ -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 -> {
@@ -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<Version, Integer> 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<String, Boolean>, Pair<Version, Integer>> 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<String, Boolean>, Pair<Version, Integer>> 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;
@@ -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);