private static int execInProcess( String compilerClassName, String[] arguments, CompilerEnvironment environment, PrintStream out, MessageCollector messageCollector) { try { messageCollector.report( CompilerMessageSeverity.INFO, "Using kotlinHome=" + environment.getKotlinPaths().getHomePath(), CompilerMessageLocation.NO_LOCATION); messageCollector.report( CompilerMessageSeverity.INFO, "Invoking in-process compiler " + compilerClassName + " with arguments " + Arrays.asList(arguments), CompilerMessageLocation.NO_LOCATION); Object rc = CompilerRunnerUtil.invokeExecMethod( compilerClassName, arguments, environment, messageCollector, out, /*usePreloader=*/ true); // exec() returns a K2JVMCompiler.ExitCode object, that class is not accessible here, // so we take it's contents through reflection return CompilerRunnerUtil.getReturnCodeFromObject(rc); } catch (Throwable e) { MessageCollectorUtil.reportException(messageCollector, e); return -1; } }
public static Object invokeExecMethod( String compilerClassName, String[] arguments, CompilerEnvironment environment, MessageCollector messageCollector, PrintStream out, boolean usePreloader) throws Exception { ClassLoader loader = usePreloader ? getOrCreatePreloader( environment.getKotlinPaths(), environment.getParentFactory(), messageCollector) : getOrCreateClassLoader(environment.getKotlinPaths(), messageCollector); Class<?> kompiler = Class.forName(compilerClassName, true, loader); Method exec = kompiler.getMethod("exec", PrintStream.class, String[].class); return exec.invoke(kompiler.newInstance(), out, arguments); }
private static void runOutOfProcess( String compilerClassName, String[] arguments, final MessageCollector messageCollector, final OutputItemsCollector itemCollector, CompilerEnvironment environment) { SimpleJavaParameters params = new SimpleJavaParameters(); params.setJdk(new SimpleJavaSdkType().createJdk("tmp", SystemProperties.getJavaHome())); params.setMainClass(compilerClassName); for (String arg : arguments) { params.getProgramParametersList().add(arg); } for (File jar : CompilerRunnerUtil.kompilerClasspath(environment.getKotlinPaths(), messageCollector)) { params.getClassPath().add(jar); } params.getVMParametersList().addParametersString("-Djava.awt.headless=true -Xmx512m"); // params.getVMParametersList().addParametersString("-agentlib:yjpagent=sampling"); Sdk sdk = params.getJdk(); assert sdk != null; GeneralCommandLine commandLine = JdkUtil.setupJVMCommandLine( ((JavaSdkType) sdk.getSdkType()).getVMExecutablePath(sdk), params, false); messageCollector.report( CompilerMessageSeverity.INFO, "Invoking out-of-process compiler with arguments: " + commandLine, CompilerMessageLocation.NO_LOCATION); try { final Process process = commandLine.createProcess(); ApplicationManager.getApplication() .executeOnPooledThread( new Runnable() { @Override public void run() { CompilerOutputParser.parseCompilerMessagesFromReader( messageCollector, new InputStreamReader(process.getInputStream()), itemCollector); } }); ApplicationManager.getApplication() .executeOnPooledThread( new Runnable() { @Override public void run() { try { FileUtil.loadBytes(process.getErrorStream()); } catch (IOException e) { // Don't care } } }); int exitCode = process.waitFor(); CompilerRunnerUtil.handleProcessTermination(exitCode, messageCollector); } catch (Exception e) { messageCollector.report( CompilerMessageSeverity.ERROR, "[Internal Error] " + e.getLocalizedMessage(), CompilerMessageLocation.NO_LOCATION); } }