You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Javac.java 56 kB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
9 years ago
11 years ago
11 years ago
11 years ago
9 years ago
11 years ago
9 years ago
11 years ago
11 years ago
9 years ago
11 years ago
11 years ago
11 years ago
9 years ago
9 years ago
9 years ago
11 years ago
9 years ago
11 years ago
11 years ago
9 years ago
11 years ago
11 years ago
9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
9 years ago
11 years ago
11 years ago
11 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package org.apache.tools.ant.taskdefs;
  19. import java.io.File;
  20. import java.io.IOException;
  21. import java.io.OutputStream;
  22. import java.nio.file.Files;
  23. import java.util.ArrayList;
  24. import java.util.Collection;
  25. import java.util.HashMap;
  26. import java.util.List;
  27. import java.util.Map;
  28. import java.util.TreeMap;
  29. import org.apache.tools.ant.BuildException;
  30. import org.apache.tools.ant.DirectoryScanner;
  31. import org.apache.tools.ant.MagicNames;
  32. import org.apache.tools.ant.Project;
  33. import org.apache.tools.ant.taskdefs.compilers.CompilerAdapter;
  34. import org.apache.tools.ant.taskdefs.compilers.CompilerAdapterExtension;
  35. import org.apache.tools.ant.taskdefs.compilers.CompilerAdapterFactory;
  36. import org.apache.tools.ant.types.Path;
  37. import org.apache.tools.ant.types.Reference;
  38. import org.apache.tools.ant.util.FileUtils;
  39. import org.apache.tools.ant.util.GlobPatternMapper;
  40. import org.apache.tools.ant.util.JavaEnvUtils;
  41. import org.apache.tools.ant.util.SourceFileScanner;
  42. import org.apache.tools.ant.util.facade.FacadeTaskHelper;
  43. /**
  44. * Compiles Java source files. This task can take the following
  45. * arguments:
  46. * <ul>
  47. * <li>sourcedir
  48. * <li>destdir
  49. * <li>deprecation
  50. * <li>classpath
  51. * <li>bootclasspath
  52. * <li>extdirs
  53. * <li>optimize
  54. * <li>debug
  55. * <li>encoding
  56. * <li>target
  57. * <li>depend
  58. * <li>verbose
  59. * <li>failonerror
  60. * <li>includeantruntime
  61. * <li>includejavaruntime
  62. * <li>source
  63. * <li>compiler
  64. * <li>release
  65. * </ul>
  66. * Of these arguments, the <b>sourcedir</b> and <b>destdir</b> are required.
  67. * <p>
  68. * When this task executes, it will recursively scan the sourcedir and
  69. * destdir looking for Java source files to compile. This task makes its
  70. * compile decision based on timestamp.
  71. *
  72. *
  73. * @since Ant 1.1
  74. *
  75. * @ant.task category="java"
  76. */
  77. public class Javac extends MatchingTask {
  78. private static final String FAIL_MSG
  79. = "Compile failed; see the compiler error output for details.";
  80. private static final String JAVAC10_PLUS = "javac10+";
  81. private static final String JAVAC9 = "javac9";
  82. private static final String JAVAC19 = "javac1.9";
  83. private static final String JAVAC18 = "javac1.8";
  84. private static final String JAVAC17 = "javac1.7";
  85. private static final String JAVAC16 = "javac1.6";
  86. private static final String JAVAC15 = "javac1.5";
  87. private static final String JAVAC14 = "javac1.4";
  88. private static final String JAVAC13 = "javac1.3";
  89. private static final String JAVAC12 = "javac1.2";
  90. private static final String JAVAC11 = "javac1.1";
  91. private static final String MODERN = "modern";
  92. private static final String CLASSIC = "classic";
  93. private static final String EXTJAVAC = "extJavac";
  94. private static final char GROUP_START_MARK = '{'; //modulesourcepath group start character
  95. private static final char GROUP_END_MARK = '}'; //modulesourcepath group end character
  96. private static final char GROUP_SEP_MARK = ','; //modulesourcepath group element separator character
  97. private static final String MODULE_MARKER = "*"; //modulesourcepath module name marker
  98. private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
  99. private Path src;
  100. private File destDir;
  101. private File nativeHeaderDir;
  102. private Path compileClasspath;
  103. private Path modulepath;
  104. private Path upgrademodulepath;
  105. private Path compileSourcepath;
  106. private Path moduleSourcepath;
  107. private String encoding;
  108. private boolean debug = false;
  109. private boolean optimize = false;
  110. private boolean deprecation = false;
  111. private boolean depend = false;
  112. private boolean verbose = false;
  113. private String targetAttribute;
  114. private String release;
  115. private Path bootclasspath;
  116. private Path extdirs;
  117. private Boolean includeAntRuntime;
  118. private boolean includeJavaRuntime = false;
  119. private boolean fork = false;
  120. private String forkedExecutable = null;
  121. private boolean nowarn = false;
  122. private String memoryInitialSize;
  123. private String memoryMaximumSize;
  124. private FacadeTaskHelper facade = null;
  125. // CheckStyle:VisibilityModifier OFF - bc
  126. protected boolean failOnError = true;
  127. protected boolean listFiles = false;
  128. protected File[] compileList = new File[0];
  129. private Map<String, Long> packageInfos = new HashMap<>();
  130. // CheckStyle:VisibilityModifier ON
  131. private String source;
  132. private String debugLevel;
  133. private File tmpDir;
  134. private String updatedProperty;
  135. private String errorProperty;
  136. private boolean taskSuccess = true; // assume the best
  137. private boolean includeDestClasses = true;
  138. private CompilerAdapter nestedAdapter = null;
  139. private boolean createMissingPackageInfoClass = true;
  140. /**
  141. * Javac task for compilation of Java files.
  142. */
  143. public Javac() {
  144. facade = new FacadeTaskHelper(assumedJavaVersion());
  145. }
  146. private String assumedJavaVersion() {
  147. if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_4)) {
  148. return JAVAC14;
  149. }
  150. if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_5)) {
  151. return JAVAC15;
  152. }
  153. if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_6)) {
  154. return JAVAC16;
  155. }
  156. if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_7)) {
  157. return JAVAC17;
  158. }
  159. if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_8)) {
  160. return JAVAC18;
  161. }
  162. if (JavaEnvUtils.isAtLeastJavaVersion("10")) {
  163. return JAVAC10_PLUS;
  164. }
  165. if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_9)) {
  166. return JAVAC9;
  167. }
  168. return CLASSIC;
  169. }
  170. /**
  171. * Get the value of debugLevel.
  172. * @return value of debugLevel.
  173. */
  174. public String getDebugLevel() {
  175. return debugLevel;
  176. }
  177. /**
  178. * Keyword list to be appended to the -g command-line switch.
  179. *
  180. * This will be ignored by all implementations except modern
  181. * and classic(ver &gt;= 1.2). Legal values are none or a
  182. * comma-separated list of the following keywords: lines, vars,
  183. * and source. If debuglevel is not specified, by default, :none
  184. * will be appended to -g. If debug is not turned on, this attribute
  185. * will be ignored.
  186. *
  187. * @param v Value to assign to debugLevel.
  188. */
  189. public void setDebugLevel(final String v) {
  190. this.debugLevel = v;
  191. }
  192. /**
  193. * Get the value of source.
  194. * @return value of source.
  195. */
  196. public String getSource() {
  197. return source != null
  198. ? source : getProject().getProperty(MagicNames.BUILD_JAVAC_SOURCE);
  199. }
  200. /**
  201. * Value of the -source command-line switch; will be ignored by
  202. * all implementations except modern, jikes and gcj (gcj uses
  203. * -fsource).
  204. *
  205. * <p>If you use this attribute together with jikes or gcj, you
  206. * must make sure that your version of jikes supports the -source
  207. * switch.</p>
  208. *
  209. * <p>Legal values are 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, and any integral number bigger than 4
  210. * - by default, no -source argument will be used at all.</p>
  211. *
  212. * @param v Value to assign to source.
  213. */
  214. public void setSource(final String v) {
  215. this.source = v;
  216. }
  217. /**
  218. * Adds a path for source compilation.
  219. *
  220. * @return a nested src element.
  221. */
  222. public Path createSrc() {
  223. if (src == null) {
  224. src = new Path(getProject());
  225. }
  226. return src.createPath();
  227. }
  228. /**
  229. * Recreate src.
  230. *
  231. * @return a nested src element.
  232. */
  233. protected Path recreateSrc() {
  234. src = null;
  235. return createSrc();
  236. }
  237. /**
  238. * Set the source directories to find the source Java files.
  239. * @param srcDir the source directories as a path
  240. */
  241. public void setSrcdir(final Path srcDir) {
  242. if (src == null) {
  243. src = srcDir;
  244. } else {
  245. src.append(srcDir);
  246. }
  247. }
  248. /**
  249. * Gets the source dirs to find the source java files.
  250. * @return the source directories as a path
  251. */
  252. public Path getSrcdir() {
  253. return src;
  254. }
  255. /**
  256. * Set the destination directory into which the Java source
  257. * files should be compiled.
  258. * @param destDir the destination director
  259. */
  260. public void setDestdir(final File destDir) {
  261. this.destDir = destDir;
  262. }
  263. /**
  264. * Gets the destination directory into which the java source files
  265. * should be compiled.
  266. * @return the destination directory
  267. */
  268. public File getDestdir() {
  269. return destDir;
  270. }
  271. /**
  272. * Set the destination directory into which the generated native
  273. * header files should be placed.
  274. * @param nhDir where to place generated native header files
  275. * @since Ant 1.9.8
  276. */
  277. public void setNativeHeaderDir(final File nhDir) {
  278. this.nativeHeaderDir = nhDir;
  279. }
  280. /**
  281. * Gets the destination directory into which the generated native
  282. * header files should be placed.
  283. * @return where to place generated native header files
  284. * @since Ant 1.9.8
  285. */
  286. public File getNativeHeaderDir() {
  287. return nativeHeaderDir;
  288. }
  289. /**
  290. * Set the sourcepath to be used for this compilation.
  291. * @param sourcepath the source path
  292. */
  293. public void setSourcepath(final Path sourcepath) {
  294. if (compileSourcepath == null) {
  295. compileSourcepath = sourcepath;
  296. } else {
  297. compileSourcepath.append(sourcepath);
  298. }
  299. }
  300. /**
  301. * Gets the sourcepath to be used for this compilation.
  302. * @return the source path
  303. */
  304. public Path getSourcepath() {
  305. return compileSourcepath;
  306. }
  307. /**
  308. * Adds a path to sourcepath.
  309. * @return a sourcepath to be configured
  310. */
  311. public Path createSourcepath() {
  312. if (compileSourcepath == null) {
  313. compileSourcepath = new Path(getProject());
  314. }
  315. return compileSourcepath.createPath();
  316. }
  317. /**
  318. * Adds a reference to a source path defined elsewhere.
  319. * @param r a reference to a source path
  320. */
  321. public void setSourcepathRef(final Reference r) {
  322. createSourcepath().setRefid(r);
  323. }
  324. /**
  325. * Set the modulesourcepath to be used for this compilation.
  326. * @param msp the modulesourcepath
  327. * @since 1.9.7
  328. */
  329. public void setModulesourcepath(final Path msp) {
  330. if (moduleSourcepath == null) {
  331. moduleSourcepath = msp;
  332. } else {
  333. moduleSourcepath.append(msp);
  334. }
  335. }
  336. /**
  337. * Gets the modulesourcepath to be used for this compilation.
  338. * @return the modulesourcepath
  339. * @since 1.9.7
  340. */
  341. public Path getModulesourcepath() {
  342. return moduleSourcepath;
  343. }
  344. /**
  345. * Adds a path to modulesourcepath.
  346. * @return a modulesourcepath to be configured
  347. * @since 1.9.7
  348. */
  349. public Path createModulesourcepath() {
  350. if (moduleSourcepath == null) {
  351. moduleSourcepath = new Path(getProject());
  352. }
  353. return moduleSourcepath.createPath();
  354. }
  355. /**
  356. * Adds a reference to a modulesourcepath defined elsewhere.
  357. * @param r a reference to a modulesourcepath
  358. * @since 1.9.7
  359. */
  360. public void setModulesourcepathRef(final Reference r) {
  361. createModulesourcepath().setRefid(r);
  362. }
  363. /**
  364. * Set the classpath to be used for this compilation.
  365. *
  366. * @param classpath an Ant Path object containing the compilation classpath.
  367. */
  368. public void setClasspath(final Path classpath) {
  369. if (compileClasspath == null) {
  370. compileClasspath = classpath;
  371. } else {
  372. compileClasspath.append(classpath);
  373. }
  374. }
  375. /**
  376. * Gets the classpath to be used for this compilation.
  377. * @return the class path
  378. */
  379. public Path getClasspath() {
  380. return compileClasspath;
  381. }
  382. /**
  383. * Adds a path to the classpath.
  384. * @return a class path to be configured
  385. */
  386. public Path createClasspath() {
  387. if (compileClasspath == null) {
  388. compileClasspath = new Path(getProject());
  389. }
  390. return compileClasspath.createPath();
  391. }
  392. /**
  393. * Adds a reference to a classpath defined elsewhere.
  394. * @param r a reference to a classpath
  395. */
  396. public void setClasspathRef(final Reference r) {
  397. createClasspath().setRefid(r);
  398. }
  399. /**
  400. * Set the modulepath to be used for this compilation.
  401. * @param mp an Ant Path object containing the modulepath.
  402. * @since 1.9.7
  403. */
  404. public void setModulepath(final Path mp) {
  405. if (modulepath == null) {
  406. modulepath = mp;
  407. } else {
  408. modulepath.append(mp);
  409. }
  410. }
  411. /**
  412. * Gets the modulepath to be used for this compilation.
  413. * @return the modulepath
  414. * @since 1.9.7
  415. */
  416. public Path getModulepath() {
  417. return modulepath;
  418. }
  419. /**
  420. * Adds a path to the modulepath.
  421. * @return a modulepath to be configured
  422. * @since 1.9.7
  423. */
  424. public Path createModulepath() {
  425. if (modulepath == null) {
  426. modulepath = new Path(getProject());
  427. }
  428. return modulepath.createPath();
  429. }
  430. /**
  431. * Adds a reference to a modulepath defined elsewhere.
  432. * @param r a reference to a modulepath
  433. * @since 1.9.7
  434. */
  435. public void setModulepathRef(final Reference r) {
  436. createModulepath().setRefid(r);
  437. }
  438. /**
  439. * Set the upgrademodulepath to be used for this compilation.
  440. * @param ump an Ant Path object containing the upgrademodulepath.
  441. * @since 1.9.7
  442. */
  443. public void setUpgrademodulepath(final Path ump) {
  444. if (upgrademodulepath == null) {
  445. upgrademodulepath = ump;
  446. } else {
  447. upgrademodulepath.append(ump);
  448. }
  449. }
  450. /**
  451. * Gets the upgrademodulepath to be used for this compilation.
  452. * @return the upgrademodulepath
  453. * @since 1.9.7
  454. */
  455. public Path getUpgrademodulepath() {
  456. return upgrademodulepath;
  457. }
  458. /**
  459. * Adds a path to the upgrademodulepath.
  460. * @return an upgrademodulepath to be configured
  461. * @since 1.9.7
  462. */
  463. public Path createUpgrademodulepath() {
  464. if (upgrademodulepath == null) {
  465. upgrademodulepath = new Path(getProject());
  466. }
  467. return upgrademodulepath.createPath();
  468. }
  469. /**
  470. * Adds a reference to the upgrademodulepath defined elsewhere.
  471. * @param r a reference to an upgrademodulepath
  472. * @since 1.9.7
  473. */
  474. public void setUpgrademodulepathRef(final Reference r) {
  475. createUpgrademodulepath().setRefid(r);
  476. }
  477. /**
  478. * Sets the bootclasspath that will be used to compile the classes
  479. * against.
  480. * @param bootclasspath a path to use as a boot class path (may be more
  481. * than one)
  482. */
  483. public void setBootclasspath(final Path bootclasspath) {
  484. if (this.bootclasspath == null) {
  485. this.bootclasspath = bootclasspath;
  486. } else {
  487. this.bootclasspath.append(bootclasspath);
  488. }
  489. }
  490. /**
  491. * Gets the bootclasspath that will be used to compile the classes
  492. * against.
  493. * @return the boot path
  494. */
  495. public Path getBootclasspath() {
  496. return bootclasspath;
  497. }
  498. /**
  499. * Adds a path to the bootclasspath.
  500. * @return a path to be configured
  501. */
  502. public Path createBootclasspath() {
  503. if (bootclasspath == null) {
  504. bootclasspath = new Path(getProject());
  505. }
  506. return bootclasspath.createPath();
  507. }
  508. /**
  509. * Adds a reference to a classpath defined elsewhere.
  510. * @param r a reference to a classpath
  511. */
  512. public void setBootClasspathRef(final Reference r) {
  513. createBootclasspath().setRefid(r);
  514. }
  515. /**
  516. * Sets the extension directories that will be used during the
  517. * compilation.
  518. * @param extdirs a path
  519. */
  520. public void setExtdirs(final Path extdirs) {
  521. if (this.extdirs == null) {
  522. this.extdirs = extdirs;
  523. } else {
  524. this.extdirs.append(extdirs);
  525. }
  526. }
  527. /**
  528. * Gets the extension directories that will be used during the
  529. * compilation.
  530. * @return the extension directories as a path
  531. */
  532. public Path getExtdirs() {
  533. return extdirs;
  534. }
  535. /**
  536. * Adds a path to extdirs.
  537. * @return a path to be configured
  538. */
  539. public Path createExtdirs() {
  540. if (extdirs == null) {
  541. extdirs = new Path(getProject());
  542. }
  543. return extdirs.createPath();
  544. }
  545. /**
  546. * If true, list the source files being handed off to the compiler.
  547. * @param list if true list the source files
  548. */
  549. public void setListfiles(final boolean list) {
  550. listFiles = list;
  551. }
  552. /**
  553. * Get the listfiles flag.
  554. * @return the listfiles flag
  555. */
  556. public boolean getListfiles() {
  557. return listFiles;
  558. }
  559. /**
  560. * Indicates whether the build will continue
  561. * even if there are compilation errors; defaults to true.
  562. * @param fail if true halt the build on failure
  563. */
  564. public void setFailonerror(final boolean fail) {
  565. failOnError = fail;
  566. }
  567. /**
  568. * @ant.attribute ignore="true"
  569. * @param proceed inverse of failoferror
  570. */
  571. public void setProceed(final boolean proceed) {
  572. failOnError = !proceed;
  573. }
  574. /**
  575. * Gets the failonerror flag.
  576. * @return the failonerror flag
  577. */
  578. public boolean getFailonerror() {
  579. return failOnError;
  580. }
  581. /**
  582. * Indicates whether source should be
  583. * compiled with deprecation information; defaults to off.
  584. * @param deprecation if true turn on deprecation information
  585. */
  586. public void setDeprecation(final boolean deprecation) {
  587. this.deprecation = deprecation;
  588. }
  589. /**
  590. * Gets the deprecation flag.
  591. * @return the deprecation flag
  592. */
  593. public boolean getDeprecation() {
  594. return deprecation;
  595. }
  596. /**
  597. * The initial size of the memory for the underlying VM
  598. * if javac is run externally; ignored otherwise.
  599. * Defaults to the standard VM memory setting.
  600. * (Examples: 83886080, 81920k, or 80m)
  601. * @param memoryInitialSize string to pass to VM
  602. */
  603. public void setMemoryInitialSize(final String memoryInitialSize) {
  604. this.memoryInitialSize = memoryInitialSize;
  605. }
  606. /**
  607. * Gets the memoryInitialSize flag.
  608. * @return the memoryInitialSize flag
  609. */
  610. public String getMemoryInitialSize() {
  611. return memoryInitialSize;
  612. }
  613. /**
  614. * The maximum size of the memory for the underlying VM
  615. * if javac is run externally; ignored otherwise.
  616. * Defaults to the standard VM memory setting.
  617. * (Examples: 83886080, 81920k, or 80m)
  618. * @param memoryMaximumSize string to pass to VM
  619. */
  620. public void setMemoryMaximumSize(final String memoryMaximumSize) {
  621. this.memoryMaximumSize = memoryMaximumSize;
  622. }
  623. /**
  624. * Gets the memoryMaximumSize flag.
  625. * @return the memoryMaximumSize flag
  626. */
  627. public String getMemoryMaximumSize() {
  628. return memoryMaximumSize;
  629. }
  630. /**
  631. * Set the Java source file encoding name.
  632. * @param encoding the source file encoding
  633. */
  634. public void setEncoding(final String encoding) {
  635. this.encoding = encoding;
  636. }
  637. /**
  638. * Gets the java source file encoding name.
  639. * @return the source file encoding name
  640. */
  641. public String getEncoding() {
  642. return encoding;
  643. }
  644. /**
  645. * Indicates whether source should be compiled
  646. * with debug information; defaults to off.
  647. * @param debug if true compile with debug information
  648. */
  649. public void setDebug(final boolean debug) {
  650. this.debug = debug;
  651. }
  652. /**
  653. * Gets the debug flag.
  654. * @return the debug flag
  655. */
  656. public boolean getDebug() {
  657. return debug;
  658. }
  659. /**
  660. * If true, compiles with optimization enabled.
  661. * @param optimize if true compile with optimization enabled
  662. */
  663. public void setOptimize(final boolean optimize) {
  664. this.optimize = optimize;
  665. }
  666. /**
  667. * Gets the optimize flag.
  668. * @return the optimize flag
  669. */
  670. public boolean getOptimize() {
  671. return optimize;
  672. }
  673. /**
  674. * Enables dependency-tracking for compilers
  675. * that support this (jikes and classic).
  676. * @param depend if true enable dependency-tracking
  677. */
  678. public void setDepend(final boolean depend) {
  679. this.depend = depend;
  680. }
  681. /**
  682. * Gets the depend flag.
  683. * @return the depend flag
  684. */
  685. public boolean getDepend() {
  686. return depend;
  687. }
  688. /**
  689. * If true, asks the compiler for verbose output.
  690. * @param verbose if true, asks the compiler for verbose output
  691. */
  692. public void setVerbose(final boolean verbose) {
  693. this.verbose = verbose;
  694. }
  695. /**
  696. * Gets the verbose flag.
  697. * @return the verbose flag
  698. */
  699. public boolean getVerbose() {
  700. return verbose;
  701. }
  702. /**
  703. * Sets the target VM that the classes will be compiled for. Valid
  704. * values depend on the compiler, for jdk 1.4 the valid values are
  705. * "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9" and any integral number bigger than 4
  706. * @param target the target VM
  707. */
  708. public void setTarget(final String target) {
  709. this.targetAttribute = target;
  710. }
  711. /**
  712. * Gets the target VM that the classes will be compiled for.
  713. * @return the target VM
  714. */
  715. public String getTarget() {
  716. return targetAttribute != null
  717. ? targetAttribute
  718. : getProject().getProperty(MagicNames.BUILD_JAVAC_TARGET);
  719. }
  720. /**
  721. * Sets the version to use for the {@code --release} switch that
  722. * combines {@code source}, {@code target} and setting the
  723. * bootclasspath.
  724. *
  725. * Values depend on the compiler, for jdk 9 the valid values are
  726. * "6", "7", "8", "9".
  727. * @param release the value of the release attribute
  728. * @since Ant 1.9.8
  729. */
  730. public void setRelease(final String release) {
  731. this.release = release;
  732. }
  733. /**
  734. * Gets the version to use for the {@code --release} switch that
  735. * combines {@code source}, {@code target} and setting the
  736. * bootclasspath.
  737. *
  738. * @return the value of the release attribute
  739. * @since Ant 1.9.8
  740. */
  741. public String getRelease() {
  742. return release;
  743. }
  744. /**
  745. * If true, includes Ant's own classpath in the classpath.
  746. * @param include if true, includes Ant's own classpath in the classpath
  747. */
  748. public void setIncludeantruntime(final boolean include) {
  749. includeAntRuntime = include;
  750. }
  751. /**
  752. * Gets whether or not the ant classpath is to be included in the classpath.
  753. * @return whether or not the ant classpath is to be included in the classpath
  754. */
  755. public boolean getIncludeantruntime() {
  756. return includeAntRuntime == null || includeAntRuntime;
  757. }
  758. /**
  759. * If true, includes the Java runtime libraries in the classpath.
  760. * @param include if true, includes the Java runtime libraries in the classpath
  761. */
  762. public void setIncludejavaruntime(final boolean include) {
  763. includeJavaRuntime = include;
  764. }
  765. /**
  766. * Gets whether or not the java runtime should be included in this
  767. * task's classpath.
  768. * @return the includejavaruntime attribute
  769. */
  770. public boolean getIncludejavaruntime() {
  771. return includeJavaRuntime;
  772. }
  773. /**
  774. * If true, forks the javac compiler.
  775. *
  776. * @param f "true|false|on|off|yes|no"
  777. */
  778. public void setFork(final boolean f) {
  779. fork = f;
  780. }
  781. /**
  782. * Sets the name of the javac executable.
  783. *
  784. * <p>Ignored unless fork is true or extJavac has been specified
  785. * as the compiler.</p>
  786. * @param forkExec the name of the executable
  787. */
  788. public void setExecutable(final String forkExec) {
  789. forkedExecutable = forkExec;
  790. }
  791. /**
  792. * The value of the executable attribute, if any.
  793. *
  794. * @since Ant 1.6
  795. * @return the name of the java executable
  796. */
  797. public String getExecutable() {
  798. return forkedExecutable;
  799. }
  800. /**
  801. * Is this a forked invocation of JDK's javac?
  802. * @return true if this is a forked invocation
  803. */
  804. public boolean isForkedJavac() {
  805. return fork || EXTJAVAC.equalsIgnoreCase(getCompiler());
  806. }
  807. /**
  808. * The name of the javac executable to use in fork-mode.
  809. *
  810. * <p>This is either the name specified with the executable
  811. * attribute or the full path of the javac compiler of the VM Ant
  812. * is currently running in - guessed by Ant.</p>
  813. *
  814. * <p>You should <strong>not</strong> invoke this method if you
  815. * want to get the value of the executable command - use {@link
  816. * #getExecutable getExecutable} for this.</p>
  817. * @return the name of the javac executable
  818. */
  819. public String getJavacExecutable() {
  820. if (forkedExecutable == null && isForkedJavac()) {
  821. forkedExecutable = getSystemJavac();
  822. } else if (forkedExecutable != null && !isForkedJavac()) {
  823. forkedExecutable = null;
  824. }
  825. return forkedExecutable;
  826. }
  827. /**
  828. * If true, enables the -nowarn option.
  829. * @param flag if true, enable the -nowarn option
  830. */
  831. public void setNowarn(final boolean flag) {
  832. this.nowarn = flag;
  833. }
  834. /**
  835. * Should the -nowarn option be used.
  836. * @return true if the -nowarn option should be used
  837. */
  838. public boolean getNowarn() {
  839. return nowarn;
  840. }
  841. /**
  842. * Adds an implementation specific command-line argument.
  843. * @return a ImplementationSpecificArgument to be configured
  844. */
  845. public ImplementationSpecificArgument createCompilerArg() {
  846. final ImplementationSpecificArgument arg =
  847. new ImplementationSpecificArgument();
  848. facade.addImplementationArgument(arg);
  849. return arg;
  850. }
  851. /**
  852. * Get the additional implementation specific command line arguments.
  853. * @return array of command line arguments, guaranteed to be non-null.
  854. */
  855. public String[] getCurrentCompilerArgs() {
  856. final String chosen = facade.getExplicitChoice();
  857. try {
  858. // make sure facade knows about magic properties and fork setting
  859. final String appliedCompiler = getCompiler();
  860. facade.setImplementation(appliedCompiler);
  861. String[] result = facade.getArgs();
  862. final String altCompilerName = getAltCompilerName(facade.getImplementation());
  863. if (result.length == 0 && altCompilerName != null) {
  864. facade.setImplementation(altCompilerName);
  865. result = facade.getArgs();
  866. }
  867. return result;
  868. } finally {
  869. facade.setImplementation(chosen);
  870. }
  871. }
  872. private String getAltCompilerName(final String anImplementation) {
  873. if (JAVAC10_PLUS.equalsIgnoreCase(anImplementation)
  874. || JAVAC9.equalsIgnoreCase(anImplementation)
  875. || JAVAC19.equalsIgnoreCase(anImplementation)
  876. || JAVAC18.equalsIgnoreCase(anImplementation)
  877. || JAVAC17.equalsIgnoreCase(anImplementation)
  878. || JAVAC16.equalsIgnoreCase(anImplementation)
  879. || JAVAC15.equalsIgnoreCase(anImplementation)
  880. || JAVAC14.equalsIgnoreCase(anImplementation)
  881. || JAVAC13.equalsIgnoreCase(anImplementation)) {
  882. return MODERN;
  883. }
  884. if (JAVAC12.equalsIgnoreCase(anImplementation)
  885. || JAVAC11.equalsIgnoreCase(anImplementation)) {
  886. return CLASSIC;
  887. }
  888. if (MODERN.equalsIgnoreCase(anImplementation)) {
  889. final String nextSelected = assumedJavaVersion();
  890. if (JAVAC10_PLUS.equalsIgnoreCase(anImplementation)
  891. || JAVAC9.equalsIgnoreCase(nextSelected)
  892. || JAVAC18.equalsIgnoreCase(nextSelected)
  893. || JAVAC17.equalsIgnoreCase(nextSelected)
  894. || JAVAC16.equalsIgnoreCase(nextSelected)
  895. || JAVAC15.equalsIgnoreCase(nextSelected)
  896. || JAVAC14.equalsIgnoreCase(nextSelected)
  897. || JAVAC13.equalsIgnoreCase(nextSelected)) {
  898. return nextSelected;
  899. }
  900. }
  901. if (CLASSIC.equalsIgnoreCase(anImplementation)) {
  902. return assumedJavaVersion();
  903. }
  904. if (EXTJAVAC.equalsIgnoreCase(anImplementation)) {
  905. return assumedJavaVersion();
  906. }
  907. return null;
  908. }
  909. /**
  910. * Where Ant should place temporary files.
  911. *
  912. * @since Ant 1.6
  913. * @param tmpDir the temporary directory
  914. */
  915. public void setTempdir(final File tmpDir) {
  916. this.tmpDir = tmpDir;
  917. }
  918. /**
  919. * Where Ant should place temporary files.
  920. *
  921. * @since Ant 1.6
  922. * @return the temporary directory
  923. */
  924. public File getTempdir() {
  925. return tmpDir;
  926. }
  927. /**
  928. * The property to set on compilation success.
  929. * This property will not be set if the compilation
  930. * fails, or if there are no files to compile.
  931. * @param updatedProperty the property name to use.
  932. * @since Ant 1.7.1.
  933. */
  934. public void setUpdatedProperty(final String updatedProperty) {
  935. this.updatedProperty = updatedProperty;
  936. }
  937. /**
  938. * The property to set on compilation failure.
  939. * This property will be set if the compilation
  940. * fails.
  941. * @param errorProperty the property name to use.
  942. * @since Ant 1.7.1.
  943. */
  944. public void setErrorProperty(final String errorProperty) {
  945. this.errorProperty = errorProperty;
  946. }
  947. /**
  948. * This property controls whether to include the
  949. * destination classes directory in the classpath
  950. * given to the compiler.
  951. * The default value is "true".
  952. * @param includeDestClasses the value to use.
  953. */
  954. public void setIncludeDestClasses(final boolean includeDestClasses) {
  955. this.includeDestClasses = includeDestClasses;
  956. }
  957. /**
  958. * Get the value of the includeDestClasses property.
  959. * @return the value.
  960. */
  961. public boolean isIncludeDestClasses() {
  962. return includeDestClasses;
  963. }
  964. /**
  965. * Get the result of the javac task (success or failure).
  966. * @return true if compilation succeeded, or
  967. * was not necessary, false if the compilation failed.
  968. */
  969. public boolean getTaskSuccess() {
  970. return taskSuccess;
  971. }
  972. /**
  973. * The classpath to use when loading the compiler implementation
  974. * if it is not a built-in one.
  975. *
  976. * @return Path
  977. * @since Ant 1.8.0
  978. */
  979. public Path createCompilerClasspath() {
  980. return facade.getImplementationClasspath(getProject());
  981. }
  982. /**
  983. * Set the compiler adapter explicitly.
  984. *
  985. * @param adapter CompilerAdapter
  986. * @since Ant 1.8.0
  987. */
  988. public void add(final CompilerAdapter adapter) {
  989. if (nestedAdapter != null) {
  990. throw new BuildException(
  991. "Can't have more than one compiler adapter");
  992. }
  993. nestedAdapter = adapter;
  994. }
  995. /**
  996. * Whether package-info.class files will be created by Ant
  997. * matching package-info.java files that have been compiled but
  998. * didn't create class files themselves.
  999. *
  1000. * @param b boolean
  1001. * @since Ant 1.8.3
  1002. */
  1003. public void setCreateMissingPackageInfoClass(final boolean b) {
  1004. createMissingPackageInfoClass = b;
  1005. }
  1006. /**
  1007. * Executes the task.
  1008. * @exception BuildException if an error occurs
  1009. */
  1010. @Override
  1011. public void execute() throws BuildException {
  1012. checkParameters();
  1013. resetFileLists();
  1014. // scan source directories and dest directory to build up
  1015. // compile list
  1016. if (hasPath(src)) {
  1017. collectFileListFromSourcePath();
  1018. } else {
  1019. assert hasPath(moduleSourcepath) : "Either srcDir or moduleSourcepath must be given";
  1020. collectFileListFromModulePath();
  1021. }
  1022. compile();
  1023. if (updatedProperty != null
  1024. && taskSuccess
  1025. && compileList.length != 0) {
  1026. getProject().setNewProperty(updatedProperty, "true");
  1027. }
  1028. }
  1029. /**
  1030. * Clear the list of files to be compiled and copied..
  1031. */
  1032. protected void resetFileLists() {
  1033. compileList = new File[0];
  1034. packageInfos = new HashMap<>();
  1035. }
  1036. /**
  1037. * Scans the directory looking for source files to be compiled.
  1038. * The results are returned in the class variable compileList
  1039. *
  1040. * @param srcDir The source directory
  1041. * @param destDir The destination directory
  1042. * @param files An array of filenames
  1043. */
  1044. protected void scanDir(final File srcDir, final File destDir, final String[] files) {
  1045. final GlobPatternMapper m = new GlobPatternMapper();
  1046. for (String extension : findSupportedFileExtensions()) {
  1047. m.setFrom(extension);
  1048. m.setTo("*.class");
  1049. final SourceFileScanner sfs = new SourceFileScanner(this);
  1050. final File[] newFiles = sfs.restrictAsFiles(files, srcDir, destDir, m);
  1051. if (newFiles.length > 0) {
  1052. lookForPackageInfos(srcDir, newFiles);
  1053. final File[] newCompileList
  1054. = new File[compileList.length + newFiles.length];
  1055. System.arraycopy(compileList, 0, newCompileList, 0,
  1056. compileList.length);
  1057. System.arraycopy(newFiles, 0, newCompileList,
  1058. compileList.length, newFiles.length);
  1059. compileList = newCompileList;
  1060. }
  1061. }
  1062. }
  1063. private void collectFileListFromSourcePath() {
  1064. for (String filename : src.list()) {
  1065. final File srcDir = getProject().resolveFile(filename);
  1066. if (!srcDir.exists()) {
  1067. throw new BuildException("srcdir \""
  1068. + srcDir.getPath()
  1069. + "\" does not exist!", getLocation());
  1070. }
  1071. final DirectoryScanner ds = this.getDirectoryScanner(srcDir);
  1072. final String[] files = ds.getIncludedFiles();
  1073. scanDir(srcDir, destDir != null ? destDir : srcDir, files);
  1074. }
  1075. }
  1076. private void collectFileListFromModulePath() {
  1077. final FileUtils fu = FileUtils.getFileUtils();
  1078. for (String pathElement : moduleSourcepath.list()) {
  1079. boolean valid = false;
  1080. for (Map.Entry<String, Collection<File>> modules : resolveModuleSourcePathElement(
  1081. getProject().getBaseDir(), pathElement).entrySet()) {
  1082. final String moduleName = modules.getKey();
  1083. for (File srcDir : modules.getValue()) {
  1084. if (srcDir.exists()) {
  1085. valid = true;
  1086. final DirectoryScanner ds = getDirectoryScanner(srcDir);
  1087. final String[] files = ds.getIncludedFiles();
  1088. scanDir(srcDir, fu.resolveFile(destDir, moduleName), files);
  1089. }
  1090. }
  1091. }
  1092. if (!valid) {
  1093. throw new BuildException("modulesourcepath \""
  1094. + pathElement
  1095. + "\" does not exist!", getLocation());
  1096. }
  1097. }
  1098. }
  1099. private String[] findSupportedFileExtensions() {
  1100. final String compilerImpl = getCompiler();
  1101. final CompilerAdapter adapter =
  1102. nestedAdapter != null ? nestedAdapter :
  1103. CompilerAdapterFactory.getCompiler(compilerImpl, this,
  1104. createCompilerClasspath());
  1105. String[] extensions = null;
  1106. if (adapter instanceof CompilerAdapterExtension) {
  1107. extensions =
  1108. ((CompilerAdapterExtension) adapter).getSupportedFileExtensions();
  1109. }
  1110. if (extensions == null) {
  1111. extensions = new String[] {"java"};
  1112. }
  1113. // now process the extensions to ensure that they are the
  1114. // right format
  1115. for (int i = 0; i < extensions.length; i++) {
  1116. if (!extensions[i].startsWith("*.")) {
  1117. extensions[i] = "*." + extensions[i];
  1118. }
  1119. }
  1120. return extensions;
  1121. }
  1122. /**
  1123. * Gets the list of files to be compiled.
  1124. * @return the list of files as an array
  1125. */
  1126. public File[] getFileList() {
  1127. return compileList;
  1128. }
  1129. /**
  1130. * Is the compiler implementation a jdk compiler
  1131. *
  1132. * @param compilerImpl the name of the compiler implementation
  1133. * @return true if compilerImpl is "modern", "classic",
  1134. * "javac1.1", "javac1.2", "javac1.3", "javac1.4", "javac1.5",
  1135. * "javac1.6", "javac1.7", "javac1.8", "javac1.9", "javac9" or "javac10+".
  1136. */
  1137. protected boolean isJdkCompiler(final String compilerImpl) {
  1138. return MODERN.equals(compilerImpl)
  1139. || CLASSIC.equals(compilerImpl)
  1140. || JAVAC10_PLUS.equals(compilerImpl)
  1141. || JAVAC9.equals(compilerImpl)
  1142. || JAVAC18.equals(compilerImpl)
  1143. || JAVAC17.equals(compilerImpl)
  1144. || JAVAC16.equals(compilerImpl)
  1145. || JAVAC15.equals(compilerImpl)
  1146. || JAVAC14.equals(compilerImpl)
  1147. || JAVAC13.equals(compilerImpl)
  1148. || JAVAC12.equals(compilerImpl)
  1149. || JAVAC11.equals(compilerImpl);
  1150. }
  1151. /**
  1152. * @return the executable name of the java compiler
  1153. */
  1154. protected String getSystemJavac() {
  1155. return JavaEnvUtils.getJdkExecutable("javac");
  1156. }
  1157. /**
  1158. * Choose the implementation for this particular task.
  1159. * @param compiler the name of the compiler
  1160. * @since Ant 1.5
  1161. */
  1162. public void setCompiler(final String compiler) {
  1163. facade.setImplementation(compiler);
  1164. }
  1165. /**
  1166. * The implementation for this particular task.
  1167. *
  1168. * <p>Defaults to the build.compiler property but can be overridden
  1169. * via the compiler and fork attributes.</p>
  1170. *
  1171. * <p>If fork has been set to true, the result will be extJavac
  1172. * and not classic or java1.2 - no matter what the compiler
  1173. * attribute looks like.</p>
  1174. *
  1175. * @see #getCompilerVersion
  1176. * @return the compiler.
  1177. * @since Ant 1.5
  1178. */
  1179. public String getCompiler() {
  1180. String compilerImpl = getCompilerVersion();
  1181. if (fork) {
  1182. if (isJdkCompiler(compilerImpl)) {
  1183. compilerImpl = EXTJAVAC;
  1184. } else {
  1185. log("Since compiler setting isn't classic or modern, ignoring fork setting.",
  1186. Project.MSG_WARN);
  1187. }
  1188. }
  1189. return compilerImpl;
  1190. }
  1191. /**
  1192. * The implementation for this particular task.
  1193. *
  1194. * <p>Defaults to the build.compiler property but can be overridden
  1195. * via the compiler attribute.</p>
  1196. *
  1197. * <p>This method does not take the fork attribute into
  1198. * account.</p>
  1199. *
  1200. * @see #getCompiler
  1201. * @return the compiler.
  1202. *
  1203. * @since Ant 1.5
  1204. */
  1205. public String getCompilerVersion() {
  1206. facade.setMagicValue(getProject().getProperty("build.compiler"));
  1207. return facade.getImplementation();
  1208. }
  1209. /**
  1210. * Check that all required attributes have been set and nothing
  1211. * silly has been entered.
  1212. *
  1213. * @since Ant 1.5
  1214. * @exception BuildException if an error occurs
  1215. */
  1216. protected void checkParameters() throws BuildException {
  1217. if (hasPath(src)) {
  1218. if (hasPath(moduleSourcepath)) {
  1219. throw new BuildException("modulesourcepath cannot be combined with srcdir attribute!",
  1220. getLocation());
  1221. }
  1222. } else if (hasPath(moduleSourcepath)) {
  1223. if (hasPath(src) || hasPath(compileSourcepath)) {
  1224. throw new BuildException("modulesourcepath cannot be combined with srcdir or sourcepath !",
  1225. getLocation());
  1226. }
  1227. if (destDir == null) {
  1228. throw new BuildException("modulesourcepath requires destdir attribute to be set!",
  1229. getLocation());
  1230. }
  1231. } else {
  1232. throw new BuildException("either srcdir or modulesourcepath attribute must be set!",
  1233. getLocation());
  1234. }
  1235. if (destDir != null && !destDir.isDirectory()) {
  1236. throw new BuildException("destination directory \""
  1237. + destDir
  1238. + "\" does not exist or is not a directory", getLocation());
  1239. }
  1240. if (includeAntRuntime == null && getProject().getProperty("build.sysclasspath") == null) {
  1241. log(getLocation()
  1242. + "warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds",
  1243. Project.MSG_WARN);
  1244. }
  1245. }
  1246. /**
  1247. * Perform the compilation.
  1248. *
  1249. * @since Ant 1.5
  1250. */
  1251. protected void compile() {
  1252. final String compilerImpl = getCompiler();
  1253. if (compileList.length > 0) {
  1254. log("Compiling " + compileList.length + " source file"
  1255. + (compileList.length == 1 ? "" : "s")
  1256. + (destDir != null ? " to " + destDir : ""));
  1257. if (listFiles) {
  1258. for (File element : compileList) {
  1259. log(element.getAbsolutePath());
  1260. }
  1261. }
  1262. final CompilerAdapter adapter =
  1263. nestedAdapter != null ? nestedAdapter :
  1264. CompilerAdapterFactory.getCompiler(compilerImpl, this,
  1265. createCompilerClasspath());
  1266. // now we need to populate the compiler adapter
  1267. adapter.setJavac(this);
  1268. // finally, lets execute the compiler!!
  1269. if (adapter.execute()) {
  1270. // Success
  1271. if (createMissingPackageInfoClass) {
  1272. try {
  1273. generateMissingPackageInfoClasses(destDir != null
  1274. ? destDir
  1275. : getProject()
  1276. .resolveFile(src.list()[0]));
  1277. } catch (final IOException x) {
  1278. // Should this be made a nonfatal warning?
  1279. throw new BuildException(x, getLocation());
  1280. }
  1281. }
  1282. } else {
  1283. // Fail path
  1284. this.taskSuccess = false;
  1285. if (errorProperty != null) {
  1286. getProject().setNewProperty(
  1287. errorProperty, "true");
  1288. }
  1289. if (failOnError) {
  1290. throw new BuildException(FAIL_MSG, getLocation());
  1291. }
  1292. log(FAIL_MSG, Project.MSG_ERR);
  1293. }
  1294. }
  1295. }
  1296. /**
  1297. * Adds an "compiler" attribute to Commandline$Attribute used to
  1298. * filter command line attributes based on the current
  1299. * implementation.
  1300. */
  1301. public class ImplementationSpecificArgument extends
  1302. org.apache.tools.ant.util.facade.ImplementationSpecificArgument {
  1303. /**
  1304. * @param impl the name of the compiler
  1305. */
  1306. public void setCompiler(final String impl) {
  1307. super.setImplementation(impl);
  1308. }
  1309. }
  1310. private void lookForPackageInfos(final File srcDir, final File[] newFiles) {
  1311. for (File f : newFiles) {
  1312. if (!"package-info.java".equals(f.getName())) {
  1313. continue;
  1314. }
  1315. final String path = FILE_UTILS.removeLeadingPath(srcDir, f).
  1316. replace(File.separatorChar, '/');
  1317. final String suffix = "/package-info.java";
  1318. if (!path.endsWith(suffix)) {
  1319. log("anomalous package-info.java path: " + path, Project.MSG_WARN);
  1320. continue;
  1321. }
  1322. final String pkg = path.substring(0, path.length() - suffix.length());
  1323. packageInfos.put(pkg, f.lastModified());
  1324. }
  1325. }
  1326. /**
  1327. * Ensure that every {@code package-info.java} produced a {@code package-info.class}.
  1328. * Otherwise this task's up-to-date tracking mechanisms do not work.
  1329. * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=43114">Bug #43114</a>
  1330. */
  1331. private void generateMissingPackageInfoClasses(final File dest) throws IOException {
  1332. for (final Map.Entry<String, Long> entry : packageInfos.entrySet()) {
  1333. final String pkg = entry.getKey();
  1334. final Long sourceLastMod = entry.getValue();
  1335. final File pkgBinDir = new File(dest, pkg.replace('/', File.separatorChar));
  1336. pkgBinDir.mkdirs();
  1337. final File pkgInfoClass = new File(pkgBinDir, "package-info.class");
  1338. if (pkgInfoClass.isFile() && pkgInfoClass.lastModified() >= sourceLastMod) {
  1339. continue;
  1340. }
  1341. log("Creating empty " + pkgInfoClass);
  1342. try (OutputStream os = Files.newOutputStream(pkgInfoClass.toPath())) {
  1343. os.write(PACKAGE_INFO_CLASS_HEADER);
  1344. final byte[] name = pkg.getBytes("UTF-8");
  1345. final int length = name.length + /* "/package-info" */ 13;
  1346. os.write((byte) length / 256);
  1347. os.write((byte) length % 256);
  1348. os.write(name);
  1349. os.write(PACKAGE_INFO_CLASS_FOOTER);
  1350. }
  1351. }
  1352. }
  1353. /**
  1354. * Checks if a path exists and is non empty.
  1355. * @param path to be checked
  1356. * @return true if the path is non <code>null</code> and non empty.
  1357. * @since 1.9.7
  1358. */
  1359. private static boolean hasPath(final Path path) {
  1360. return path != null && !path.isEmpty();
  1361. }
  1362. /**
  1363. * Resolves the modulesourcepath element possibly containing groups
  1364. * and module marks to module names and source roots.
  1365. * @param projectDir the project directory
  1366. * @param element the modulesourcepath elemement
  1367. * @return a mapping from module name to module source roots
  1368. * @since 1.9.7
  1369. */
  1370. private static Map<String, Collection<File>> resolveModuleSourcePathElement(
  1371. final File projectDir,
  1372. final String element) {
  1373. final Map<String, Collection<File>> result = new TreeMap<>();
  1374. for (CharSequence resolvedElement : expandGroups(element)) {
  1375. findModules(projectDir, resolvedElement.toString(), result);
  1376. }
  1377. return result;
  1378. }
  1379. /**
  1380. * Expands the groups in the modulesourcepath entry to alternatives.
  1381. * <p>
  1382. * The <code>'*'</code> is a token representing the name of any of the modules in the compilation module set.
  1383. * The <code>'{' ... ',' ... '}'</code> express alternates for expansion.
  1384. * An example of the modulesourcepath entry is <code>src/&#42;/{linux,share}/classes</code>
  1385. * </p>
  1386. * @param element the entry to expand groups in
  1387. * @return the possible alternatives
  1388. * @since 1.9.7
  1389. */
  1390. private static Collection<? extends CharSequence> expandGroups(
  1391. final CharSequence element) {
  1392. List<StringBuilder> result = new ArrayList<>();
  1393. result.add(new StringBuilder());
  1394. StringBuilder resolved = new StringBuilder();
  1395. for (int i = 0; i < element.length(); i++) {
  1396. final char c = element.charAt(i);
  1397. switch (c) {
  1398. case GROUP_START_MARK:
  1399. final int end = getGroupEndIndex(element, i);
  1400. if (end < 0) {
  1401. throw new BuildException(String.format(
  1402. "Unclosed group %s, starting at: %d",
  1403. element,
  1404. i));
  1405. }
  1406. final Collection<? extends CharSequence> parts = resolveGroup(element.subSequence(i + 1, end));
  1407. switch (parts.size()) {
  1408. case 0:
  1409. break;
  1410. case 1:
  1411. resolved.append(parts.iterator().next());
  1412. break;
  1413. default:
  1414. final List<StringBuilder> oldRes = result;
  1415. result = new ArrayList<>(oldRes.size() * parts.size());
  1416. for (CharSequence part : parts) {
  1417. for (CharSequence prefix : oldRes) {
  1418. result.add(new StringBuilder(prefix).append(resolved).append(part));
  1419. }
  1420. }
  1421. resolved = new StringBuilder();
  1422. }
  1423. i = end;
  1424. break;
  1425. default:
  1426. resolved.append(c);
  1427. }
  1428. }
  1429. for (StringBuilder prefix : result) {
  1430. prefix.append(resolved);
  1431. }
  1432. return result;
  1433. }
  1434. /**
  1435. * Resolves the group to alternatives.
  1436. * @param group the group to resolve
  1437. * @return the possible alternatives
  1438. * @since 1.9.7
  1439. */
  1440. private static Collection<? extends CharSequence> resolveGroup(final CharSequence group) {
  1441. final Collection<CharSequence> result = new ArrayList<>();
  1442. int start = 0;
  1443. int depth = 0;
  1444. for (int i = 0; i < group.length(); i++) {
  1445. final char c = group.charAt(i);
  1446. switch (c) {
  1447. case GROUP_START_MARK:
  1448. depth++;
  1449. break;
  1450. case GROUP_END_MARK:
  1451. depth--;
  1452. break;
  1453. case GROUP_SEP_MARK:
  1454. if (depth == 0) {
  1455. result.addAll(expandGroups(group.subSequence(start, i)));
  1456. start = i + 1;
  1457. }
  1458. break;
  1459. }
  1460. }
  1461. result.addAll(expandGroups(group.subSequence(start, group.length())));
  1462. return result;
  1463. }
  1464. /**
  1465. * Finds the index of an enclosing brace of the group.
  1466. * @param element the element to find the enclosing brace in
  1467. * @param start the index of the opening brace.
  1468. * @return return the index of an enclosing brace of the group or -1 if not found
  1469. * @since 1.9.7
  1470. */
  1471. private static int getGroupEndIndex(
  1472. final CharSequence element,
  1473. final int start) {
  1474. int depth = 0;
  1475. for (int i = start; i < element.length(); i++) {
  1476. final char c = element.charAt(i);
  1477. switch (c) {
  1478. case GROUP_START_MARK:
  1479. depth++;
  1480. break;
  1481. case GROUP_END_MARK:
  1482. depth--;
  1483. if (depth == 0) {
  1484. return i;
  1485. }
  1486. break;
  1487. }
  1488. }
  1489. return -1;
  1490. }
  1491. /**
  1492. * Finds modules in the expanded modulesourcepath entry.
  1493. * @param root the project root
  1494. * @param pattern the expanded modulesourcepath entry
  1495. * @param collector the map to put modules into
  1496. * @since 1.9.7
  1497. */
  1498. private static void findModules(
  1499. final File root,
  1500. String pattern,
  1501. final Map<String,Collection<File>> collector) {
  1502. pattern = pattern
  1503. .replace('/', File.separatorChar)
  1504. .replace('\\', File.separatorChar);
  1505. final int startIndex = pattern.indexOf(MODULE_MARKER);
  1506. if (startIndex == -1) {
  1507. findModules(root, pattern, null, collector);
  1508. return;
  1509. }
  1510. if (startIndex == 0) {
  1511. throw new BuildException("The modulesourcepath entry must be a folder.");
  1512. }
  1513. final int endIndex = startIndex + MODULE_MARKER.length();
  1514. if (pattern.charAt(startIndex - 1) != File.separatorChar) {
  1515. throw new BuildException("The module mark must be preceded by separator");
  1516. }
  1517. if (endIndex < pattern.length() && pattern.charAt(endIndex) != File.separatorChar) {
  1518. throw new BuildException("The module mark must be followed by separator");
  1519. }
  1520. if (pattern.indexOf(MODULE_MARKER, endIndex) != -1) {
  1521. throw new BuildException("The modulesourcepath entry must contain at most one module mark");
  1522. }
  1523. final String pathToModule = pattern.substring(0, startIndex);
  1524. final String pathInModule = endIndex == pattern.length()
  1525. ? null : pattern.substring(endIndex + 1); //+1 the separator
  1526. findModules(root, pathToModule, pathInModule, collector);
  1527. }
  1528. /**
  1529. * Finds modules in the expanded modulesourcepath entry.
  1530. * @param root the project root
  1531. * @param pathToModule the path to modules folder
  1532. * @param pathInModule the path in module to source folder
  1533. * @param collector the map to put modules into
  1534. * @since 1.9.7
  1535. */
  1536. private static void findModules(
  1537. final File root,
  1538. final String pathToModule,
  1539. final String pathInModule,
  1540. final Map<String,Collection<File>> collector) {
  1541. final FileUtils fu = FileUtils.getFileUtils();
  1542. final File f = fu.resolveFile(root, pathToModule);
  1543. if (!f.isDirectory()) {
  1544. return;
  1545. }
  1546. for (File module : f.listFiles(File::isDirectory)) {
  1547. final String moduleName = module.getName();
  1548. final File moduleSourceRoot = pathInModule == null ?
  1549. module :
  1550. new File(module, pathInModule);
  1551. Collection<File> moduleRoots = collector.computeIfAbsent(moduleName, k -> new ArrayList<>());
  1552. moduleRoots.add(moduleSourceRoot);
  1553. }
  1554. }
  1555. private static final byte[] PACKAGE_INFO_CLASS_HEADER = {
  1556. (byte) 0xca, (byte) 0xfe, (byte) 0xba, (byte) 0xbe, 0x00, 0x00, 0x00,
  1557. 0x31, 0x00, 0x07, 0x07, 0x00, 0x05, 0x07, 0x00, 0x06, 0x01, 0x00, 0x0a,
  1558. 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x01, 0x00,
  1559. 0x11, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2d, 0x69, 0x6e, 0x66,
  1560. 0x6f, 0x2e, 0x6a, 0x61, 0x76, 0x61, 0x01
  1561. };
  1562. private static final byte[] PACKAGE_INFO_CLASS_FOOTER = {
  1563. 0x2f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2d, 0x69, 0x6e, 0x66,
  1564. 0x6f, 0x01, 0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e,
  1565. 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x02, 0x00, 0x00, 0x01,
  1566. 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03,
  1567. 0x00, 0x00, 0x00, 0x02, 0x00, 0x04
  1568. };
  1569. }