1 package org.jetbrains.jps.javac;
3 import com.intellij.execution.process.BaseOSProcessHandler;
4 import com.intellij.execution.process.ProcessAdapter;
5 import com.intellij.execution.process.ProcessEvent;
6 import com.intellij.execution.process.ProcessOutputTypes;
7 import com.intellij.openapi.util.Key;
8 import com.intellij.openapi.util.Ref;
9 import com.intellij.openapi.util.SystemInfo;
10 import com.intellij.openapi.util.io.FileUtil;
11 import com.intellij.openapi.util.text.StringUtil;
12 import com.intellij.util.concurrency.Semaphore;
13 import org.jetbrains.jps.server.ClasspathBootstrap;
16 import java.util.ArrayList;
17 import java.util.List;
20 * @author Eugene Zhuravlev
23 public class JavacServerBootstrap {
25 public static BaseOSProcessHandler launchJavacServer(String vmExecutablePath,
29 List<String> vmOptions) throws Exception {
31 final List<String> cmdLine = new ArrayList<String>();
32 appendParam(cmdLine, vmExecutablePath);
33 appendParam(cmdLine, "-server");
34 appendParam(cmdLine, "-XX:MaxPermSize=150m");
35 //appendParam(cmdLine, "-XX:ReservedCodeCacheSize=64m");
36 appendParam(cmdLine, "-Djava.awt.headless=true");
37 appendParam(cmdLine, "-Xmx" + heapSize + "m");
40 //appendParam(cmdLine, "-XX:+HeapDumpOnOutOfMemoryError");
41 //appendParam(cmdLine, "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009");
43 // javac's VM should use the same default locale that IDEA uses in order for javac to print messages in 'correct' language
44 final String lang = System.getProperty("user.language");
46 //noinspection HardCodedStringLiteral
47 appendParam(cmdLine, "-Duser.language=" + lang);
49 final String country = System.getProperty("user.country");
50 if (country != null) {
51 //noinspection HardCodedStringLiteral
52 appendParam(cmdLine, "-Duser.country=" + country);
54 //noinspection HardCodedStringLiteral
55 final String region = System.getProperty("user.region");
57 //noinspection HardCodedStringLiteral
58 appendParam(cmdLine, "-Duser.region=" + region);
61 for (String option : vmOptions) {
62 appendParam(cmdLine, option);
65 appendParam(cmdLine, "-classpath");
67 final List<File> cp = ClasspathBootstrap.getJavacServerClasspath();
68 final StringBuilder classpath = new StringBuilder();
69 for (File file : cp) {
70 if (classpath.length() > 0) {
71 classpath.append(File.pathSeparator);
73 classpath.append(file.getPath());
75 appendParam(cmdLine, classpath.toString());
77 appendParam(cmdLine, org.jetbrains.jps.javac.JavacServer.class.getName());
78 appendParam(cmdLine, Integer.toString(port));
82 appendParam(cmdLine, FileUtil.toSystemIndependentName(workingDir.getPath()));
84 final ProcessBuilder builder = new ProcessBuilder(cmdLine);
85 builder.directory(workingDir);
87 final Process process = builder.start();
88 final BaseOSProcessHandler processHandler = new BaseOSProcessHandler(process, null, null);
89 configureProcessHandler(processHandler);
91 return processHandler;
94 private static void configureProcessHandler(final BaseOSProcessHandler processHandler) throws Exception {
95 processHandler.addProcessListener(new ProcessAdapter() {
96 public void onTextAvailable(ProcessEvent event, Key outputType) {
97 final String text = event.getText();
98 if (text != null && text.length() > 0) {
99 System.out.print("JAVAC_SERVER [" + outputType.toString() + "]: " + text);
103 final Semaphore semaphore = new Semaphore();
105 final Ref<String> serverStartMessage = new Ref<String>(null);
106 processHandler.addProcessListener(new ProcessAdapter() {
107 public void processTerminated(ProcessEvent event) {
109 processHandler.removeProcessListener(this);
116 public void onTextAvailable(ProcessEvent event, Key outputType) {
117 if (outputType == ProcessOutputTypes.STDERR) {
119 final String text = event.getText();
121 if (text.contains(JavacServer.SERVER_SUCCESS_START_MESSAGE) || text.contains(JavacServer.SERVER_ERROR_START_MESSAGE)) {
122 processHandler.removeProcessListener(this);
123 serverStartMessage.set(text);
133 processHandler.startNotify();
136 final String startupMsg = serverStartMessage.get();
137 if (startupMsg == null || !startupMsg.contains(JavacServer.SERVER_SUCCESS_START_MESSAGE)) {
138 throw new Exception("Server startup failed: " + startupMsg);
142 private static void appendParam(List<String> cmdLine, String param) {
143 if (SystemInfo.isWindows) {
144 if (param.contains("\"")) {
145 param = StringUtil.replace(param, "\"", "\\\"");
147 else if (param.length() == 0) {