29 import java.io.PrintStream; |
29 import java.io.PrintStream; |
30 import java.util.*; |
30 import java.util.*; |
31 import java.nio.file.Path; |
31 import java.nio.file.Path; |
32 import java.nio.file.Files; |
32 import java.nio.file.Files; |
33 |
33 |
|
34 import com.sun.tools.sjavac.client.SjavacClient; |
|
35 import com.sun.tools.sjavac.comp.SjavacImpl; |
|
36 import com.sun.tools.sjavac.comp.PooledSjavac; |
34 import com.sun.tools.sjavac.options.Options; |
37 import com.sun.tools.sjavac.options.Options; |
35 import com.sun.tools.sjavac.options.SourceLocation; |
38 import com.sun.tools.sjavac.options.SourceLocation; |
36 import com.sun.tools.sjavac.server.JavacService; |
39 import com.sun.tools.sjavac.server.Sjavac; |
37 import com.sun.tools.sjavac.server.JavacServer; |
40 import com.sun.tools.sjavac.server.SjavacServer; |
38 import com.sun.tools.sjavac.server.JavacServiceClient; |
|
39 |
41 |
40 /** |
42 /** |
41 * The main class of the smart javac wrapper tool. |
43 * The main class of the smart javac wrapper tool. |
42 * |
44 * |
43 * <p><b>This is NOT part of any supported API. |
45 * <p><b>This is NOT part of any supported API. |
44 * If you write code that depends on this, you do so at your own |
46 * If you write code that depends on this, you do so at your own risk. |
45 * risk. This code and its internal interfaces are subject to change |
47 * This code and its internal interfaces are subject to change or |
46 * or deletion without notice.</b></p> |
48 * deletion without notice.</b> |
47 */ |
49 */ |
48 public class Main { |
50 public class Main { |
49 |
51 |
50 /* This is a smart javac wrapper primarily used when building the OpenJDK, |
52 /* This is a smart javac wrapper primarily used when building the OpenJDK, |
51 though other projects are welcome to use it too. But please be aware |
53 though other projects are welcome to use it too. But please be aware |
161 if (args.length>1) { |
163 if (args.length>1) { |
162 Log.error("When spawning a background server, only a single --startserver argument is allowed."); |
164 Log.error("When spawning a background server, only a single --startserver argument is allowed."); |
163 return; |
165 return; |
164 } |
166 } |
165 // Spawn a background server. |
167 // Spawn a background server. |
166 int rc = JavacServer.startServer(args[0], System.err); |
168 try { |
167 System.exit(rc); |
169 SjavacServer server = new SjavacServer(args[0], System.err); |
|
170 int rc = server.startServer(); |
|
171 System.exit(rc); |
|
172 } catch (IOException ioex) { |
|
173 Log.error("IOException caught: " + ioex); |
|
174 System.exit(-1); |
|
175 } |
168 } |
176 } |
169 Main main = new Main(); |
177 Main main = new Main(); |
170 int rc = main.go(args, System.out, System.err); |
178 int rc = main.go(args, System.out, System.err); |
171 // Remove the portfile, but only if this background=false was used. |
179 // Remove the portfile, but only if this background=false was used. |
172 JavacServer.cleanup(args); |
180 SjavacServer.cleanup(args); |
173 System.exit(rc); |
181 System.exit(rc); |
174 } |
182 } |
175 |
183 |
176 private void printHelp() { |
184 private void printHelp() { |
177 System.out.println("Usage: sjavac <options>\n"+ |
185 System.out.println("Usage: sjavac <options>\n"+ |
300 // (Unless we allow them to be there.) |
311 // (Unless we allow them to be there.) |
301 // I.e. artifacts that are not known according to the build database (javac_state). |
312 // I.e. artifacts that are not known according to the build database (javac_state). |
302 // For examples, files that have been manually copied into these dirs. |
313 // For examples, files that have been manually copied into these dirs. |
303 // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp |
314 // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp |
304 // in javac_state) have already been removed when the javac_state was loaded. |
315 // in javac_state) have already been removed when the javac_state was loaded. |
305 if (!options.isUnidentifiedArtifactPermitted()) { |
316 if (!options.areUnidentifiedArtifactsPermitted()) { |
306 javac_state.removeUnidentifiedArtifacts(); |
317 javac_state.removeUnidentifiedArtifacts(); |
307 } |
318 } |
308 // Go through all sources and taint all packages that miss artifacts. |
319 // Go through all sources and taint all packages that miss artifacts. |
309 javac_state.taintPackagesThatMissArtifacts(); |
320 javac_state.taintPackagesThatMissArtifacts(); |
310 |
321 |
336 // Do the compilations, repeatedly until no tainted packages exist. |
347 // Do the compilations, repeatedly until no tainted packages exist. |
337 boolean again; |
348 boolean again; |
338 // Collect the name of all compiled packages. |
349 // Collect the name of all compiled packages. |
339 Set<String> recently_compiled = new HashSet<>(); |
350 Set<String> recently_compiled = new HashSet<>(); |
340 boolean[] rc = new boolean[1]; |
351 boolean[] rc = new boolean[1]; |
|
352 Sjavac sjavac; |
|
353 boolean background = Util.extractBooleanOption("background", options.getServerConf(), true); |
341 do { |
354 do { |
342 // Clean out artifacts in tainted packages. |
355 // Clean out artifacts in tainted packages. |
343 javac_state.deleteClassArtifactsInTaintedPackages(); |
356 javac_state.deleteClassArtifactsInTaintedPackages(); |
344 // Create a JavacService to delegate the actual compilation to. |
357 // Create an sjavac implementation to be used for compilation |
345 // Currently sjavac always connects to a server through a socket |
358 if (background) { |
346 // regardless if sjavac runs as a background service or not. |
359 sjavac = new SjavacClient(options); |
347 // This will most likely change in the future. |
360 } else { |
348 JavacService javacService = new JavacServiceClient(options.getServerConf()); |
361 int poolsize = Util.extractIntOption("poolsize", options.getServerConf()); |
349 again = javac_state.performJavaCompilations(javacService, options, recently_compiled, rc); |
362 if (poolsize <= 0) |
|
363 poolsize = Runtime.getRuntime().availableProcessors(); |
|
364 sjavac = new PooledSjavac(new SjavacImpl(), poolsize); |
|
365 } |
|
366 |
|
367 again = javac_state.performJavaCompilations(sjavac, options, recently_compiled, rc); |
350 if (!rc[0]) break; |
368 if (!rc[0]) break; |
351 } while (again); |
369 } while (again); |
352 // Only update the state if the compile went well. |
370 // Only update the state if the compile went well. |
353 if (rc[0]) { |
371 if (rc[0]) { |
354 javac_state.save(); |
372 javac_state.save(); |
355 // Reflatten only the artifacts. |
373 // Reflatten only the artifacts. |
356 javac_state.now().flattenArtifacts(modules); |
374 javac_state.now().flattenArtifacts(modules); |
357 // Remove artifacts that were generated during the last compile, but not this one. |
375 // Remove artifacts that were generated during the last compile, but not this one. |
358 javac_state.removeSuperfluousArtifacts(recently_compiled); |
376 javac_state.removeSuperfluousArtifacts(recently_compiled); |
359 } |
377 } |
|
378 if (!background) |
|
379 sjavac.shutdown(); |
360 return rc[0] ? 0 : -1; |
380 return rc[0] ? 0 : -1; |
361 } catch (ProblemException e) { |
381 } catch (ProblemException e) { |
362 Log.error(e.getMessage()); |
382 Log.error(e.getMessage()); |
363 return -1; |
383 return -1; |
364 } catch (Exception e) { |
384 } catch (Exception e) { |
373 |
393 |
374 if (options.getDestDir() == null) { |
394 if (options.getDestDir() == null) { |
375 err = "Please specify output directory."; |
395 err = "Please specify output directory."; |
376 } else if (options.isJavaFilesAmongJavacArgs()) { |
396 } else if (options.isJavaFilesAmongJavacArgs()) { |
377 err = "Sjavac does not handle explicit compilation of single .java files."; |
397 err = "Sjavac does not handle explicit compilation of single .java files."; |
378 } else if (options.isAtFilePresent()) { |
|
379 err = "Sjavac does not handle @-files."; |
|
380 } else if (options.getServerConf() == null) { |
398 } else if (options.getServerConf() == null) { |
381 err = "No server configuration provided."; |
399 err = "No server configuration provided."; |
382 } else if (!options.getImplicitPolicy().equals("none")) { |
400 } else if (!options.getImplicitPolicy().equals("none")) { |
383 err = "The only allowed setting for sjavac is -implicit:none"; |
401 err = "The only allowed setting for sjavac is -implicit:none"; |
384 } else if (options.getSources().isEmpty()) { |
402 } else if (options.getSources().isEmpty()) { |