1 /* |
|
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 package sun.rmi.rmic.newrmic; |
|
27 |
|
28 import com.sun.javadoc.ClassDoc; |
|
29 import com.sun.javadoc.RootDoc; |
|
30 import java.io.File; |
|
31 import java.io.FileNotFoundException; |
|
32 import java.io.IOException; |
|
33 import java.io.OutputStream; |
|
34 import java.io.PrintStream; |
|
35 import java.io.PrintWriter; |
|
36 import java.lang.reflect.Constructor; |
|
37 import java.lang.reflect.InvocationTargetException; |
|
38 import java.util.ArrayList; |
|
39 import java.util.Collections; |
|
40 import java.util.HashMap; |
|
41 import java.util.HashSet; |
|
42 import java.util.List; |
|
43 import java.util.Map; |
|
44 import java.util.Set; |
|
45 import sun.rmi.rmic.newrmic.jrmp.JrmpGenerator; |
|
46 import sun.tools.util.CommandLine; |
|
47 |
|
48 /** |
|
49 * The rmic front end. This class contains the "main" method for rmic |
|
50 * command line invocation. |
|
51 * |
|
52 * A Main instance contains the stream to output error messages and |
|
53 * other diagnostics to. |
|
54 * |
|
55 * An rmic compilation batch (for example, one rmic command line |
|
56 * invocation) is executed by invoking the "compile" method of a Main |
|
57 * instance. |
|
58 * |
|
59 * WARNING: The contents of this source file are not part of any |
|
60 * supported API. Code that depends on them does so at its own risk: |
|
61 * they are subject to change or removal without notice. |
|
62 * |
|
63 * NOTE: If and when there is a J2SE API for invoking SDK tools, this |
|
64 * class should be updated to support that API. |
|
65 * |
|
66 * NOTE: This class is the front end for a "new" rmic implementation, |
|
67 * which uses javadoc and the doclet API for reading class files and |
|
68 * javac for compiling generated source files. This implementation is |
|
69 * incomplete: it lacks any CORBA-based back end implementations, and |
|
70 * thus the command line options "-idl", "-iiop", and their related |
|
71 * options are not yet supported. The front end for the "old", |
|
72 * oldjavac-based rmic implementation is sun.rmi.rmic.Main. |
|
73 * |
|
74 * @author Peter Jones |
|
75 **/ |
|
76 public class Main { |
|
77 |
|
78 /* |
|
79 * Implementation note: |
|
80 * |
|
81 * In order to use the doclet API to read class files, much of |
|
82 * this implementation of rmic executes as a doclet within an |
|
83 * invocation of javadoc. This class is used as the doclet class |
|
84 * for such javadoc invocations, via its static "start" and |
|
85 * "optionLength" methods. There is one javadoc invocation per |
|
86 * rmic compilation batch. |
|
87 * |
|
88 * The only guaranteed way to pass data to a doclet through a |
|
89 * javadoc invocation is through doclet-specific options on the |
|
90 * javadoc "command line". Rather than passing numerous pieces of |
|
91 * individual data in string form as javadoc options, we use a |
|
92 * single doclet-specific option ("-batchID") to pass a numeric |
|
93 * identifier that uniquely identifies the rmic compilation batch |
|
94 * that the javadoc invocation is for, and that identifier can |
|
95 * then be used as a key in a global table to retrieve an object |
|
96 * containing all of batch-specific data (rmic command line |
|
97 * arguments, etc.). |
|
98 */ |
|
99 |
|
100 /** guards "batchCount" */ |
|
101 private static final Object batchCountLock = new Object(); |
|
102 |
|
103 /** number of batches run; used to generated batch IDs */ |
|
104 private static long batchCount = 0; |
|
105 |
|
106 /** maps batch ID to batch data */ |
|
107 private static final Map<Long,Batch> batchTable = |
|
108 Collections.synchronizedMap(new HashMap<Long,Batch>()); |
|
109 |
|
110 /** stream to output error messages and other diagnostics to */ |
|
111 private final PrintStream out; |
|
112 |
|
113 /** name of this program, to use in error messages */ |
|
114 private final String program; |
|
115 |
|
116 /** |
|
117 * Command line entry point. |
|
118 **/ |
|
119 public static void main(String[] args) { |
|
120 Main rmic = new Main(System.err, "rmic"); |
|
121 System.exit(rmic.compile(args) ? 0 : 1); |
|
122 } |
|
123 |
|
124 /** |
|
125 * Creates a Main instance that writes output to the specified |
|
126 * stream. The specified program name is used in error messages. |
|
127 **/ |
|
128 public Main(OutputStream out, String program) { |
|
129 this.out = out instanceof PrintStream ? |
|
130 (PrintStream) out : new PrintStream(out); |
|
131 this.program = program; |
|
132 } |
|
133 |
|
134 /** |
|
135 * Compiles a batch of input classes, as given by the specified |
|
136 * command line arguments. Protocol-specific generators are |
|
137 * determined by the choice options on the command line. Returns |
|
138 * true if successful, or false if an error occurred. |
|
139 * |
|
140 * NOTE: This method is retained for transitional consistency with |
|
141 * previous implementations. |
|
142 **/ |
|
143 public boolean compile(String[] args) { |
|
144 long startTime = System.currentTimeMillis(); |
|
145 |
|
146 long batchID; |
|
147 synchronized (batchCountLock) { |
|
148 batchID = batchCount++; // assign batch ID |
|
149 } |
|
150 |
|
151 // process command line |
|
152 Batch batch = parseArgs(args); |
|
153 if (batch == null) { |
|
154 return false; // terminate if error occurred |
|
155 } |
|
156 |
|
157 /* |
|
158 * With the batch data retrievable in the global table, run |
|
159 * javadoc to continue the rest of the batch's compliation as |
|
160 * a doclet. |
|
161 */ |
|
162 boolean status; |
|
163 try { |
|
164 batchTable.put(batchID, batch); |
|
165 status = invokeJavadoc(batch, batchID); |
|
166 } finally { |
|
167 batchTable.remove(batchID); |
|
168 } |
|
169 |
|
170 if (batch.verbose) { |
|
171 long deltaTime = System.currentTimeMillis() - startTime; |
|
172 output(Resources.getText("rmic.done_in", |
|
173 Long.toString(deltaTime))); |
|
174 } |
|
175 |
|
176 return status; |
|
177 } |
|
178 |
|
179 /** |
|
180 * Prints the specified string to the output stream of this Main |
|
181 * instance. |
|
182 **/ |
|
183 public void output(String msg) { |
|
184 out.println(msg); |
|
185 } |
|
186 |
|
187 /** |
|
188 * Prints an error message to the output stream of this Main |
|
189 * instance. The first argument is used as a key in rmic's |
|
190 * resource bundle, and the rest of the arguments are used as |
|
191 * arguments in the formatting of the resource string. |
|
192 **/ |
|
193 public void error(String msg, String... args) { |
|
194 output(Resources.getText(msg, args)); |
|
195 } |
|
196 |
|
197 /** |
|
198 * Prints rmic's usage message to the output stream of this Main |
|
199 * instance. |
|
200 * |
|
201 * This method is public so that it can be used by the "parseArgs" |
|
202 * methods of Generator implementations. |
|
203 **/ |
|
204 public void usage() { |
|
205 error("rmic.usage", program); |
|
206 } |
|
207 |
|
208 /** |
|
209 * Processes rmic command line arguments. Returns a Batch object |
|
210 * representing the command line arguments if successful, or null |
|
211 * if an error occurred. Processed elements of the args array are |
|
212 * set to null. |
|
213 **/ |
|
214 private Batch parseArgs(String[] args) { |
|
215 Batch batch = new Batch(); |
|
216 |
|
217 /* |
|
218 * Pre-process command line for @file arguments. |
|
219 */ |
|
220 try { |
|
221 args = CommandLine.parse(args); |
|
222 } catch (FileNotFoundException e) { |
|
223 error("rmic.cant.read", e.getMessage()); |
|
224 return null; |
|
225 } catch (IOException e) { |
|
226 e.printStackTrace(out); |
|
227 return null; |
|
228 } |
|
229 |
|
230 for (int i = 0; i < args.length; i++) { |
|
231 |
|
232 if (args[i] == null) { |
|
233 // already processed by a generator |
|
234 continue; |
|
235 |
|
236 } else if (args[i].equals("-Xnew")) { |
|
237 // we're already using the "new" implementation |
|
238 args[i] = null; |
|
239 |
|
240 } else if (args[i].equals("-show")) { |
|
241 // obselete: fail |
|
242 error("rmic.option.unsupported", args[i]); |
|
243 usage(); |
|
244 return null; |
|
245 |
|
246 } else if (args[i].equals("-O")) { |
|
247 // obselete: warn but tolerate |
|
248 error("rmic.option.unsupported", args[i]); |
|
249 args[i] = null; |
|
250 |
|
251 } else if (args[i].equals("-debug")) { |
|
252 // obselete: warn but tolerate |
|
253 error("rmic.option.unsupported", args[i]); |
|
254 args[i] = null; |
|
255 |
|
256 } else if (args[i].equals("-depend")) { |
|
257 // obselete: warn but tolerate |
|
258 // REMIND: should this fail instead? |
|
259 error("rmic.option.unsupported", args[i]); |
|
260 args[i] = null; |
|
261 |
|
262 } else if (args[i].equals("-keep") || |
|
263 args[i].equals("-keepgenerated")) |
|
264 { |
|
265 batch.keepGenerated = true; |
|
266 args[i] = null; |
|
267 |
|
268 } else if (args[i].equals("-g")) { |
|
269 batch.debug = true; |
|
270 args[i] = null; |
|
271 |
|
272 } else if (args[i].equals("-nowarn")) { |
|
273 batch.noWarn = true; |
|
274 args[i] = null; |
|
275 |
|
276 } else if (args[i].equals("-nowrite")) { |
|
277 batch.noWrite = true; |
|
278 args[i] = null; |
|
279 |
|
280 } else if (args[i].equals("-verbose")) { |
|
281 batch.verbose = true; |
|
282 args[i] = null; |
|
283 |
|
284 } else if (args[i].equals("-Xnocompile")) { |
|
285 batch.noCompile = true; |
|
286 batch.keepGenerated = true; |
|
287 args[i] = null; |
|
288 |
|
289 } else if (args[i].equals("-bootclasspath")) { |
|
290 if ((i + 1) >= args.length) { |
|
291 error("rmic.option.requires.argument", args[i]); |
|
292 usage(); |
|
293 return null; |
|
294 } |
|
295 if (batch.bootClassPath != null) { |
|
296 error("rmic.option.already.seen", args[i]); |
|
297 usage(); |
|
298 return null; |
|
299 } |
|
300 args[i] = null; |
|
301 batch.bootClassPath = args[++i]; |
|
302 assert batch.bootClassPath != null; |
|
303 args[i] = null; |
|
304 |
|
305 } else if (args[i].equals("-extdirs")) { |
|
306 if ((i + 1) >= args.length) { |
|
307 error("rmic.option.requires.argument", args[i]); |
|
308 usage(); |
|
309 return null; |
|
310 } |
|
311 if (batch.extDirs != null) { |
|
312 error("rmic.option.already.seen", args[i]); |
|
313 usage(); |
|
314 return null; |
|
315 } |
|
316 args[i] = null; |
|
317 batch.extDirs = args[++i]; |
|
318 assert batch.extDirs != null; |
|
319 args[i] = null; |
|
320 |
|
321 } else if (args[i].equals("-classpath")) { |
|
322 if ((i + 1) >= args.length) { |
|
323 error("rmic.option.requires.argument", args[i]); |
|
324 usage(); |
|
325 return null; |
|
326 } |
|
327 if (batch.classPath != null) { |
|
328 error("rmic.option.already.seen", args[i]); |
|
329 usage(); |
|
330 return null; |
|
331 } |
|
332 args[i] = null; |
|
333 batch.classPath = args[++i]; |
|
334 assert batch.classPath != null; |
|
335 args[i] = null; |
|
336 |
|
337 } else if (args[i].equals("-d")) { |
|
338 if ((i + 1) >= args.length) { |
|
339 error("rmic.option.requires.argument", args[i]); |
|
340 usage(); |
|
341 return null; |
|
342 } |
|
343 if (batch.destDir != null) { |
|
344 error("rmic.option.already.seen", args[i]); |
|
345 usage(); |
|
346 return null; |
|
347 } |
|
348 args[i] = null; |
|
349 batch.destDir = new File(args[++i]); |
|
350 assert batch.destDir != null; |
|
351 args[i] = null; |
|
352 if (!batch.destDir.exists()) { |
|
353 error("rmic.no.such.directory", batch.destDir.getPath()); |
|
354 usage(); |
|
355 return null; |
|
356 } |
|
357 |
|
358 } else if (args[i].equals("-v1.1") || |
|
359 args[i].equals("-vcompat") || |
|
360 args[i].equals("-v1.2")) |
|
361 { |
|
362 Generator gen = new JrmpGenerator(); |
|
363 batch.generators.add(gen); |
|
364 // JrmpGenerator only requires base BatchEnvironment class |
|
365 if (!gen.parseArgs(args, this)) { |
|
366 return null; |
|
367 } |
|
368 |
|
369 } else if (args[i].equalsIgnoreCase("-iiop")) { |
|
370 error("rmic.option.unimplemented", args[i]); |
|
371 return null; |
|
372 |
|
373 // Generator gen = new IiopGenerator(); |
|
374 // batch.generators.add(gen); |
|
375 // if (!batch.envClass.isAssignableFrom(gen.envClass())) { |
|
376 // error("rmic.cannot.use.both", |
|
377 // batch.envClass.getName(), gen.envClass().getName()); |
|
378 // return null; |
|
379 // } |
|
380 // batch.envClass = gen.envClass(); |
|
381 // if (!gen.parseArgs(args, this)) { |
|
382 // return null; |
|
383 // } |
|
384 |
|
385 } else if (args[i].equalsIgnoreCase("-idl")) { |
|
386 error("rmic.option.unimplemented", args[i]); |
|
387 return null; |
|
388 |
|
389 // see implementation sketch above |
|
390 |
|
391 } else if (args[i].equalsIgnoreCase("-xprint")) { |
|
392 error("rmic.option.unimplemented", args[i]); |
|
393 return null; |
|
394 |
|
395 // see implementation sketch above |
|
396 } |
|
397 } |
|
398 |
|
399 /* |
|
400 * At this point, all that remains non-null in the args |
|
401 * array are input class names or illegal options. |
|
402 */ |
|
403 for (int i = 0; i < args.length; i++) { |
|
404 if (args[i] != null) { |
|
405 if (args[i].startsWith("-")) { |
|
406 error("rmic.no.such.option", args[i]); |
|
407 usage(); |
|
408 return null; |
|
409 } else { |
|
410 batch.classes.add(args[i]); |
|
411 } |
|
412 } |
|
413 } |
|
414 if (batch.classes.isEmpty()) { |
|
415 usage(); |
|
416 return null; |
|
417 } |
|
418 |
|
419 /* |
|
420 * If options did not specify at least one protocol-specific |
|
421 * generator, then JRMP is the default. |
|
422 */ |
|
423 if (batch.generators.isEmpty()) { |
|
424 batch.generators.add(new JrmpGenerator()); |
|
425 } |
|
426 return batch; |
|
427 } |
|
428 |
|
429 /** |
|
430 * Doclet class entry point. |
|
431 **/ |
|
432 public static boolean start(RootDoc rootDoc) { |
|
433 |
|
434 /* |
|
435 * Find batch ID among javadoc options, and retrieve |
|
436 * corresponding batch data from global table. |
|
437 */ |
|
438 long batchID = -1; |
|
439 for (String[] option : rootDoc.options()) { |
|
440 if (option[0].equals("-batchID")) { |
|
441 try { |
|
442 batchID = Long.parseLong(option[1]); |
|
443 } catch (NumberFormatException e) { |
|
444 throw new AssertionError(e); |
|
445 } |
|
446 } |
|
447 } |
|
448 Batch batch = batchTable.get(batchID); |
|
449 assert batch != null; |
|
450 |
|
451 /* |
|
452 * Construct batch environment using class agreed upon by |
|
453 * generator implementations. |
|
454 */ |
|
455 BatchEnvironment env; |
|
456 try { |
|
457 Constructor<? extends BatchEnvironment> cons = |
|
458 batch.envClass.getConstructor(new Class<?>[] { RootDoc.class }); |
|
459 env = cons.newInstance(rootDoc); |
|
460 } catch (NoSuchMethodException e) { |
|
461 throw new AssertionError(e); |
|
462 } catch (IllegalAccessException e) { |
|
463 throw new AssertionError(e); |
|
464 } catch (InstantiationException e) { |
|
465 throw new AssertionError(e); |
|
466 } catch (InvocationTargetException e) { |
|
467 throw new AssertionError(e); |
|
468 } |
|
469 |
|
470 env.setVerbose(batch.verbose); |
|
471 |
|
472 /* |
|
473 * Determine the destination directory (the top of the package |
|
474 * hierarchy) for the output of this batch; if no destination |
|
475 * directory was specified on the command line, then the |
|
476 * default is the current working directory. |
|
477 */ |
|
478 File destDir = batch.destDir; |
|
479 if (destDir == null) { |
|
480 destDir = new File(System.getProperty("user.dir")); |
|
481 } |
|
482 |
|
483 /* |
|
484 * Run each input class through each generator. |
|
485 */ |
|
486 for (String inputClassName : batch.classes) { |
|
487 ClassDoc inputClass = rootDoc.classNamed(inputClassName); |
|
488 try { |
|
489 for (Generator gen : batch.generators) { |
|
490 gen.generate(env, inputClass, destDir); |
|
491 } |
|
492 } catch (NullPointerException e) { |
|
493 /* |
|
494 * We assume that this means that some class that was |
|
495 * needed (perhaps even a bootstrap class) was not |
|
496 * found, and that javadoc has already reported this |
|
497 * as an error. There is nothing for us to do here |
|
498 * but try to continue with the next input class. |
|
499 * |
|
500 * REMIND: More explicit error checking throughout |
|
501 * would be preferable, however. |
|
502 */ |
|
503 } |
|
504 } |
|
505 |
|
506 /* |
|
507 * Compile any generated source files, if configured to do so. |
|
508 */ |
|
509 boolean status = true; |
|
510 List<File> generatedFiles = env.generatedFiles(); |
|
511 if (!batch.noCompile && !batch.noWrite && !generatedFiles.isEmpty()) { |
|
512 status = batch.enclosingMain().invokeJavac(batch, generatedFiles); |
|
513 } |
|
514 |
|
515 /* |
|
516 * Delete any generated source files, if configured to do so. |
|
517 */ |
|
518 if (!batch.keepGenerated) { |
|
519 for (File file : generatedFiles) { |
|
520 file.delete(); |
|
521 } |
|
522 } |
|
523 |
|
524 return status; |
|
525 } |
|
526 |
|
527 /** |
|
528 * Doclet class method that indicates that this doclet class |
|
529 * recognizes (only) the "-batchID" option on the javadoc command |
|
530 * line, and that the "-batchID" option comprises two arguments on |
|
531 * the javadoc command line. |
|
532 **/ |
|
533 public static int optionLength(String option) { |
|
534 if (option.equals("-batchID")) { |
|
535 return 2; |
|
536 } else { |
|
537 return 0; |
|
538 } |
|
539 } |
|
540 |
|
541 /** |
|
542 * Runs the javadoc tool to invoke this class as a doclet, passing |
|
543 * command line options derived from the specified batch data and |
|
544 * indicating the specified batch ID. |
|
545 * |
|
546 * NOTE: This method currently uses a J2SE-internal API to run |
|
547 * javadoc. If and when there is a J2SE API for invoking SDK |
|
548 * tools, this method should be updated to use that API instead. |
|
549 **/ |
|
550 private boolean invokeJavadoc(Batch batch, long batchID) { |
|
551 List<String> javadocArgs = new ArrayList<String>(); |
|
552 |
|
553 // include all types, regardless of language-level access |
|
554 javadocArgs.add("-private"); |
|
555 |
|
556 // inputs are class names, not source files |
|
557 javadocArgs.add("-Xclasses"); |
|
558 |
|
559 // reproduce relevant options from rmic invocation |
|
560 if (batch.verbose) { |
|
561 javadocArgs.add("-verbose"); |
|
562 } |
|
563 if (batch.bootClassPath != null) { |
|
564 javadocArgs.add("-bootclasspath"); |
|
565 javadocArgs.add(batch.bootClassPath); |
|
566 } |
|
567 if (batch.extDirs != null) { |
|
568 javadocArgs.add("-extdirs"); |
|
569 javadocArgs.add(batch.extDirs); |
|
570 } |
|
571 if (batch.classPath != null) { |
|
572 javadocArgs.add("-classpath"); |
|
573 javadocArgs.add(batch.classPath); |
|
574 } |
|
575 |
|
576 // specify batch ID |
|
577 javadocArgs.add("-batchID"); |
|
578 javadocArgs.add(Long.toString(batchID)); |
|
579 |
|
580 /* |
|
581 * Run javadoc on union of rmic input classes and all |
|
582 * generators' bootstrap classes, so that they will all be |
|
583 * available to the doclet code. |
|
584 */ |
|
585 Set<String> classNames = new HashSet<String>(); |
|
586 for (Generator gen : batch.generators) { |
|
587 classNames.addAll(gen.bootstrapClassNames()); |
|
588 } |
|
589 classNames.addAll(batch.classes); |
|
590 for (String s : classNames) { |
|
591 javadocArgs.add(s); |
|
592 } |
|
593 |
|
594 // run javadoc with our program name and output stream |
|
595 int status = com.sun.tools.javadoc.Main.execute( |
|
596 program, |
|
597 new PrintWriter(out, true), |
|
598 new PrintWriter(out, true), |
|
599 new PrintWriter(out, true), |
|
600 this.getClass().getName(), // doclet class is this class |
|
601 javadocArgs.toArray(new String[javadocArgs.size()])); |
|
602 return status == 0; |
|
603 } |
|
604 |
|
605 /** |
|
606 * Runs the javac tool to compile the specified source files, |
|
607 * passing command line options derived from the specified batch |
|
608 * data. |
|
609 * |
|
610 * NOTE: This method currently uses a J2SE-internal API to run |
|
611 * javac. If and when there is a J2SE API for invoking SDK tools, |
|
612 * this method should be updated to use that API instead. |
|
613 **/ |
|
614 private boolean invokeJavac(Batch batch, List<File> files) { |
|
615 List<String> javacArgs = new ArrayList<String>(); |
|
616 |
|
617 // rmic never wants to display javac warnings |
|
618 javacArgs.add("-nowarn"); |
|
619 |
|
620 // reproduce relevant options from rmic invocation |
|
621 if (batch.debug) { |
|
622 javacArgs.add("-g"); |
|
623 } |
|
624 if (batch.verbose) { |
|
625 javacArgs.add("-verbose"); |
|
626 } |
|
627 if (batch.bootClassPath != null) { |
|
628 javacArgs.add("-bootclasspath"); |
|
629 javacArgs.add(batch.bootClassPath); |
|
630 } |
|
631 if (batch.extDirs != null) { |
|
632 javacArgs.add("-extdirs"); |
|
633 javacArgs.add(batch.extDirs); |
|
634 } |
|
635 if (batch.classPath != null) { |
|
636 javacArgs.add("-classpath"); |
|
637 javacArgs.add(batch.classPath); |
|
638 } |
|
639 |
|
640 /* |
|
641 * For now, rmic still always produces class files that have a |
|
642 * class file format version compatible with JDK 1.1. |
|
643 */ |
|
644 javacArgs.add("-source"); |
|
645 javacArgs.add("1.3"); |
|
646 javacArgs.add("-target"); |
|
647 javacArgs.add("1.1"); |
|
648 |
|
649 // add source files to compile |
|
650 for (File file : files) { |
|
651 javacArgs.add(file.getPath()); |
|
652 } |
|
653 |
|
654 // run javac with our output stream |
|
655 int status = com.sun.tools.javac.Main.compile( |
|
656 javacArgs.toArray(new String[javacArgs.size()]), |
|
657 new PrintWriter(out, true)); |
|
658 return status == 0; |
|
659 } |
|
660 |
|
661 /** |
|
662 * The data for an rmic compliation batch: the processed command |
|
663 * line arguments. |
|
664 **/ |
|
665 private class Batch { |
|
666 boolean keepGenerated = false; // -keep or -keepgenerated |
|
667 boolean debug = false; // -g |
|
668 boolean noWarn = false; // -nowarn |
|
669 boolean noWrite = false; // -nowrite |
|
670 boolean verbose = false; // -verbose |
|
671 boolean noCompile = false; // -Xnocompile |
|
672 String bootClassPath = null; // -bootclasspath |
|
673 String extDirs = null; // -extdirs |
|
674 String classPath = null; // -classpath |
|
675 File destDir = null; // -d |
|
676 List<Generator> generators = new ArrayList<Generator>(); |
|
677 Class<? extends BatchEnvironment> envClass = BatchEnvironment.class; |
|
678 List<String> classes = new ArrayList<String>(); |
|
679 |
|
680 Batch() { } |
|
681 |
|
682 /** |
|
683 * Returns the Main instance for this batch. |
|
684 **/ |
|
685 Main enclosingMain() { |
|
686 return Main.this; |
|
687 } |
|
688 } |
|
689 } |
|