24 */
25
26 package com.sun.tools.sjavac.server;
27
28 import java.io.BufferedReader;
29 import java.io.File;
30 import java.io.FileReader;
31 import java.io.IOException;
32 import java.io.InputStreamReader;
33 import java.io.PrintStream;
34 import java.io.PrintWriter;
35 import java.io.StringWriter;
36 import java.net.InetAddress;
37 import java.net.InetSocketAddress;
38 import java.net.Socket;
39 import java.net.SocketAddress;
40 import java.net.URI;
41 import java.util.Collections;
42 import java.util.HashMap;
43 import java.util.HashSet;
44 import java.util.List;
45 import java.util.Map;
46 import java.util.Set;
47
48 import com.sun.tools.sjavac.Util;
49 import com.sun.tools.sjavac.options.Options;
50
51 import static com.sun.tools.sjavac.server.CompilationResult.ERROR_BUT_TRY_AGAIN;
52 import static com.sun.tools.sjavac.server.CompilationResult.ERROR_FATAL;
53
54 public class JavacServiceClient implements JavacService {
55
56
57 // The id can perhaps be used in the future by the javac server to reuse the
58 // JavaCompiler instance for several compiles using the same id.
59 private final String id;
60 private final String portfile;
61 private final String logfile;
62 private final String stdouterrfile;
63 private final boolean background;
119 Collections.<URI>emptySet(),
120 Collections.<URI, Set<String>>emptyMap());
121 return cr.sysinfo;
122 } catch (Exception e) {
123 return new SysInfo(-1, -1);
124 }
125 }
126
127 @Override
128 public CompilationResult compile(String protocolId,
129 String invocationId,
130 String[] args,
131 List<File> explicitSources,
132 Set<URI> sourcesToCompile,
133 Set<URI> visibleSources) {
134 // Delegate to useServer, which delegates to compileHelper
135 return useServer(args, sourcesToCompile, visibleSources, null);
136 }
137
138 /**
139 * Connect and compile using the javac server settings and the args. When using more advanced features, the sources_to_compile and visible_sources are
140 * supplied to the server and meta data is returned in package_artifacts, package_dependencies and package_pubapis.
141 */
142 public CompilationResult compileHelper(String id,
143 String[] args,
144 Set<URI> sourcesToCompile,
145 Set<URI> visibleSources) {
146
147 CompilationResult rc = new CompilationResult(-3);
148
149 try {
150 PortFile portFile = JavacServer.getPortFile(this.portfile);
151
152 int port = portFile.containsPortInfo() ? portFile.getPort() : 0;
153 if (port == 0) {
154 return new CompilationResult(ERROR_BUT_TRY_AGAIN);
155 }
156 long cookie = portFile.getCookie();
157 // Acquire the localhost/127.0.0.1 address.
158 InetAddress addr = InetAddress.getByName(null);
264 rc.packageArtifacts.put(pkg, lastUriSet);
265 } else if (l.length() > 1 && lastUriSet != null) {
266 lastUriSet.add(new URI(l.substring(1)));
267 }
268 }
269 // Load package dependencies
270 Set<String> lastPackageSet = null;
271 for (;;) {
272 String l = in.readLine();
273 if (l == null) {
274 return new CompilationResult(ERROR_FATAL);
275 }
276 if (l.equals(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS)) {
277 break;
278 }
279 if (l.length() > 1 && l.charAt(0) == '+') {
280 String pkg = l.substring(1);
281 lastPackageSet = new HashSet<>();
282 rc.packageDependencies.put(pkg, lastPackageSet);
283 } else if (l.length() > 1 && lastPackageSet != null) {
284 lastPackageSet.add(l.substring(1));
285 }
286 }
287 // Load package pubapis
288 Map<String, StringBuffer> tmp = new HashMap<>();
289 StringBuffer lastPublicApi = null;
290 for (;;) {
291 String l = in.readLine();
292 if (l == null) {
293 return new CompilationResult(ERROR_FATAL);
294 }
295 if (l.equals(JavacServer.PROTOCOL_SYSINFO)) {
296 break;
297 }
298 if (l.length() > 1 && l.charAt(0) == '+') {
299 String pkg = l.substring(1);
300 lastPublicApi = new StringBuffer();
301 tmp.put(pkg, lastPublicApi);
302 } else if (l.length() > 1 && lastPublicApi != null) {
303 lastPublicApi.append(l.substring(1));
304 lastPublicApi.append("\n");
305 }
306 }
307 for (String p : tmp.keySet()) {
308 //assert (packagePublicApis.get(p) == null);
309 String api = tmp.get(p).toString();
310 rc.packagePubapis.put(p, api);
311 }
312 // Now reading the max memory possible.
313 for (;;) {
314 String l = in.readLine();
315 if (l == null) {
316 return new CompilationResult(ERROR_FATAL);
317 }
318 if (l.equals(JavacServer.PROTOCOL_RETURN_CODE)) {
319 break;
320 }
321 if (l.startsWith("num_cores=")) {
322 rc.sysinfo.numCores = Integer.parseInt(l.substring(10));
323 }
324 if (l.startsWith("max_memory=")) {
325 rc.sysinfo.maxMemory = Long.parseLong(l.substring(11));
326 }
327 }
328 String l = in.readLine();
329 if (l == null) {
330 rc.setReturnCode(ERROR_FATAL);
331 rc.stderr = "No return value from the server!";
332 return rc;
333 }
334 rc.setReturnCode(Integer.parseInt(l));
335 rc.stdout = stdout.toString();
336 rc.stderr = stderr.toString();
337 } catch (Exception e) {
338 StringWriter sw = new StringWriter();
339 e.printStackTrace(new PrintWriter(sw));
340 rc.stderr = sw.toString();
341 }
342 return rc;
343 }
344
345 /**
346 * Dispatch a compilation request to a javac server.
347 *
348 * @param args are the command line args to javac and is allowed to contain source files, @file and other command line options to javac.
349 *
350 * The generated classes, h files and other artifacts from the javac invocation are stored by the javac server to disk.
351 *
352 * @param sources_to_compile The sources to compile.
353 *
354 * @param visibleSources If visible sources has a non zero size, then visible_sources are the only files in the file system that the javac server can see!
355 * (Sources to compile are always visible.) The visible sources are those supplied by the (filtered) -sourcepath
356 *
|
24 */
25
26 package com.sun.tools.sjavac.server;
27
28 import java.io.BufferedReader;
29 import java.io.File;
30 import java.io.FileReader;
31 import java.io.IOException;
32 import java.io.InputStreamReader;
33 import java.io.PrintStream;
34 import java.io.PrintWriter;
35 import java.io.StringWriter;
36 import java.net.InetAddress;
37 import java.net.InetSocketAddress;
38 import java.net.Socket;
39 import java.net.SocketAddress;
40 import java.net.URI;
41 import java.util.Collections;
42 import java.util.HashMap;
43 import java.util.HashSet;
44 import java.util.LinkedList;
45 import java.util.List;
46 import java.util.Map;
47 import java.util.Set;
48
49 import com.sun.tools.sjavac.Util;
50 import com.sun.tools.sjavac.options.Options;
51
52 import static com.sun.tools.sjavac.server.CompilationResult.ERROR_BUT_TRY_AGAIN;
53 import static com.sun.tools.sjavac.server.CompilationResult.ERROR_FATAL;
54
55 public class JavacServiceClient implements JavacService {
56
57
58 // The id can perhaps be used in the future by the javac server to reuse the
59 // JavaCompiler instance for several compiles using the same id.
60 private final String id;
61 private final String portfile;
62 private final String logfile;
63 private final String stdouterrfile;
64 private final boolean background;
120 Collections.<URI>emptySet(),
121 Collections.<URI, Set<String>>emptyMap());
122 return cr.sysinfo;
123 } catch (Exception e) {
124 return new SysInfo(-1, -1);
125 }
126 }
127
128 @Override
129 public CompilationResult compile(String protocolId,
130 String invocationId,
131 String[] args,
132 List<File> explicitSources,
133 Set<URI> sourcesToCompile,
134 Set<URI> visibleSources) {
135 // Delegate to useServer, which delegates to compileHelper
136 return useServer(args, sourcesToCompile, visibleSources, null);
137 }
138
139 /**
140 * Extract the package name and the class from the string.
141 * Deps will be a map from packag name to class name.
142 */
143 static void addClasspathPackageDependency(Map<String, Set<String>> deps, String fullname) {
144 // Modules beware!
145 String pkg;
146 int p = fullname.lastIndexOf('.');
147 if (p == -1) {
148 // Arghh, a source file without a package.
149 pkg = ":";
150 }
151 else {
152 pkg = ":"+fullname.substring(0, p);
153 }
154 synchronized (deps) {
155 Set<String> set = deps.get(pkg);
156 if (set == null) {
157 set = new HashSet<String>();
158 deps.put(pkg, set);
159 }
160 set.add(fullname);
161 }
162 }
163
164 /**
165 * Connect and compile using the javac server settings and the args. When using more advanced features, the sources_to_compile and visible_sources are
166 * supplied to the server and meta data is returned in package_artifacts, package_dependencies and package_pubapis.
167 */
168 public CompilationResult compileHelper(String id,
169 String[] args,
170 Set<URI> sourcesToCompile,
171 Set<URI> visibleSources) {
172
173 CompilationResult rc = new CompilationResult(-3);
174
175 try {
176 PortFile portFile = JavacServer.getPortFile(this.portfile);
177
178 int port = portFile.containsPortInfo() ? portFile.getPort() : 0;
179 if (port == 0) {
180 return new CompilationResult(ERROR_BUT_TRY_AGAIN);
181 }
182 long cookie = portFile.getCookie();
183 // Acquire the localhost/127.0.0.1 address.
184 InetAddress addr = InetAddress.getByName(null);
290 rc.packageArtifacts.put(pkg, lastUriSet);
291 } else if (l.length() > 1 && lastUriSet != null) {
292 lastUriSet.add(new URI(l.substring(1)));
293 }
294 }
295 // Load package dependencies
296 Set<String> lastPackageSet = null;
297 for (;;) {
298 String l = in.readLine();
299 if (l == null) {
300 return new CompilationResult(ERROR_FATAL);
301 }
302 if (l.equals(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS)) {
303 break;
304 }
305 if (l.length() > 1 && l.charAt(0) == '+') {
306 String pkg = l.substring(1);
307 lastPackageSet = new HashSet<>();
308 rc.packageDependencies.put(pkg, lastPackageSet);
309 } else if (l.length() > 1 && lastPackageSet != null) {
310 if (l.startsWith(" :. ")) {
311 // This is a classpath dependency.
312 addClasspathPackageDependency(rc.classpathPackageDependencies, l.substring(4));
313 } else {
314 // Standard package dependency.
315 lastPackageSet.add(l.substring(1));
316 }
317 }
318 }
319 // Load package pubapis
320 List<String> lastPublicApi = new LinkedList<>();
321 for (;;) {
322 String l = in.readLine();
323 if (l == null) {
324 return new CompilationResult(ERROR_FATAL);
325 }
326 if (l.equals(JavacServer.PROTOCOL_SYSINFO)) {
327 break;
328 }
329 if (l.length() > 1 && l.charAt(0) == '+') {
330 String pkg = l.substring(1);
331 lastPublicApi = new LinkedList<>();
332 rc.packagePublicApis.put(pkg, lastPublicApi);
333 } else if (l.length() > 1 && lastPublicApi != null) {
334 lastPublicApi.add(l.substring(1));
335 }
336 }
337 // Now reading the max memory possible.
338 for (;;) {
339 String l = in.readLine();
340 if (l == null) {
341 return new CompilationResult(ERROR_FATAL);
342 }
343 if (l.equals(JavacServer.PROTOCOL_RETURN_CODE)) {
344 break;
345 }
346 if (l.startsWith("num_cores=")) {
347 rc.sysinfo.numCores = Integer.parseInt(l.substring(10));
348 }
349 if (l.startsWith("max_memory=")) {
350 rc.sysinfo.maxMemory = Long.parseLong(l.substring(11));
351 }
352 }
353 String l = in.readLine();
354 if (l == null) {
355 rc.setReturnCode(ERROR_FATAL);
356 rc.stderr = "No return value from the server!";
357 return rc;
358 }
359 rc.setReturnCode(Integer.parseInt(l));
360 rc.stdout = stdout.toString();
361 rc.stderr = stderr.toString();
362 System.out.print(rc.stdout);
363 System.err.print(rc.stderr);
364 } catch (Exception e) {
365 StringWriter sw = new StringWriter();
366 e.printStackTrace(new PrintWriter(sw));
367 rc.stderr = sw.toString();
368 }
369 return rc;
370 }
371
372 /**
373 * Dispatch a compilation request to a javac server.
374 *
375 * @param args are the command line args to javac and is allowed to contain source files, @file and other command line options to javac.
376 *
377 * The generated classes, h files and other artifacts from the javac invocation are stored by the javac server to disk.
378 *
379 * @param sources_to_compile The sources to compile.
380 *
381 * @param visibleSources If visible sources has a non zero size, then visible_sources are the only files in the file system that the javac server can see!
382 * (Sources to compile are always visible.) The visible sources are those supplied by the (filtered) -sourcepath
383 *
|