IDEA-145790: When a run configuration is started run java process using newest JDK from module dependencies

This commit is contained in:
nik
2015-10-01 13:08:14 +03:00
parent 3a43e5a8b6
commit 309727d069
4 changed files with 70 additions and 11 deletions
@@ -124,7 +124,7 @@ public class JavaParametersUtil {
JavaParameters parameters,
@MagicConstant(valuesFromClass = JavaParameters.class) int classPathType,
@Nullable String jreHome) throws CantRunException {
parameters.configureByModule(module, classPathType, createModuleJdk(module, jreHome));
parameters.configureByModule(module, classPathType, createModuleJdk(module, (classPathType & JavaParameters.TESTS_ONLY) == 0, jreHome));
}
public static void configureProject(Project project,
@@ -134,8 +134,8 @@ public class JavaParametersUtil {
parameters.configureByProject(project, classPathType, createProjectJdk(project, jreHome));
}
private static Sdk createModuleJdk(final Module module, @Nullable String jreHome) throws CantRunException {
return jreHome == null ? JavaParameters.getModuleJdk(module) : createAlternativeJdk(jreHome);
private static Sdk createModuleJdk(final Module module, boolean productionOnly, @Nullable String jreHome) throws CantRunException {
return jreHome == null ? JavaParameters.getValidJdkToRunModule(module, productionOnly) : createAlternativeJdk(jreHome);
}
public static Sdk createProjectJdk(final Project project, @Nullable String jreHome) throws CantRunException {
@@ -27,11 +27,15 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
import com.intellij.util.NotNullFunction;
import com.intellij.util.PathsList;
import com.intellij.util.Processor;
import com.intellij.util.text.VersionComparatorUtil;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.charset.Charset;
import java.util.LinkedHashSet;
import java.util.Set;
public class JavaParameters extends SimpleJavaParameters {
private static final Logger LOG = Logger.getInstance(JavaParameters.class);
@@ -53,7 +57,7 @@ public class JavaParameters extends SimpleJavaParameters {
public static final int JDK_ONLY = 0x1;
public static final int CLASSES_ONLY = 0x2;
private static final int TESTS_ONLY = 0x4;
public static final int TESTS_ONLY = 0x4;
public static final int JDK_AND_CLASSES = JDK_ONLY | CLASSES_ONLY;
public static final int JDK_AND_CLASSES_AND_TESTS = JDK_ONLY | CLASSES_ONLY | TESTS_ONLY;
public static final int CLASSES_AND_TESTS = CLASSES_ONLY | TESTS_ONLY;
@@ -112,11 +116,19 @@ public class JavaParameters extends SimpleJavaParameters {
public void configureByModule(final Module module,
@MagicConstant(valuesFromClass = JavaParameters.class) final int classPathType) throws CantRunException {
configureByModule(module, classPathType, getModuleJdk(module));
configureByModule(module, classPathType, getValidJdkToRunModule(module, (classPathType & TESTS_ONLY) == 0));
}
/**
* @deprecated use {@link #getValidJdkToRunModule(Module, boolean)} instead
*/
public static Sdk getModuleJdk(final Module module) throws CantRunException {
final Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
return getValidJdkToRunModule(module, false);
}
@NotNull
public static Sdk getValidJdkToRunModule(final Module module, boolean productionOnly) throws CantRunException {
Sdk jdk = getJdkToRunModule(module, productionOnly);
if (jdk == null) {
throw CantRunException.noJdkForModule(module);
}
@@ -127,6 +139,42 @@ public class JavaParameters extends SimpleJavaParameters {
return jdk;
}
@Nullable
public static Sdk getJdkToRunModule(Module module, boolean productionOnly) {
final Sdk moduleSdk = ModuleRootManager.getInstance(module).getSdk();
if (moduleSdk == null) {
return null;
}
final Set<Sdk> sdksFromDependencies = new LinkedHashSet<Sdk>();
OrderEnumerator enumerator = OrderEnumerator.orderEntries(module).runtimeOnly().recursively();
if (productionOnly) {
enumerator = enumerator.productionOnly();
}
enumerator.forEachModule(new Processor<Module>() {
@Override
public boolean process(Module module) {
Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
if (sdk != null && sdk.getSdkType().equals(moduleSdk.getSdkType())) {
sdksFromDependencies.add(sdk);
}
return true;
}
});
return findLatestVersion(moduleSdk, sdksFromDependencies);
}
@NotNull
private static Sdk findLatestVersion(@NotNull Sdk mainSdk, @NotNull Set<Sdk> sdks) {
Sdk result = mainSdk;
for (Sdk sdk : sdks) {
if (VersionComparatorUtil.compare(result.getVersionString(), sdk.getVersionString()) < 0) {
result = sdk;
}
}
return result;
}
public void configureByProject(final Project project, @MagicConstant(valuesFromClass = JavaParameters.class) final int classPathType, final Sdk jdk) throws CantRunException {
if ((classPathType & JDK_ONLY) != 0) {
if (jdk == null) {
@@ -22,6 +22,7 @@ import com.intellij.openapi.roots.DependencyScope;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.roots.ModuleRootManagerTestCase;
import org.intellij.lang.annotations.MagicConstant;
/**
* @author nik
@@ -96,13 +97,22 @@ public class JavaParametersTest extends ModuleRootManagerTestCase {
getJDomJar());
}
private static void assertClasspath(final Module module, final int type, VirtualFile... roots) throws CantRunException {
public void testUseNewestJreVersion() throws CantRunException {
Module dep = createModule("dep");
ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.TEST, true);
ModuleRootModificationUtil.setModuleSdk(myModule, getMockJdk17WithRtJarOnly());
ModuleRootModificationUtil.setModuleSdk(dep, getMockJdk18WithRtJarOnly());
assertClasspath(myModule, JavaParameters.JDK_AND_CLASSES, getRtJarJdk17());
assertClasspath(myModule, JavaParameters.JDK_AND_CLASSES_AND_TESTS, getRtJarJdk18());
}
private static void assertClasspath(final Module module, @MagicConstant(flagsFromClass = JavaParameters.class) int type, VirtualFile... roots) throws CantRunException {
final JavaParameters javaParameters = new JavaParameters();
javaParameters.configureByModule(module, type);
assertRoots(javaParameters.getClassPath(), roots);
}
private void assertClasspath(final Project project, final int type, VirtualFile... roots) throws CantRunException {
private void assertClasspath(final Project project, @MagicConstant(flagsFromClass = JavaParameters.class) int type, VirtualFile... roots) throws CantRunException {
final JavaParameters javaParameters = new JavaParameters();
javaParameters.configureByProject(project, type, getTestProjectJdk());
assertRoots(javaParameters.getClassPath(), roots);
@@ -33,15 +33,15 @@ public abstract class ModuleRootManagerTestCase extends ModuleTestCase {
@NotNull
protected static Sdk getMockJdk17WithRtJarOnly() {
return retainRtJarOnly(IdeaTestUtil.getMockJdk17());
return retainRtJarOnlyAndSetVersion(IdeaTestUtil.getMockJdk17());
}
protected Sdk getMockJdk18WithRtJarOnly() {
return retainRtJarOnly(IdeaTestUtil.getMockJdk18());
return retainRtJarOnlyAndSetVersion(IdeaTestUtil.getMockJdk18());
}
@NotNull
private static Sdk retainRtJarOnly(Sdk jdk) {
private static Sdk retainRtJarOnlyAndSetVersion(Sdk jdk) {
final SdkModificator modificator = jdk.getSdkModificator();
VirtualFile rtJar = null;
for (VirtualFile root : modificator.getRoots(OrderRootType.CLASSES)) {
@@ -51,6 +51,7 @@ public abstract class ModuleRootManagerTestCase extends ModuleTestCase {
}
}
assertNotNull("rt.jar not found in jdk: " + jdk, rtJar);
modificator.setVersionString(IdeaTestUtil.getMockJdkVersion(jdk.getHomePath()));
modificator.removeAllRoots();
modificator.addRoot(rtJar, OrderRootType.CLASSES);
modificator.commitChanges();