1. /*
  2. * Copyright 2000-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant.taskdefs;
  18. import java.io.File;
  19. import org.apache.tools.ant.BuildException;
  20. import org.apache.tools.ant.DirectoryScanner;
  21. import org.apache.tools.ant.Project;
  22. import org.apache.tools.ant.taskdefs.compilers.CompilerAdapter;
  23. import org.apache.tools.ant.taskdefs.compilers.CompilerAdapterFactory;
  24. import org.apache.tools.ant.types.Path;
  25. import org.apache.tools.ant.types.Reference;
  26. import org.apache.tools.ant.util.GlobPatternMapper;
  27. import org.apache.tools.ant.util.JavaEnvUtils;
  28. import org.apache.tools.ant.util.SourceFileScanner;
  29. import org.apache.tools.ant.util.facade.FacadeTaskHelper;
  30. /**
  31. * Compiles Java source files. This task can take the following
  32. * arguments:
  33. * <ul>
  34. * <li>sourcedir
  35. * <li>destdir
  36. * <li>deprecation
  37. * <li>classpath
  38. * <li>bootclasspath
  39. * <li>extdirs
  40. * <li>optimize
  41. * <li>debug
  42. * <li>encoding
  43. * <li>target
  44. * <li>depend
  45. * <li>verbose
  46. * <li>failonerror
  47. * <li>includeantruntime
  48. * <li>includejavaruntime
  49. * <li>source
  50. * <li>compiler
  51. * </ul>
  52. * Of these arguments, the <b>sourcedir</b> and <b>destdir</b> are required.
  53. * <p>
  54. * When this task executes, it will recursively scan the sourcedir and
  55. * destdir looking for Java source files to compile. This task makes its
  56. * compile decision based on timestamp.
  57. *
  58. * @version $Revision: 1.115.2.6 $
  59. *
  60. * @since Ant 1.1
  61. *
  62. * @ant.task category="java"
  63. */
  64. public class Javac extends MatchingTask {
  65. private static final String FAIL_MSG
  66. = "Compile failed; see the compiler error output for details.";
  67. private Path src;
  68. private File destDir;
  69. private Path compileClasspath;
  70. private Path compileSourcepath;
  71. private String encoding;
  72. private boolean debug = false;
  73. private boolean optimize = false;
  74. private boolean deprecation = false;
  75. private boolean depend = false;
  76. private boolean verbose = false;
  77. private String target;
  78. private Path bootclasspath;
  79. private Path extdirs;
  80. private boolean includeAntRuntime = true;
  81. private boolean includeJavaRuntime = false;
  82. private boolean fork = false;
  83. private String forkedExecutable = null;
  84. private boolean nowarn = false;
  85. private String memoryInitialSize;
  86. private String memoryMaximumSize;
  87. private FacadeTaskHelper facade = null;
  88. protected boolean failOnError = true;
  89. protected boolean listFiles = false;
  90. protected File[] compileList = new File[0];
  91. private String source;
  92. private String debugLevel;
  93. private File tmpDir;
  94. /**
  95. * Javac task for compilation of Java files.
  96. */
  97. public Javac() {
  98. if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) {
  99. facade = new FacadeTaskHelper("javac1.1");
  100. } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_2)) {
  101. facade = new FacadeTaskHelper("javac1.2");
  102. } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_3)) {
  103. facade = new FacadeTaskHelper("javac1.3");
  104. } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_4)) {
  105. facade = new FacadeTaskHelper("javac1.4");
  106. } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_5)) {
  107. facade = new FacadeTaskHelper("javac1.5");
  108. } else {
  109. facade = new FacadeTaskHelper("classic");
  110. }
  111. }
  112. /**
  113. * Get the value of debugLevel.
  114. * @return value of debugLevel.
  115. */
  116. public String getDebugLevel() {
  117. return debugLevel;
  118. }
  119. /**
  120. * Keyword list to be appended to the -g command-line switch.
  121. *
  122. * This will be ignored by all implementations except modern
  123. * and classic(ver >= 1.2). Legal values are none or a
  124. * comma-separated list of the following keywords: lines, vars,
  125. * and source. If debuglevel is not specified, by default, :none
  126. * will be appended to -g. If debug is not turned on, this attribute
  127. * will be ignored.
  128. *
  129. * @param v Value to assign to debugLevel.
  130. */
  131. public void setDebugLevel(String v) {
  132. this.debugLevel = v;
  133. }
  134. /**
  135. * Get the value of source.
  136. * @return value of source.
  137. */
  138. public String getSource() {
  139. return source;
  140. }
  141. /**
  142. * Value of the -source command-line switch; will be ignored
  143. * by all implementations except modern and jikes.
  144. *
  145. * If you use this attribute together with jikes, you must
  146. * make sure that your version of jikes supports the -source switch.
  147. * Legal values are 1.3, 1.4 and 1.5 - by default, no -source argument
  148. * will be used at all.
  149. *
  150. * @param v Value to assign to source.
  151. */
  152. public void setSource(String v) {
  153. this.source = v;
  154. }
  155. /**
  156. * Adds a path for source compilation.
  157. *
  158. * @return a nested src element.
  159. */
  160. public Path createSrc() {
  161. if (src == null) {
  162. src = new Path(getProject());
  163. }
  164. return src.createPath();
  165. }
  166. /**
  167. * Recreate src.
  168. *
  169. * @return a nested src element.
  170. */
  171. protected Path recreateSrc() {
  172. src = null;
  173. return createSrc();
  174. }
  175. /**
  176. * Set the source directories to find the source Java files.
  177. * @param srcDir the source directories as a path
  178. */
  179. public void setSrcdir(Path srcDir) {
  180. if (src == null) {
  181. src = srcDir;
  182. } else {
  183. src.append(srcDir);
  184. }
  185. }
  186. /**
  187. * Gets the source dirs to find the source java files.
  188. * @return the source directories as a path
  189. */
  190. public Path getSrcdir() {
  191. return src;
  192. }
  193. /**
  194. * Set the destination directory into which the Java source
  195. * files should be compiled.
  196. * @param destDir the destination director
  197. */
  198. public void setDestdir(File destDir) {
  199. this.destDir = destDir;
  200. }
  201. /**
  202. * Gets the destination directory into which the java source files
  203. * should be compiled.
  204. * @return the destination directory
  205. */
  206. public File getDestdir() {
  207. return destDir;
  208. }
  209. /**
  210. * Set the sourcepath to be used for this compilation.
  211. * @param sourcepath the source path
  212. */
  213. public void setSourcepath(Path sourcepath) {
  214. if (compileSourcepath == null) {
  215. compileSourcepath = sourcepath;
  216. } else {
  217. compileSourcepath.append(sourcepath);
  218. }
  219. }
  220. /**
  221. * Gets the sourcepath to be used for this compilation.
  222. * @return the source path
  223. */
  224. public Path getSourcepath() {
  225. return compileSourcepath;
  226. }
  227. /**
  228. * Adds a path to sourcepath.
  229. * @return a sourcepath to be configured
  230. */
  231. public Path createSourcepath() {
  232. if (compileSourcepath == null) {
  233. compileSourcepath = new Path(getProject());
  234. }
  235. return compileSourcepath.createPath();
  236. }
  237. /**
  238. * Adds a reference to a source path defined elsewhere.
  239. * @param r a reference to a source path
  240. */
  241. public void setSourcepathRef(Reference r) {
  242. createSourcepath().setRefid(r);
  243. }
  244. /**
  245. * Set the classpath to be used for this compilation.
  246. *
  247. * @param classpath an Ant Path object containing the compilation classpath.
  248. */
  249. public void setClasspath(Path classpath) {
  250. if (compileClasspath == null) {
  251. compileClasspath = classpath;
  252. } else {
  253. compileClasspath.append(classpath);
  254. }
  255. }
  256. /**
  257. * Gets the classpath to be used for this compilation.
  258. * @return the class path
  259. */
  260. public Path getClasspath() {
  261. return compileClasspath;
  262. }
  263. /**
  264. * Adds a path to the classpath.
  265. * @return a class path to be configured
  266. */
  267. public Path createClasspath() {
  268. if (compileClasspath == null) {
  269. compileClasspath = new Path(getProject());
  270. }
  271. return compileClasspath.createPath();
  272. }
  273. /**
  274. * Adds a reference to a classpath defined elsewhere.
  275. * @param r a reference to a classpath
  276. */
  277. public void setClasspathRef(Reference r) {
  278. createClasspath().setRefid(r);
  279. }
  280. /**
  281. * Sets the bootclasspath that will be used to compile the classes
  282. * against.
  283. * @param bootclasspath a path to use as a boot class path (may be more
  284. * than one)
  285. */
  286. public void setBootclasspath(Path bootclasspath) {
  287. if (this.bootclasspath == null) {
  288. this.bootclasspath = bootclasspath;
  289. } else {
  290. this.bootclasspath.append(bootclasspath);
  291. }
  292. }
  293. /**
  294. * Gets the bootclasspath that will be used to compile the classes
  295. * against.
  296. * @return the boot path
  297. */
  298. public Path getBootclasspath() {
  299. return bootclasspath;
  300. }
  301. /**
  302. * Adds a path to the bootclasspath.
  303. * @return a path to be configured
  304. */
  305. public Path createBootclasspath() {
  306. if (bootclasspath == null) {
  307. bootclasspath = new Path(getProject());
  308. }
  309. return bootclasspath.createPath();
  310. }
  311. /**
  312. * Adds a reference to a classpath defined elsewhere.
  313. * @param r a reference to a classpath
  314. */
  315. public void setBootClasspathRef(Reference r) {
  316. createBootclasspath().setRefid(r);
  317. }
  318. /**
  319. * Sets the extension directories that will be used during the
  320. * compilation.
  321. * @param extdirs a path
  322. */
  323. public void setExtdirs(Path extdirs) {
  324. if (this.extdirs == null) {
  325. this.extdirs = extdirs;
  326. } else {
  327. this.extdirs.append(extdirs);
  328. }
  329. }
  330. /**
  331. * Gets the extension directories that will be used during the
  332. * compilation.
  333. * @return the extension directories as a path
  334. */
  335. public Path getExtdirs() {
  336. return extdirs;
  337. }
  338. /**
  339. * Adds a path to extdirs.
  340. * @return a path to be configured
  341. */
  342. public Path createExtdirs() {
  343. if (extdirs == null) {
  344. extdirs = new Path(getProject());
  345. }
  346. return extdirs.createPath();
  347. }
  348. /**
  349. * If true, list the source files being handed off to the compiler.
  350. * @param list if true list the source files
  351. */
  352. public void setListfiles(boolean list) {
  353. listFiles = list;
  354. }
  355. /**
  356. * Get the listfiles flag.
  357. * @return the listfiles flag
  358. */
  359. public boolean getListfiles() {
  360. return listFiles;
  361. }
  362. /**
  363. * Indicates whether the build will continue
  364. * even if there are compilation errors; defaults to true.
  365. * @param fail if true halt the build on failure
  366. */
  367. public void setFailonerror(boolean fail) {
  368. failOnError = fail;
  369. }
  370. /**
  371. * @ant.attribute ignore="true"
  372. * @param proceed inverse of failoferror
  373. */
  374. public void setProceed(boolean proceed) {
  375. failOnError = !proceed;
  376. }
  377. /**
  378. * Gets the failonerror flag.
  379. * @return the failonerror flag
  380. */
  381. public boolean getFailonerror() {
  382. return failOnError;
  383. }
  384. /**
  385. * Indicates whether source should be
  386. * compiled with deprecation information; defaults to off.
  387. * @param deprecation if true turn on deprecation information
  388. */
  389. public void setDeprecation(boolean deprecation) {
  390. this.deprecation = deprecation;
  391. }
  392. /**
  393. * Gets the deprecation flag.
  394. * @return the deprecation flag
  395. */
  396. public boolean getDeprecation() {
  397. return deprecation;
  398. }
  399. /**
  400. * The initial size of the memory for the underlying VM
  401. * if javac is run externally; ignored otherwise.
  402. * Defaults to the standard VM memory setting.
  403. * (Examples: 83886080, 81920k, or 80m)
  404. * @param memoryInitialSize string to pass to VM
  405. */
  406. public void setMemoryInitialSize(String memoryInitialSize) {
  407. this.memoryInitialSize = memoryInitialSize;
  408. }
  409. /**
  410. * Gets the memoryInitialSize flag.
  411. * @return the memoryInitialSize flag
  412. */
  413. public String getMemoryInitialSize() {
  414. return memoryInitialSize;
  415. }
  416. /**
  417. * The maximum size of the memory for the underlying VM
  418. * if javac is run externally; ignored otherwise.
  419. * Defaults to the standard VM memory setting.
  420. * (Examples: 83886080, 81920k, or 80m)
  421. * @param memoryMaximumSize string to pass to VM
  422. */
  423. public void setMemoryMaximumSize(String memoryMaximumSize) {
  424. this.memoryMaximumSize = memoryMaximumSize;
  425. }
  426. /**
  427. * Gets the memoryMaximumSize flag.
  428. * @return the memoryMaximumSize flag
  429. */
  430. public String getMemoryMaximumSize() {
  431. return memoryMaximumSize;
  432. }
  433. /**
  434. * Set the Java source file encoding name.
  435. * @param encoding the source file encoding
  436. */
  437. public void setEncoding(String encoding) {
  438. this.encoding = encoding;
  439. }
  440. /**
  441. * Gets the java source file encoding name.
  442. * @return the source file encoding name
  443. */
  444. public String getEncoding() {
  445. return encoding;
  446. }
  447. /**
  448. * Indicates whether source should be compiled
  449. * with debug information; defaults to off.
  450. * @param debug if true compile with debug information
  451. */
  452. public void setDebug(boolean debug) {
  453. this.debug = debug;
  454. }
  455. /**
  456. * Gets the debug flag.
  457. * @return the debug flag
  458. */
  459. public boolean getDebug() {
  460. return debug;
  461. }
  462. /**
  463. * If true, compiles with optimization enabled.
  464. * @param optimize if true compile with optimization enabled
  465. */
  466. public void setOptimize(boolean optimize) {
  467. this.optimize = optimize;
  468. }
  469. /**
  470. * Gets the optimize flag.
  471. * @return the optimize flag
  472. */
  473. public boolean getOptimize() {
  474. return optimize;
  475. }
  476. /**
  477. * Enables dependency-tracking for compilers
  478. * that support this (jikes and classic).
  479. * @param depend if true enable dependency-tracking
  480. */
  481. public void setDepend(boolean depend) {
  482. this.depend = depend;
  483. }
  484. /**
  485. * Gets the depend flag.
  486. * @return the depend flag
  487. */
  488. public boolean getDepend() {
  489. return depend;
  490. }
  491. /**
  492. * If true, asks the compiler for verbose output.
  493. * @param verbose if true, asks the compiler for verbose output
  494. */
  495. public void setVerbose(boolean verbose) {
  496. this.verbose = verbose;
  497. }
  498. /**
  499. * Gets the verbose flag.
  500. * @return the verbose flag
  501. */
  502. public boolean getVerbose() {
  503. return verbose;
  504. }
  505. /**
  506. * Sets the target VM that the classes will be compiled for. Valid
  507. * values depend on the compiler, for jdk 1.4 the valid values are
  508. * "1.1", "1.2", "1.3", "1.4" and "1.5".
  509. * @param target the target VM
  510. */
  511. public void setTarget(String target) {
  512. this.target = target;
  513. }
  514. /**
  515. * Gets the target VM that the classes will be compiled for.
  516. * @return the target VM
  517. */
  518. public String getTarget() {
  519. return target;
  520. }
  521. /**
  522. * If true, includes Ant's own classpath in the classpath.
  523. * @param include if true, includes Ant's own classpath in the classpath
  524. */
  525. public void setIncludeantruntime(boolean include) {
  526. includeAntRuntime = include;
  527. }
  528. /**
  529. * Gets whether or not the ant classpath is to be included in the classpath.
  530. * @return whether or not the ant classpath is to be included in the classpath
  531. */
  532. public boolean getIncludeantruntime() {
  533. return includeAntRuntime;
  534. }
  535. /**
  536. * If true, includes the Java runtime libraries in the classpath.
  537. * @param include if true, includes the Java runtime libraries in the classpath
  538. */
  539. public void setIncludejavaruntime(boolean include) {
  540. includeJavaRuntime = include;
  541. }
  542. /**
  543. * Gets whether or not the java runtime should be included in this
  544. * task's classpath.
  545. * @return the includejavaruntime attribute
  546. */
  547. public boolean getIncludejavaruntime() {
  548. return includeJavaRuntime;
  549. }
  550. /**
  551. * If true, forks the javac compiler.
  552. *
  553. * @param f "true|false|on|off|yes|no"
  554. */
  555. public void setFork(boolean f) {
  556. fork = f;
  557. }
  558. /**
  559. * Sets the name of the javac executable.
  560. *
  561. * <p>Ignored unless fork is true or extJavac has been specified
  562. * as the compiler.</p>
  563. * @param forkExec the name of the executable
  564. */
  565. public void setExecutable(String forkExec) {
  566. forkedExecutable = forkExec;
  567. }
  568. /**
  569. * The value of the executable attribute, if any.
  570. *
  571. * @since Ant 1.6
  572. * @return the name of the java executable
  573. */
  574. public String getExecutable() {
  575. return forkedExecutable;
  576. }
  577. /**
  578. * Is this a forked invocation of JDK's javac?
  579. * @return true if this is a forked invocation
  580. */
  581. public boolean isForkedJavac() {
  582. return fork || "extJavac".equals(getCompiler());
  583. }
  584. /**
  585. * The name of the javac executable to use in fork-mode.
  586. *
  587. * <p>This is either the name specified with the executable
  588. * attribute or the full path of the javac compiler of the VM Ant
  589. * is currently running in - guessed by Ant.</p>
  590. *
  591. * <p>You should <strong>not</strong> invoke this method if you
  592. * want to get the value of the executable command - use {@link
  593. * #getExecutable getExecutable} for this.</p>
  594. * @return the name of the javac executable
  595. */
  596. public String getJavacExecutable() {
  597. if (forkedExecutable == null && isForkedJavac()) {
  598. forkedExecutable = getSystemJavac();
  599. } else if (forkedExecutable != null && !isForkedJavac()) {
  600. forkedExecutable = null;
  601. }
  602. return forkedExecutable;
  603. }
  604. /**
  605. * If true, enables the -nowarn option.
  606. * @param flag if true, enable the -nowarn option
  607. */
  608. public void setNowarn(boolean flag) {
  609. this.nowarn = flag;
  610. }
  611. /**
  612. * Should the -nowarn option be used.
  613. * @return true if the -nowarn option should be used
  614. */
  615. public boolean getNowarn() {
  616. return nowarn;
  617. }
  618. /**
  619. * Adds an implementation specific command-line argument.
  620. * @return a ImplementationSpecificArgument to be configured
  621. */
  622. public ImplementationSpecificArgument createCompilerArg() {
  623. ImplementationSpecificArgument arg =
  624. new ImplementationSpecificArgument();
  625. facade.addImplementationArgument(arg);
  626. return arg;
  627. }
  628. /**
  629. * Get the additional implementation specific command line arguments.
  630. * @return array of command line arguments, guaranteed to be non-null.
  631. */
  632. public String[] getCurrentCompilerArgs() {
  633. String chosen = facade.getExplicitChoice();
  634. // make sure facade knows about magic properties and fork setting
  635. facade.setImplementation(getCompiler());
  636. try {
  637. return facade.getArgs();
  638. } finally {
  639. facade.setImplementation(chosen);
  640. }
  641. }
  642. /**
  643. * Where Ant should place temporary files.
  644. *
  645. * @since Ant 1.6
  646. * @param tmpDir the temporary directory
  647. */
  648. public void setTempdir(File tmpDir) {
  649. this.tmpDir = tmpDir;
  650. }
  651. /**
  652. * Where Ant should place temporary files.
  653. *
  654. * @since Ant 1.6
  655. * @return the temporary directory
  656. */
  657. public File getTempdir() {
  658. return tmpDir;
  659. }
  660. /**
  661. * Executes the task.
  662. * @exception BuildException if an error occurs
  663. */
  664. public void execute() throws BuildException {
  665. checkParameters();
  666. resetFileLists();
  667. // scan source directories and dest directory to build up
  668. // compile lists
  669. String[] list = src.list();
  670. for (int i = 0; i < list.length; i++) {
  671. File srcDir = getProject().resolveFile(list[i]);
  672. if (!srcDir.exists()) {
  673. throw new BuildException("srcdir \""
  674. + srcDir.getPath()
  675. + "\" does not exist!", getLocation());
  676. }
  677. DirectoryScanner ds = this.getDirectoryScanner(srcDir);
  678. String[] files = ds.getIncludedFiles();
  679. scanDir(srcDir, destDir != null ? destDir : srcDir, files);
  680. }
  681. compile();
  682. }
  683. /**
  684. * Clear the list of files to be compiled and copied..
  685. */
  686. protected void resetFileLists() {
  687. compileList = new File[0];
  688. }
  689. /**
  690. * Scans the directory looking for source files to be compiled.
  691. * The results are returned in the class variable compileList
  692. *
  693. * @param srcDir The source directory
  694. * @param destDir The destination directory
  695. * @param files An array of filenames
  696. */
  697. protected void scanDir(File srcDir, File destDir, String[] files) {
  698. GlobPatternMapper m = new GlobPatternMapper();
  699. m.setFrom("*.java");
  700. m.setTo("*.class");
  701. SourceFileScanner sfs = new SourceFileScanner(this);
  702. File[] newFiles = sfs.restrictAsFiles(files, srcDir, destDir, m);
  703. if (newFiles.length > 0) {
  704. File[] newCompileList
  705. = new File[compileList.length + newFiles.length];
  706. System.arraycopy(compileList, 0, newCompileList, 0,
  707. compileList.length);
  708. System.arraycopy(newFiles, 0, newCompileList,
  709. compileList.length, newFiles.length);
  710. compileList = newCompileList;
  711. }
  712. }
  713. /**
  714. * Gets the list of files to be compiled.
  715. * @return the list of files as an array
  716. */
  717. public File[] getFileList() {
  718. return compileList;
  719. }
  720. /**
  721. * Is the compiler implementation a jdk compiler
  722. *
  723. * @param compilerImpl the name of the compiler implementation
  724. * @return true if compilerImpl is "modern", "classic", "javac1.1",
  725. * "javac1.2", "javac1.3", "javac1.4" or "javac1.5".
  726. */
  727. protected boolean isJdkCompiler(String compilerImpl) {
  728. return "modern".equals(compilerImpl)
  729. || "classic".equals(compilerImpl)
  730. || "javac1.1".equals(compilerImpl)
  731. || "javac1.2".equals(compilerImpl)
  732. || "javac1.3".equals(compilerImpl)
  733. || "javac1.4".equals(compilerImpl)
  734. || "javac1.5".equals(compilerImpl);
  735. }
  736. /**
  737. * @return the executable name of the java compiler
  738. */
  739. protected String getSystemJavac() {
  740. return JavaEnvUtils.getJdkExecutable("javac");
  741. }
  742. /**
  743. * Choose the implementation for this particular task.
  744. * @param compiler the name of the compiler
  745. * @since Ant 1.5
  746. */
  747. public void setCompiler(String compiler) {
  748. facade.setImplementation(compiler);
  749. }
  750. /**
  751. * The implementation for this particular task.
  752. *
  753. * <p>Defaults to the build.compiler property but can be overridden
  754. * via the compiler and fork attributes.</p>
  755. *
  756. * <p>If fork has been set to true, the result will be extJavac
  757. * and not classic or java1.2 - no matter what the compiler
  758. * attribute looks like.</p>
  759. *
  760. * @see #getCompilerVersion
  761. *
  762. * @since Ant 1.5
  763. */
  764. public String getCompiler() {
  765. String compilerImpl = getCompilerVersion();
  766. if (fork) {
  767. if (isJdkCompiler(compilerImpl)) {
  768. if (facade.hasBeenSet()) {
  769. log("Since fork is true, ignoring compiler setting.",
  770. Project.MSG_WARN);
  771. }
  772. compilerImpl = "extJavac";
  773. } else {
  774. log("Since compiler setting isn't classic or modern,"
  775. + "ignoring fork setting.", Project.MSG_WARN);
  776. }
  777. }
  778. return compilerImpl;
  779. }
  780. /**
  781. * The implementation for this particular task.
  782. *
  783. * <p>Defaults to the build.compiler property but can be overridden
  784. * via the compiler attribute.</p>
  785. *
  786. * <p>This method does not take the fork attribute into
  787. * account.</p>
  788. *
  789. * @see #getCompiler
  790. *
  791. * @since Ant 1.5
  792. */
  793. public String getCompilerVersion() {
  794. facade.setMagicValue(getProject().getProperty("build.compiler"));
  795. return facade.getImplementation();
  796. }
  797. /**
  798. * Check that all required attributes have been set and nothing
  799. * silly has been entered.
  800. *
  801. * @since Ant 1.5
  802. * @exception BuildException if an error occurs
  803. */
  804. protected void checkParameters() throws BuildException {
  805. if (src == null) {
  806. throw new BuildException("srcdir attribute must be set!",
  807. getLocation());
  808. }
  809. if (src.size() == 0) {
  810. throw new BuildException("srcdir attribute must be set!",
  811. getLocation());
  812. }
  813. if (destDir != null && !destDir.isDirectory()) {
  814. throw new BuildException("destination directory \""
  815. + destDir
  816. + "\" does not exist "
  817. + "or is not a directory", getLocation());
  818. }
  819. }
  820. /**
  821. * Perform the compilation.
  822. *
  823. * @since Ant 1.5
  824. */
  825. protected void compile() {
  826. String compilerImpl = getCompiler();
  827. if (compileList.length > 0) {
  828. log("Compiling " + compileList.length + " source file"
  829. + (compileList.length == 1 ? "" : "s")
  830. + (destDir != null ? " to " + destDir : ""));
  831. if (listFiles) {
  832. for (int i = 0; i < compileList.length; i++) {
  833. String filename = compileList[i].getAbsolutePath();
  834. log(filename);
  835. }
  836. }
  837. CompilerAdapter adapter =
  838. CompilerAdapterFactory.getCompiler(compilerImpl, this);
  839. // now we need to populate the compiler adapter
  840. adapter.setJavac(this);
  841. // finally, lets execute the compiler!!
  842. if (!adapter.execute()) {
  843. if (failOnError) {
  844. throw new BuildException(FAIL_MSG, getLocation());
  845. } else {
  846. log(FAIL_MSG, Project.MSG_ERR);
  847. }
  848. }
  849. }
  850. }
  851. /**
  852. * Adds an "compiler" attribute to Commandline$Attribute used to
  853. * filter command line attributes based on the current
  854. * implementation.
  855. */
  856. public class ImplementationSpecificArgument extends
  857. org.apache.tools.ant.util.facade.ImplementationSpecificArgument {
  858. /**
  859. * @param impl the name of the compiler
  860. */
  861. public void setCompiler(String impl) {
  862. super.setImplementation(impl);
  863. }
  864. }
  865. }