Gradle: use module-path to run java9 modular application

This commit is contained in:
Vladislav.Soroka
2017-10-02 21:06:45 +03:00
parent fdf08a2c8c
commit ac191c76f6
@@ -15,12 +15,14 @@
*/
package org.jetbrains.plugins.gradle.execution.build;
import com.intellij.codeInsight.daemon.impl.analysis.JavaModuleGraphUtil;
import com.intellij.execution.CantRunException;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.Executor;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.application.ApplicationConfiguration;
import com.intellij.execution.configurations.JavaParameters;
import com.intellij.execution.configurations.JavaRunConfigurationModule;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.util.ExecutionErrorDialog;
@@ -31,16 +33,20 @@ import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunCo
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkType;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkTypeId;
import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiJavaModule;
import com.intellij.task.ExecuteRunConfigurationTask;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
@@ -82,6 +88,7 @@ public class GradleApplicationEnvironmentProvider implements GradleExecutionEnvi
JavaParametersUtil.configureConfiguration(params, applicationConfiguration);
params.getVMParametersList().addParametersString(applicationConfiguration.getVMParameters());
String javaModuleName = null;
String javaExePath = null;
try {
final Sdk jdk = JavaParametersUtil.createProjectJdk(project, applicationConfiguration.getAlternativeJrePath());
@@ -91,6 +98,7 @@ public class GradleApplicationEnvironmentProvider implements GradleExecutionEnvi
javaExePath = ((JavaSdkType)type).getVMExecutablePath(jdk);
if (javaExePath == null) throw new RuntimeException(ExecutionBundle.message("run.configuration.cannot.find.vm.executable"));
javaExePath = FileUtil.toSystemIndependentName(javaExePath);
javaModuleName = findJavaModuleName(jdk, applicationConfiguration.getConfigurationModule(), mainClass);
}
catch (CantRunException e) {
ExecutionErrorDialog.show(e, "Cannot use specified JRE", project);
@@ -135,24 +143,35 @@ public class GradleApplicationEnvironmentProvider implements GradleExecutionEnvi
String workingDir = ProgramParametersUtil.getWorkingDir(applicationConfiguration, project, module);
workingDir = workingDir == null ? null : FileUtil.toSystemIndependentName(workingDir);
// @formatter:off
@Language("Groovy")
String initScript = "allprojects {\n" +
" afterEvaluate { project ->\n" +
" if(project.path == '" + gradlePath + "' && project?.convention?.findPlugin(JavaPluginConvention)) {\n" +
" project.tasks.create(name: '" + runAppTaskName + "', overwrite: true, type: JavaExec) {\n" +
(javaExePath != null ?
" executable = '" + javaExePath + "'\n" : "") +
(javaExePath == null ? "" :
" executable = '" + javaExePath + "'\n") +
" classpath = project.sourceSets.'" + sourceSetName + "'.runtimeClasspath\n" +
" main = '" + mainClass.getQualifiedName() + "'\n" +
parametersString.toString() +
vmParametersString.toString() +
(StringUtil.isNotEmpty(workingDir) ?
" workingDir = '" + workingDir + "'\n" : "") +
parametersString.toString() +
vmParametersString.toString() +
(StringUtil.isNotEmpty(workingDir) ?
" workingDir = '" + workingDir + "'\n" : "") +
" standardInput = System.in\n" +
(javaModuleName == null ? "" :
" inputs.property('moduleName', '" + javaModuleName + "')\n" +
" doFirst {\n" +
" jvmArgs += [\n" +
" '--module-path', classpath.asPath,\n" +
" '--module', '" + javaModuleName + "/" + mainClass.getQualifiedName() + "'\n" +
" ]\n" +
" classpath = files()\n"+
" }\n") +
" }\n" +
" }\n" +
" }\n" +
"}\n";
// @formatter:on
runConfiguration.putUserData(GradleTaskManager.INIT_SCRIPT_KEY, initScript);
return environment;
@@ -161,4 +180,16 @@ public class GradleApplicationEnvironmentProvider implements GradleExecutionEnvi
return null;
}
}
@Nullable
private static String findJavaModuleName(Sdk sdk, JavaRunConfigurationModule module, PsiClass mainClass) {
if (JavaSdkUtil.isJdkAtLeast(sdk, JavaSdkVersion.JDK_1_9)) {
PsiJavaModule mainModule = DumbService.getInstance(module.getProject()).computeWithAlternativeResolveEnabled(
() -> JavaModuleGraphUtil.findDescriptorByElement(module.findClass(mainClass.getQualifiedName())));
if (mainModule != null) {
return mainModule.getName();
}
}
return null;
}
}