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

AjcTask.java 63KB

21 years ago
4 years ago
4 years ago
4 years ago
4 years ago
21 years ago
18 years ago
18 years ago
18 years ago
18 years ago
21 years ago
18 years ago
21 years ago
15 years ago
15 years ago
4 years ago
21 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
15 years ago
15 years ago
21 years ago
15 years ago
21 years ago
21 years ago
15 years ago
4 years ago
15 years ago
21 years ago
15 years ago
15 years ago
15 years ago
15 years ago
21 years ago
15 years ago
15 years ago
21 years ago
15 years ago
21 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
21 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
21 years ago
15 years ago
21 years ago
15 years ago
21 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
21 years ago
15 years ago
4 years ago
15 years ago
21 years ago
15 years ago
4 years ago
21 years ago
15 years ago
15 years ago
4 years ago
4 years ago
4 years ago
4 years ago
21 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
4 years ago
15 years ago
4 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
4 years ago
15 years ago
15 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173
  1. /* *******************************************************************
  2. * Copyright (c) 2001-2001 Xerox Corporation,
  3. * 2002 Palo Alto Research Center, Incorporated (PARC)
  4. * 2003-2004 Contributors.
  5. * All rights reserved.
  6. * This program and the accompanying materials are made available
  7. * under the terms of the Eclipse Public License v 2.0
  8. * which accompanies this distribution and is available at
  9. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  10. *
  11. * Contributors:
  12. * Xerox/PARC initial implementation
  13. * Wes Isberg 2003-2004 changes
  14. * ******************************************************************/
  15. package org.aspectj.tools.ant.taskdefs;
  16. import java.io.File;
  17. import java.io.FileWriter;
  18. import java.io.IOException;
  19. import java.io.PrintWriter;
  20. import java.util.ArrayList;
  21. import java.util.Arrays;
  22. import java.util.Collections;
  23. import java.util.List;
  24. import java.util.StringTokenizer;
  25. import org.apache.tools.ant.AntClassLoader;
  26. import org.apache.tools.ant.BuildException;
  27. import org.apache.tools.ant.Location;
  28. import org.apache.tools.ant.Project;
  29. import org.apache.tools.ant.taskdefs.Copy;
  30. import org.apache.tools.ant.taskdefs.Delete;
  31. import org.apache.tools.ant.taskdefs.Execute;
  32. import org.apache.tools.ant.taskdefs.Expand;
  33. import org.apache.tools.ant.taskdefs.Javac;
  34. import org.apache.tools.ant.taskdefs.LogStreamHandler;
  35. import org.apache.tools.ant.taskdefs.MatchingTask;
  36. import org.apache.tools.ant.taskdefs.Mkdir;
  37. import org.apache.tools.ant.taskdefs.PumpStreamHandler;
  38. import org.apache.tools.ant.taskdefs.Zip;
  39. import org.apache.tools.ant.types.Commandline;
  40. import org.apache.tools.ant.types.CommandlineJava;
  41. import org.apache.tools.ant.types.FileSet;
  42. import org.apache.tools.ant.types.Path;
  43. import org.apache.tools.ant.types.PatternSet;
  44. import org.apache.tools.ant.types.Reference;
  45. import org.apache.tools.ant.types.ZipFileSet;
  46. import org.apache.tools.ant.util.TaskLogger;
  47. import org.aspectj.bridge.AbortException;
  48. import org.aspectj.bridge.IMessage;
  49. import org.aspectj.bridge.IMessage.Kind;
  50. import org.aspectj.bridge.IMessageHandler;
  51. import org.aspectj.bridge.IMessageHolder;
  52. import org.aspectj.bridge.MessageHandler;
  53. import org.aspectj.bridge.MessageUtil;
  54. import org.aspectj.tools.ajc.Main;
  55. import org.aspectj.util.FileUtil;
  56. import org.aspectj.util.LangUtil;
  57. /**
  58. * This runs the AspectJ 1.1 compiler, supporting all the command-line options. In 1.1.1, ajc copies resources from input jars, but
  59. * you can copy resources from the source directories using sourceRootCopyFilter. When not forking, things will be copied as needed
  60. * for each iterative compile, but when forking things are only copied at the completion of a successful compile.
  61. * <p>
  62. * See the development environment guide for usage documentation.
  63. *
  64. * @since AspectJ 1.1, Ant 1.5
  65. */
  66. public class AjcTask extends MatchingTask {
  67. /*
  68. * This task mainly converts ant specification for ajc, verbosely ignoring improper input. It also has some special features for
  69. * non-obvious clients: (1) Javac compiler adapter supported in <code>setupAjc(AjcTask, Javac, File)</code> and
  70. * <code>readArguments(String[])</code>; (2) testing is supported by (a) permitting the same specification to be re-run with
  71. * added flags (settings once made cannot be removed); and (b) permitting recycling the task with <code>reset()</code>
  72. * (untested).
  73. *
  74. * The parts that do more than convert ant specs are (a) code for forking; (b) code for copying resources.
  75. *
  76. * If you maintain/upgrade this task, keep in mind: (1) changes to the semantics of ajc (new options, new values permitted,
  77. * etc.) will have to be reflected here. (2) the clients: the iajc ant script, Javac compiler adapter, maven clients of iajc,
  78. * and testing code.
  79. */
  80. // XXX move static methods after static initializer
  81. /**
  82. * This method extracts javac arguments to ajc, and add arguments to make ajc behave more like javac in copying resources.
  83. * <p>
  84. * Pass ajc-specific options using compilerarg sub-element:
  85. *
  86. * <pre>
  87. * &lt;javac srcdir=&quot;src&quot;&gt;
  88. * &lt;compilerarg compiler=&quot;...&quot; line=&quot;-argfile src/args.lst&quot;/&gt;
  89. * &lt;javac&gt;
  90. * </pre>
  91. *
  92. * Some javac arguments are not supported in this component (yet):
  93. *
  94. * <pre>
  95. * String memoryInitialSize;
  96. * boolean includeAntRuntime = true;
  97. * boolean includeJavaRuntime = false;
  98. * </pre>
  99. *
  100. * Other javac arguments are not supported in ajc 1.1:
  101. *
  102. * <pre>
  103. * boolean optimize;
  104. * String forkedExecutable;
  105. * FacadeTaskHelper facade;
  106. * boolean depend;
  107. * String debugLevel;
  108. * Path compileSourcepath;
  109. * </pre>
  110. *
  111. * @param javac the Javac command to implement (not null)
  112. * @return null if no error, or String error otherwise
  113. */
  114. public String setupAjc(Javac javac) {
  115. if (null == javac) {
  116. return "null javac";
  117. }
  118. AjcTask ajc = this;
  119. // no null checks b/c AjcTask handles null input gracefully
  120. ajc.setProject(javac.getProject());
  121. ajc.setLocation(javac.getLocation());
  122. ajc.setTaskName("javac-iajc");
  123. ajc.setDebug(javac.getDebug());
  124. ajc.setDeprecation(javac.getDeprecation());
  125. ajc.setFailonerror(javac.getFailonerror());
  126. final boolean fork = javac.isForkedJavac();
  127. ajc.setFork(fork);
  128. if (fork) {
  129. ajc.setMaxmem(javac.getMemoryMaximumSize());
  130. }
  131. ajc.setNowarn(javac.getNowarn());
  132. ajc.setListFileArgs(javac.getListfiles());
  133. ajc.setVerbose(javac.getVerbose());
  134. ajc.setTarget(javac.getTarget());
  135. ajc.setSource(javac.getSource());
  136. ajc.setEncoding(javac.getEncoding());
  137. File javacDestDir = javac.getDestdir();
  138. if (null != javacDestDir) {
  139. ajc.setDestdir(javacDestDir);
  140. // filter requires dest dir
  141. // mimic Javac task's behavior in copying resources,
  142. ajc.setSourceRootCopyFilter("**/CVS/*,**/*.java,**/*.aj");
  143. }
  144. ajc.setBootclasspath(javac.getBootclasspath());
  145. ajc.setExtdirs(javac.getExtdirs());
  146. ajc.setClasspath(javac.getClasspath());
  147. // ignore srcDir -- all files picked up in recalculated file list
  148. // ajc.setSrcDir(javac.getSrcdir());
  149. ajc.addFiles(javac.getFileList());
  150. // arguments can override the filter, add to paths, override options
  151. ajc.readArguments(javac.getCurrentCompilerArgs());
  152. return null;
  153. }
  154. /**
  155. * Find aspectjtools.jar on the task or system classpath. Accept <code>aspectj{-}tools{...}.jar</code> mainly to support build
  156. * systems using maven-style re-naming (e.g., <code>aspectj-tools-1.1.0.jar</code>. Note that we search the task classpath
  157. * first, though an entry on the system classpath would be loaded first, because it seems more correct as the more specific one.
  158. *
  159. * @return readable File for aspectjtools.jar, or null if not found.
  160. */
  161. public static File findAspectjtoolsJar() {
  162. File result = null;
  163. ClassLoader loader = AjcTask.class.getClassLoader();
  164. if (loader instanceof AntClassLoader) {
  165. AntClassLoader taskLoader = (AntClassLoader) loader;
  166. String cp = taskLoader.getClasspath();
  167. String[] cps = LangUtil.splitClasspath(cp);
  168. for (int i = 0; (i < cps.length) && (null == result); i++) {
  169. result = isAspectjtoolsjar(cps[i]);
  170. }
  171. }
  172. if (null == result) {
  173. final Path classpath = Path.systemClasspath;
  174. final String[] paths = classpath.list();
  175. for (int i = 0; (i < paths.length) && (null == result); i++) {
  176. result = isAspectjtoolsjar(paths[i]);
  177. }
  178. }
  179. return (null == result ? null : result.getAbsoluteFile());
  180. }
  181. /** @return File if readable jar with aspectj tools name, or null */
  182. private static File isAspectjtoolsjar(String path) {
  183. if (null == path) {
  184. return null;
  185. }
  186. final String prefix = "aspectj";
  187. final String infix = "tools";
  188. final String altInfix = "-tools";
  189. final String suffix = ".jar";
  190. final int prefixLength = 7; // prefix.length();
  191. final int minLength = 16;
  192. // prefixLength + infix.length() + suffix.length();
  193. if (!path.endsWith(suffix)) {
  194. return null;
  195. }
  196. int loc = path.lastIndexOf(prefix);
  197. if ((-1 != loc) && ((loc + minLength) <= path.length())) {
  198. String rest = path.substring(loc + prefixLength);
  199. if (rest.contains(File.pathSeparator)) {
  200. return null;
  201. }
  202. if (rest.startsWith(infix) || rest.startsWith(altInfix)) {
  203. File result = new File(path);
  204. if (result.canRead() && result.isFile()) {
  205. return result;
  206. }
  207. }
  208. }
  209. return null;
  210. }
  211. /**
  212. * Maximum length (in chars) of command line before converting to an argfile when forking
  213. */
  214. private static final int MAX_COMMANDLINE = 4096;
  215. private static final File DEFAULT_DESTDIR = new File(".") {
  216. @Override
  217. public String toString() {
  218. return "(no destination dir specified)";
  219. }
  220. };
  221. /** do not throw BuildException on fail/abort message with usage */
  222. private static final String USAGE_SUBSTRING = "AspectJ-specific options";
  223. /** valid -X[...] options other than -Xlint variants */
  224. private static final List<String> VALID_XOPTIONS;
  225. /** valid warning (-warn:[...]) variants */
  226. private static final List<String> VALID_WARNINGS;
  227. /** valid debugging (-g:[...]) variants */
  228. private static final List<String> VALID_DEBUG;
  229. /**
  230. * -Xlint variants (error, warning, ignore)
  231. *
  232. * @see org.aspectj.weaver.Lint
  233. */
  234. private static final List<String> VALID_XLINT;
  235. public static final String COMMAND_EDITOR_NAME = AjcTask.class.getName() + ".COMMAND_EDITOR";
  236. static final String[] TARGET_INPUTS = new String[] {
  237. "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "9",
  238. "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"
  239. };
  240. static final String[] SOURCE_INPUTS = new String[] {
  241. "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "9",
  242. "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"
  243. };
  244. static final String[] COMPLIANCE_INPUTS = new String[] {
  245. "-1.3", "-1.4", "-1.5", "-1.6", "-1.7", "-1.8", "-1.9", "-9",
  246. "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17", "-18", "-19"
  247. };
  248. private static final ICommandEditor COMMAND_EDITOR;
  249. static {
  250. // many now deprecated: reweavable*
  251. String[] xs = new String[] { "serializableAspects", "incrementalFile", "lazyTjp", "reweavable", "reweavable:compress",
  252. "notReweavable", "noInline", "terminateAfterCompilation", "hasMember", "ajruntimetarget:1.2",
  253. "ajruntimetarget:1.5", "addSerialVersionUID"
  254. // , "targetNearSource", "OcodeSize",
  255. };
  256. VALID_XOPTIONS = Collections.unmodifiableList(Arrays.asList(xs));
  257. xs = new String[] { "constructorName", "packageDefaultMethod", "deprecation", "maskedCatchBlocks", "unusedLocals",
  258. "unusedArguments", "unusedImports", "syntheticAccess", "assertIdentifier", "allDeprecation", "allJavadoc",
  259. "charConcat", "conditionAssign",
  260. "emptyBlock", "fieldHiding", "finally", "indirectStatic", "intfNonInherited", "javadoc", "localHiding", "nls",
  261. "noEffectAssign", "pkgDefaultMethod", "semicolon", "unqualifiedField", "unusedPrivate", "unusedThrown",
  262. "uselessTypeCheck", "specialParamHiding", "staticReceiver", "syntheticAccess", "none" };
  263. VALID_WARNINGS = Collections.unmodifiableList(Arrays.asList(xs));
  264. xs = new String[] { "none", "lines", "vars", "source" };
  265. VALID_DEBUG = Collections.unmodifiableList(Arrays.asList(xs));
  266. xs = new String[] { "error", "warning", "ignore" };
  267. VALID_XLINT = Collections.unmodifiableList(Arrays.asList(xs));
  268. ICommandEditor editor = null;
  269. try {
  270. String editorClassName = System.getProperty(COMMAND_EDITOR_NAME);
  271. if (null != editorClassName) {
  272. ClassLoader cl = AjcTask.class.getClassLoader();
  273. Class<?> editorClass = cl.loadClass(editorClassName);
  274. editor = (ICommandEditor) editorClass.getDeclaredConstructor().newInstance();
  275. }
  276. } catch (Throwable t) {
  277. System.err.println("Warning: unable to load command editor");
  278. t.printStackTrace(System.err);
  279. }
  280. COMMAND_EDITOR = editor;
  281. }
  282. // ---------------------------- state and Ant interface thereto
  283. private boolean verbose;
  284. private boolean timers;
  285. private boolean listFileArgs;
  286. private boolean failonerror;
  287. private boolean fork;
  288. private String maxMem;
  289. private TaskLogger logger;
  290. // ------- single entries dumped into cmd
  291. protected GuardedCommand cmd;
  292. // ------- lists resolved in addListArgs() at execute() time
  293. private Path srcdir;
  294. private Path injars;
  295. private Path inpath;
  296. private Path classpath;
  297. private Path bootclasspath;
  298. private Path forkclasspath;
  299. private Path extdirs;
  300. private Path aspectpath;
  301. private Path argfiles;
  302. private Path inxmlfiles;
  303. private List<String> ignored;
  304. private Path sourceRoots;
  305. private File xweaveDir;
  306. private String xdoneSignal;
  307. private List<CompilerArg> compilerArgs;
  308. // ----- added by adapter - integrate better?
  309. private List<File> adapterFiles;
  310. private String[] adapterArguments;
  311. private IMessageHolder messageHolder;
  312. private ICommandEditor commandEditor;
  313. // -------- resource-copying
  314. /** true if copying injar non-.class files to the output jar */
  315. private boolean copyInjars;
  316. private boolean copyInpath;
  317. /** non-null if copying all source root files but the filtered ones */
  318. private String sourceRootCopyFilter;
  319. /** non-null if copying all inpath dir files but the filtered ones */
  320. private String inpathDirCopyFilter;
  321. /** directory sink for classes */
  322. private File destDir;
  323. /** zip file sink for classes */
  324. private File outjar;
  325. /** track whether we've supplied any temp outjar */
  326. private boolean outjarFixedup;
  327. /**
  328. * When possibly copying resources to the output jar, pass ajc a fake output jar to copy from, so we don't change the
  329. * modification time of the output jar when copying injars/inpath into the actual outjar.
  330. */
  331. private File tmpOutjar;
  332. private boolean executing;
  333. /** non-null only while executing in same vm */
  334. private Main main;
  335. /** true only when executing in other vm */
  336. private boolean executingInOtherVM;
  337. /** true if -incremental */
  338. private boolean inIncrementalMode;
  339. /** true if -XincrementalFile (i.e, setTagFile) */
  340. private boolean inIncrementalFileMode;
  341. /** log command in non-verbose mode */
  342. private boolean logCommand;
  343. /** used when forking */
  344. private CommandlineJava javaCmd = new CommandlineJava();
  345. // also note MatchingTask grabs source files...
  346. public AjcTask() {
  347. reset();
  348. }
  349. /** to use this same Task more than once (testing) */
  350. public void reset() { // XXX possible to reset MatchingTask?
  351. // need declare for "all fields initialized in ..."
  352. adapterArguments = null;
  353. adapterFiles = new ArrayList<>();
  354. compilerArgs = null;
  355. argfiles = null;
  356. inxmlfiles = null;
  357. executing = false;
  358. aspectpath = null;
  359. bootclasspath = null;
  360. classpath = null;
  361. cmd = new GuardedCommand();
  362. copyInjars = false;
  363. copyInpath = false;
  364. destDir = DEFAULT_DESTDIR;
  365. executing = false;
  366. executingInOtherVM = false;
  367. extdirs = null;
  368. failonerror = true; // non-standard default
  369. forkclasspath = null;
  370. inIncrementalMode = false;
  371. inIncrementalFileMode = false;
  372. ignored = new ArrayList<>();
  373. injars = null;
  374. inpath = null;
  375. listFileArgs = false;
  376. maxMem = null;
  377. messageHolder = null;
  378. outjar = null;
  379. sourceRootCopyFilter = null;
  380. inpathDirCopyFilter = null;
  381. sourceRoots = null;
  382. srcdir = null;
  383. tmpOutjar = null;
  384. verbose = false;
  385. timers = false;
  386. xweaveDir = null;
  387. xdoneSignal = null;
  388. logCommand = false;
  389. javaCmd = new CommandlineJava();
  390. }
  391. protected void ignore(String ignored) {
  392. this.ignored.add(ignored + " at " + getLocation());
  393. }
  394. // ---------------------- option values
  395. // used by entries with internal commas
  396. protected String validCommaList(String list, List valid, String label) {
  397. return validCommaList(list, valid, label, valid.size());
  398. }
  399. protected String validCommaList(String list, List valid, String label, int max) {
  400. StringBuilder result = new StringBuilder();
  401. StringTokenizer st = new StringTokenizer(list, ",");
  402. int num = 0;
  403. while (st.hasMoreTokens()) {
  404. String token = st.nextToken().trim();
  405. num++;
  406. if (num > max) {
  407. ignore("too many entries for -" + label + ": " + token);
  408. break;
  409. }
  410. if (!valid.contains(token)) {
  411. ignore("bad commaList entry for -" + label + ": " + token);
  412. } else {
  413. if (0 < result.length()) {
  414. result.append(",");
  415. }
  416. result.append(token);
  417. }
  418. }
  419. return (0 == result.length() ? null : result.toString());
  420. }
  421. /**
  422. * Controls whether annotation processing and/or compilation is done.
  423. * -proc:none means that compilation takes place without annotation processing.
  424. * -proc:only means that only annotation processing is done, without any subsequent compilation.
  425. */
  426. public void setProc(String proc) {
  427. if (proc.equals("none")) {
  428. cmd.addFlag("-proc:none", true);
  429. } else if (proc.equals("only")) {
  430. cmd.addFlag("-proc:only", true);
  431. }
  432. }
  433. /**
  434. * -processor class1[,class2,class3...]
  435. * Names of the annotation processors to run. This bypasses the default discovery process.
  436. */
  437. public void setProcessor(String processors) {
  438. cmd.addFlagged("-processor", processors);
  439. }
  440. /**
  441. * -processorpath path
  442. * Specify where to find annotation processors; if this option is not used, the class path will be searched for processors.
  443. */
  444. public void setProcessorpath(String processorpath) {
  445. cmd.addFlagged("-processorpath", processorpath);
  446. }
  447. /**
  448. * -s dir
  449. * Specify the directory where to place generated source files. The directory must already exist; javac will not create it.
  450. * If a class is part of a package, the compiler puts the source file in a subdirectory reflecting the package name,
  451. * creating directories as needed.
  452. *
  453. * For example, if you specify -s C:\mysrc and the class is called com.mypackage.MyClass,
  454. * then the source file will be placed in C:\mysrc\com\mypackage\MyClass.java.
  455. */
  456. public void setS(String s) {
  457. cmd.addFlagged("-s", s);
  458. }
  459. public void setIncremental(boolean incremental) {
  460. cmd.addFlag("-incremental", incremental);
  461. inIncrementalMode = incremental;
  462. }
  463. public void setLogCommand(boolean logCommand) {
  464. this.logCommand = logCommand;
  465. }
  466. public void setHelp(boolean help) {
  467. cmd.addFlag("-help", help);
  468. }
  469. public void setVersion(boolean version) {
  470. cmd.addFlag("-version", version);
  471. }
  472. public void setXTerminateAfterCompilation(boolean b) {
  473. cmd.addFlag("-XterminateAfterCompilation", b);
  474. }
  475. public void setXReweavable(boolean reweavable) {
  476. cmd.addFlag("-Xreweavable", reweavable);
  477. }
  478. public void setXmlConfigured(boolean xmlConfigured) {
  479. cmd.addFlag("-xmlConfigured", xmlConfigured);
  480. }
  481. public void setXJoinpoints(String optionalJoinpoints) {
  482. cmd.addFlag("-Xjoinpoints:" + optionalJoinpoints, true);
  483. }
  484. public void setCheckRuntimeVersion(boolean b) {
  485. cmd.addFlag("-checkRuntimeVersion:" + b, true);
  486. }
  487. public void setXNoWeave(boolean b) {
  488. if (logger != null) {
  489. logger.warning("the noweave option is no longer required and is being ignored");
  490. }
  491. }
  492. public void setNoWeave(boolean b) {
  493. if (logger != null) {
  494. logger.warning("the noweave option is no longer required and is being ignored");
  495. }
  496. }
  497. public void setXNotReweavable(boolean notReweavable) {
  498. cmd.addFlag("-XnotReweavable", notReweavable);
  499. }
  500. public void setXaddSerialVersionUID(boolean addUID) {
  501. cmd.addFlag("-XaddSerialVersionUID", addUID);
  502. }
  503. public void setXNoInline(boolean noInline) {
  504. cmd.addFlag("-XnoInline", noInline);
  505. }
  506. public void setShowWeaveInfo(boolean showweaveinfo) {
  507. cmd.addFlag("-showWeaveInfo", showweaveinfo);
  508. }
  509. public void setNowarn(boolean nowarn) {
  510. cmd.addFlag("-nowarn", nowarn);
  511. }
  512. public void setDeprecation(boolean deprecation) {
  513. cmd.addFlag("-deprecation", deprecation);
  514. }
  515. public void setWarn(String warnings) {
  516. warnings = validCommaList(warnings, VALID_WARNINGS, "warn");
  517. cmd.addFlag("-warn:" + warnings, (null != warnings));
  518. }
  519. public void setDebug(boolean debug) {
  520. cmd.addFlag("-g", debug);
  521. }
  522. public void setDebugLevel(String level) {
  523. level = validCommaList(level, VALID_DEBUG, "g");
  524. cmd.addFlag("-g:" + level, (null != level));
  525. }
  526. public void setEmacssym(boolean emacssym) {
  527. cmd.addFlag("-emacssym", emacssym);
  528. }
  529. public void setCrossrefs(boolean on) {
  530. cmd.addFlag("-crossrefs", on);
  531. }
  532. /**
  533. * -Xlint - set default level of -Xlint messages to warning (same as <code>-Xlint:warning</code>)
  534. */
  535. public void setXlintwarnings(boolean xlintwarnings) {
  536. cmd.addFlag("-Xlint", xlintwarnings);
  537. }
  538. /**
  539. * -Xlint:{error|warning|info} - set default level for -Xlint messages
  540. *
  541. * @param xlint the String with one of error, warning, ignored
  542. */
  543. public void setXlint(String xlint) {
  544. xlint = validCommaList(xlint, VALID_XLINT, "Xlint", 1);
  545. cmd.addFlag("-Xlint:" + xlint, (null != xlint));
  546. }
  547. /**
  548. * -Xlintfile {lint.properties} - enable or disable specific forms of -Xlint messages based on a lint properties file (default
  549. * is <code>org/aspectj/weaver/XLintDefault.properties</code>)
  550. *
  551. * @param xlintFile the File with lint properties
  552. */
  553. public void setXlintfile(File xlintFile) {
  554. cmd.addFlagged("-Xlintfile", xlintFile.getAbsolutePath());
  555. }
  556. public void setPreserveAllLocals(boolean preserveAllLocals) {
  557. cmd.addFlag("-preserveAllLocals", preserveAllLocals);
  558. }
  559. public void setNoImportError(boolean noImportError) {
  560. cmd.addFlag("-warn:-unusedImport", noImportError);
  561. }
  562. public void setEncoding(String encoding) {
  563. cmd.addFlagged("-encoding", encoding);
  564. }
  565. public void setLog(File file) {
  566. cmd.addFlagged("-log", file.getAbsolutePath());
  567. }
  568. public void setProceedOnError(boolean proceedOnError) {
  569. cmd.addFlag("-proceedOnError", proceedOnError);
  570. }
  571. public void setVerbose(boolean verbose) {
  572. cmd.addFlag("-verbose", verbose);
  573. this.verbose = verbose;
  574. }
  575. public void setTimers(boolean timers) {
  576. cmd.addFlag("-timers", timers);
  577. this.timers = timers;
  578. }
  579. public void setListFileArgs(boolean listFileArgs) {
  580. this.listFileArgs = listFileArgs;
  581. }
  582. public void setReferenceInfo(boolean referenceInfo) {
  583. cmd.addFlag("-referenceInfo", referenceInfo);
  584. }
  585. public void setTime(boolean time) {
  586. cmd.addFlag("-time", time);
  587. }
  588. public void setNoExit(boolean noExit) {
  589. cmd.addFlag("-noExit", noExit);
  590. }
  591. public void setFailonerror(boolean failonerror) {
  592. this.failonerror = failonerror;
  593. }
  594. /**
  595. * @return true if fork was set
  596. */
  597. public boolean isForked() {
  598. return fork;
  599. }
  600. public void setFork(boolean fork) {
  601. this.fork = fork;
  602. }
  603. public void setMaxmem(String maxMem) {
  604. this.maxMem = maxMem;
  605. }
  606. /** support for nested &lt;jvmarg&gt; elements */
  607. public Commandline.Argument createJvmarg() {
  608. return this.javaCmd.createVmArgument();
  609. }
  610. public static class CompilerArg {
  611. private String value;
  612. public String getValue() {
  613. return value;
  614. }
  615. public void setValue(String value) {
  616. this.value = value;
  617. }
  618. @Override
  619. public String toString() {
  620. return value;
  621. }
  622. }
  623. public CompilerArg createCompilerarg() {
  624. CompilerArg compilerArg = new CompilerArg();
  625. if (compilerArgs == null) {
  626. compilerArgs = new ArrayList<>();
  627. }
  628. compilerArgs.add(compilerArg);
  629. return compilerArg;
  630. }
  631. // ----------------
  632. public void setTagFile(File file) {
  633. inIncrementalMode = true;
  634. cmd.addFlagged(Main.CommandController.TAG_FILE_OPTION, file.getAbsolutePath());
  635. inIncrementalFileMode = true;
  636. }
  637. public void setOutjar(File file) {
  638. if (DEFAULT_DESTDIR != destDir) {
  639. String e = "specifying both output jar (" + file + ") and destination dir (" + destDir + ")";
  640. throw new BuildException(e);
  641. }
  642. outjar = file;
  643. outjarFixedup = false;
  644. tmpOutjar = null;
  645. }
  646. public void setOutxml(boolean outxml) {
  647. cmd.addFlag("-outxml", outxml);
  648. }
  649. public void setOutxmlfile(String name) {
  650. cmd.addFlagged("-outxmlfile", name);
  651. }
  652. public void setDestdir(File dir) {
  653. if (null != outjar) {
  654. String e = "specifying both output jar (" + outjar + ") and destination dir (" + dir + ")";
  655. throw new BuildException(e);
  656. }
  657. cmd.addFlagged("-d", dir.getAbsolutePath());
  658. destDir = dir;
  659. }
  660. /**
  661. * @param input a String in TARGET_INPUTS
  662. */
  663. public void setTarget(String input) {
  664. String ignore = cmd.addOption("-target", TARGET_INPUTS, input);
  665. if (null != ignore) {
  666. ignore(ignore);
  667. }
  668. }
  669. /**
  670. * Language compliance level. If not set explicitly, eclipse default holds.
  671. *
  672. * @param input a String in COMPLIANCE_INPUTS
  673. */
  674. public void setCompliance(String input) {
  675. String ignore = cmd.addOption(null, COMPLIANCE_INPUTS, input);
  676. if (null != ignore) {
  677. ignore(ignore);
  678. }
  679. }
  680. /**
  681. * Source compliance level. If not set explicitly, eclipse default holds.
  682. *
  683. * @param input a String in SOURCE_INPUTS
  684. */
  685. public void setSource(String input) {
  686. String ignore = cmd.addOption("-source", SOURCE_INPUTS, input);
  687. if (null != ignore) {
  688. ignore(ignore);
  689. }
  690. }
  691. public void setParameters(boolean b) {
  692. cmd.addFlag("-parameters",b);
  693. }
  694. /**
  695. * Flag to copy all non-.class contents of injars to outjar after compile completes. Requires both injars and outjar.
  696. *
  697. * @param doCopy
  698. */
  699. public void setCopyInjars(boolean doCopy) {
  700. ignore("copyInJars");
  701. log("copyInjars not required since 1.1.1.\n", Project.MSG_WARN);
  702. // this.copyInjars = doCopy;
  703. }
  704. /**
  705. * Option to copy all files from all source root directories except those specified here. If this is specified and sourceroots
  706. * are specified, then this will copy all files except those specified in the filter pattern. Requires sourceroots.
  707. *
  708. * @param filter a String acceptable as an excludes filter for an Ant Zip fileset.
  709. */
  710. public void setSourceRootCopyFilter(String filter) {
  711. this.sourceRootCopyFilter = filter;
  712. }
  713. /**
  714. * Option to copy all files from all inpath directories except the files specified here. If this is specified and inpath
  715. * directories are specified, then this will copy all files except those specified in the filter pattern. Requires inpath. If
  716. * the input does not contain "**\/*.class", then this prepends it, to avoid overwriting woven classes with unwoven input.
  717. *
  718. * @param filter a String acceptable as an excludes filter for an Ant Zip fileset.
  719. */
  720. public void setInpathDirCopyFilter(String filter) {
  721. if (null != filter) {
  722. if (!filter.contains("**/*.class")) {
  723. filter = "**/*.class," + filter;
  724. }
  725. }
  726. this.inpathDirCopyFilter = filter;
  727. }
  728. public void setX(String input) { // ajc-only eajc-also docDone
  729. StringTokenizer tokens = new StringTokenizer(input, ",", false);
  730. while (tokens.hasMoreTokens()) {
  731. String token = tokens.nextToken().trim();
  732. if (1 < token.length()) {
  733. // new special case: allow -Xset:anything
  734. if (VALID_XOPTIONS.contains(token) || token.indexOf("set:") == 0 || token.indexOf("joinpoints:") == 0) {
  735. cmd.addFlag("-X" + token, true);
  736. } else {
  737. ignore("-X" + token);
  738. }
  739. }
  740. }
  741. }
  742. public void setXDoneSignal(String doneSignal) {
  743. this.xdoneSignal = doneSignal;
  744. }
  745. /** direct API for testing */
  746. public void setMessageHolder(IMessageHolder holder) {
  747. this.messageHolder = holder;
  748. }
  749. /**
  750. * Setup custom message handling.
  751. *
  752. * @param className the String fully-qualified-name of a class reachable from this object's class loader, implementing
  753. * IMessageHolder, and having a public no-argument constructor.
  754. * @throws BuildException if unable to create instance of className
  755. */
  756. public void setMessageHolderClass(String className) {
  757. try {
  758. Class<?> mclass = Class.forName(className);
  759. IMessageHolder holder = (IMessageHolder) mclass.getDeclaredConstructor().newInstance();
  760. setMessageHolder(holder);
  761. } catch (Throwable t) {
  762. String m = "unable to instantiate message holder: " + className;
  763. throw new BuildException(m, t);
  764. }
  765. }
  766. /** direct API for testing */
  767. public void setCommandEditor(ICommandEditor editor) {
  768. this.commandEditor = editor;
  769. }
  770. /**
  771. * Setup command-line filter. To do this staticly, define the environment variable
  772. * <code>org.aspectj.tools.ant.taskdefs.AjcTask.COMMAND_EDITOR</code> with the <code>className</code> parameter.
  773. *
  774. * @param className the String fully-qualified-name of a class reachable from this object's class loader, implementing
  775. * ICommandEditor, and having a public no-argument constructor.
  776. * @throws BuildException if unable to create instance of className
  777. */
  778. public void setCommandEditorClass(String className) { // skip Ant interface?
  779. try {
  780. Class<?> mclass = Class.forName(className);
  781. setCommandEditor((ICommandEditor) mclass.getDeclaredConstructor().newInstance());
  782. } catch (Throwable t) {
  783. String m = "unable to instantiate command editor: " + className;
  784. throw new BuildException(m, t);
  785. }
  786. }
  787. // ---------------------- Path lists
  788. /**
  789. * Add path elements to source path and return result. Elements are added even if they do not exist.
  790. *
  791. * @param source the Path to add to - may be null
  792. * @param toAdd the Path to add - may be null
  793. * @return the (never-null) Path that results
  794. */
  795. protected Path incPath(Path source, Path toAdd) {
  796. if (null == source) {
  797. source = new Path(project);
  798. }
  799. if (null != toAdd) {
  800. source.append(toAdd);
  801. }
  802. return source;
  803. }
  804. public void setSourcerootsref(Reference ref) {
  805. createSourceRoots().setRefid(ref);
  806. }
  807. public void setSourceRoots(Path roots) {
  808. sourceRoots = incPath(sourceRoots, roots);
  809. }
  810. public Path createSourceRoots() {
  811. if (sourceRoots == null) {
  812. sourceRoots = new Path(project);
  813. }
  814. return sourceRoots.createPath();
  815. }
  816. public void setXWeaveDir(File file) {
  817. if ((null != file) && file.isDirectory() && file.canRead()) {
  818. xweaveDir = file;
  819. }
  820. }
  821. public void setInjarsref(Reference ref) {
  822. createInjars().setRefid(ref);
  823. }
  824. public void setInpathref(Reference ref) {
  825. createInpath().setRefid(ref);
  826. }
  827. public void setInjars(Path path) {
  828. injars = incPath(injars, path);
  829. }
  830. public void setInpath(Path path) {
  831. inpath = incPath(inpath, path);
  832. }
  833. public Path createInjars() {
  834. if (injars == null) {
  835. injars = new Path(project);
  836. }
  837. return injars.createPath();
  838. }
  839. public Path createInpath() {
  840. if (inpath == null) {
  841. inpath = new Path(project);
  842. }
  843. return inpath.createPath();
  844. }
  845. public void setClasspath(Path path) {
  846. classpath = incPath(classpath, path);
  847. }
  848. public void setClasspathref(Reference classpathref) {
  849. createClasspath().setRefid(classpathref);
  850. }
  851. public Path createClasspath() {
  852. if (classpath == null) {
  853. classpath = new Path(project);
  854. }
  855. return classpath.createPath();
  856. }
  857. public void setBootclasspath(Path path) {
  858. bootclasspath = incPath(bootclasspath, path);
  859. }
  860. public void setBootclasspathref(Reference bootclasspathref) {
  861. createBootclasspath().setRefid(bootclasspathref);
  862. }
  863. public Path createBootclasspath() {
  864. if (bootclasspath == null) {
  865. bootclasspath = new Path(project);
  866. }
  867. return bootclasspath.createPath();
  868. }
  869. public void setForkclasspath(Path path) {
  870. forkclasspath = incPath(forkclasspath, path);
  871. }
  872. public void setForkclasspathref(Reference forkclasspathref) {
  873. createForkclasspath().setRefid(forkclasspathref);
  874. }
  875. public Path createForkclasspath() {
  876. if (forkclasspath == null) {
  877. forkclasspath = new Path(project);
  878. }
  879. return forkclasspath.createPath();
  880. }
  881. public void setExtdirs(Path path) {
  882. extdirs = incPath(extdirs, path);
  883. }
  884. public void setExtdirsref(Reference ref) {
  885. createExtdirs().setRefid(ref);
  886. }
  887. public Path createExtdirs() {
  888. if (extdirs == null) {
  889. extdirs = new Path(project);
  890. }
  891. return extdirs.createPath();
  892. }
  893. public void setAspectpathref(Reference ref) {
  894. createAspectpath().setRefid(ref);
  895. }
  896. public void setAspectpath(Path path) {
  897. aspectpath = incPath(aspectpath, path);
  898. }
  899. public Path createAspectpath() {
  900. if (aspectpath == null) {
  901. aspectpath = new Path(project);
  902. }
  903. return aspectpath.createPath();
  904. }
  905. public void setSrcDir(Path path) {
  906. srcdir = incPath(srcdir, path);
  907. }
  908. public Path createSrc() {
  909. return createSrcdir();
  910. }
  911. public Path createSrcdir() {
  912. if (srcdir == null) {
  913. srcdir = new Path(project);
  914. }
  915. return srcdir.createPath();
  916. }
  917. /** @return true if in incremental mode (command-line or file) */
  918. public boolean isInIncrementalMode() {
  919. return inIncrementalMode;
  920. }
  921. /** @return true if in incremental file mode */
  922. public boolean isInIncrementalFileMode() {
  923. return inIncrementalFileMode;
  924. }
  925. public void setArgfilesref(Reference ref) {
  926. createArgfiles().setRefid(ref);
  927. }
  928. public void setArgfiles(Path path) { // ajc-only eajc-also docDone
  929. argfiles = incPath(argfiles, path);
  930. }
  931. public Path createArgfiles() {
  932. if (argfiles == null) {
  933. argfiles = new Path(project);
  934. }
  935. return argfiles.createPath();
  936. }
  937. public void setInxmlref(Reference ref) {
  938. createArgfiles().setRefid(ref);
  939. }
  940. public void setInxml(Path path) { // ajc-only eajc-also docDone
  941. inxmlfiles = incPath(inxmlfiles, path);
  942. }
  943. public Path createInxml() {
  944. if (inxmlfiles == null) {
  945. inxmlfiles = new Path(project);
  946. }
  947. return inxmlfiles.createPath();
  948. }
  949. // ------------------------------ run
  950. /**
  951. * Compile using ajc per settings.
  952. *
  953. * @exception BuildException if the compilation has problems or if there were compiler errors and failonerror is true.
  954. */
  955. @Override
  956. public void execute() throws BuildException {
  957. this.logger = new TaskLogger(this);
  958. if (executing) {
  959. throw new IllegalStateException("already executing");
  960. } else {
  961. executing = true;
  962. }
  963. setupOptions();
  964. verifyOptions();
  965. try {
  966. String[] args = makeCommand();
  967. if (logCommand) {
  968. log("ajc " + Arrays.asList(args));
  969. } else {
  970. logVerbose("ajc " + Arrays.asList(args));
  971. }
  972. if (!fork) {
  973. executeInSameVM(args);
  974. } else { // when forking, Adapter handles failonerror
  975. executeInOtherVM(args);
  976. }
  977. } catch (BuildException e) {
  978. throw e;
  979. } catch (Throwable x) {
  980. this.logger.error(Main.renderExceptionForUser(x));
  981. throw new BuildException("IGNORE -- See " + LangUtil.unqualifiedClassName(x) + " rendered to ant logger");
  982. } finally {
  983. executing = false;
  984. if (null != tmpOutjar) {
  985. tmpOutjar.delete();
  986. }
  987. }
  988. }
  989. /**
  990. * Halt processing. This tells main in the same vm to quit. It fails when running in forked mode.
  991. *
  992. * @return true if not in forked mode and main has quit or been told to quit
  993. */
  994. public boolean quit() {
  995. if (executingInOtherVM) {
  996. return false;
  997. }
  998. Main me = main;
  999. if (null != me) {
  1000. me.quit();
  1001. }
  1002. return true;
  1003. }
  1004. // package-private for testing
  1005. String[] makeCommand() {
  1006. if (0 < ignored.size()) {
  1007. for (String o : ignored) {
  1008. logVerbose("ignored: " + o);
  1009. }
  1010. }
  1011. // when copying resources, use temp jar for class output
  1012. // then copy temp jar contents and resources to output jar
  1013. if ((null != outjar) && !outjarFixedup) {
  1014. if (copyInjars || copyInpath || (null != sourceRootCopyFilter) || (null != inpathDirCopyFilter)) {
  1015. String path = outjar.getAbsolutePath();
  1016. int len = FileUtil.zipSuffixLength(path);
  1017. path = path.substring(0, path.length() - len) + ".tmp.jar";
  1018. tmpOutjar = new File(path);
  1019. }
  1020. if (null == tmpOutjar) {
  1021. cmd.addFlagged("-outjar", outjar.getAbsolutePath());
  1022. } else {
  1023. cmd.addFlagged("-outjar", tmpOutjar.getAbsolutePath());
  1024. }
  1025. outjarFixedup = true;
  1026. }
  1027. ArrayList<String> result = new ArrayList(cmd.extractArguments());
  1028. addListArgs(result);
  1029. String[] command = result.toArray(new String[0]);
  1030. if (null != commandEditor) {
  1031. command = commandEditor.editCommand(command);
  1032. } else if (null != COMMAND_EDITOR) {
  1033. command = COMMAND_EDITOR.editCommand(command);
  1034. }
  1035. return command;
  1036. }
  1037. /**
  1038. * Create any pseudo-options required to implement some of the macro options
  1039. *
  1040. * @throws BuildException if options conflict
  1041. */
  1042. protected void setupOptions() {
  1043. if (null != xweaveDir) {
  1044. if (DEFAULT_DESTDIR != destDir) {
  1045. throw new BuildException("weaveDir forces destdir");
  1046. }
  1047. if (null != outjar) {
  1048. throw new BuildException("weaveDir forces outjar");
  1049. }
  1050. if (null != injars) {
  1051. throw new BuildException("weaveDir incompatible with injars now");
  1052. }
  1053. if (null != inpath) {
  1054. throw new BuildException("weaveDir incompatible with inpath now");
  1055. }
  1056. File injar = zipDirectory(xweaveDir);
  1057. setInjars(new Path(getProject(), injar.getAbsolutePath()));
  1058. setDestdir(xweaveDir);
  1059. }
  1060. }
  1061. protected File zipDirectory(File dir) {
  1062. File tempDir = new File(".");
  1063. try {
  1064. tempDir = File.createTempFile("AjcTest", ".tmp");
  1065. tempDir.mkdirs();
  1066. tempDir.deleteOnExit(); // XXX remove zip explicitly..
  1067. } catch (IOException e) {
  1068. // ignore
  1069. }
  1070. // File result = new File(tempDir,
  1071. String filename = "AjcTask-" + System.currentTimeMillis() + ".zip";
  1072. File result = new File(filename);
  1073. Zip zip = new Zip();
  1074. zip.setProject(getProject());
  1075. zip.setDestFile(result);
  1076. zip.setTaskName(getTaskName() + " - zip");
  1077. FileSet fileset = new FileSet();
  1078. fileset.setDir(dir);
  1079. zip.addFileset(fileset);
  1080. zip.execute();
  1081. Delete delete = new Delete();
  1082. delete.setProject(getProject());
  1083. delete.setTaskName(getTaskName() + " - delete");
  1084. delete.setDir(dir);
  1085. delete.execute();
  1086. Mkdir mkdir = new Mkdir();
  1087. mkdir.setProject(getProject());
  1088. mkdir.setTaskName(getTaskName() + " - mkdir");
  1089. mkdir.setDir(dir);
  1090. mkdir.execute();
  1091. return result;
  1092. }
  1093. /**
  1094. * @throws BuildException if options conflict
  1095. */
  1096. protected void verifyOptions() {
  1097. StringBuilder sb = new StringBuilder();
  1098. if (fork && isInIncrementalMode() && !isInIncrementalFileMode()) {
  1099. sb.append("can fork incremental only using tag file.\n");
  1100. }
  1101. if (((null != inpathDirCopyFilter) || (null != sourceRootCopyFilter)) && (null == outjar) && (DEFAULT_DESTDIR == destDir)) {
  1102. final String REQ = " requires dest dir or output jar.\n";
  1103. if (null == inpathDirCopyFilter) {
  1104. sb.append("sourceRootCopyFilter");
  1105. } else if (null == sourceRootCopyFilter) {
  1106. sb.append("inpathDirCopyFilter");
  1107. } else {
  1108. sb.append("sourceRootCopyFilter and inpathDirCopyFilter");
  1109. }
  1110. sb.append(REQ);
  1111. }
  1112. if (0 < sb.length()) {
  1113. throw new BuildException(sb.toString());
  1114. }
  1115. }
  1116. /**
  1117. * Run the compile in the same VM by loading the compiler (Main), setting up any message holders, doing the compile, and
  1118. * converting abort/failure and error messages to BuildException, as appropriate.
  1119. *
  1120. * @throws BuildException if abort or failure messages or if errors and failonerror.
  1121. *
  1122. */
  1123. protected void executeInSameVM(String[] args) {
  1124. if (null != maxMem) {
  1125. log("maxMem ignored unless forked: " + maxMem, Project.MSG_WARN);
  1126. }
  1127. IMessageHolder holder = messageHolder;
  1128. int numPreviousErrors;
  1129. if (null == holder) {
  1130. MessageHandler mhandler = new MessageHandler(true);
  1131. final IMessageHandler delegate;
  1132. delegate = new AntMessageHandler(this.logger, this.verbose, false);
  1133. mhandler.setInterceptor(delegate);
  1134. holder = mhandler;
  1135. numPreviousErrors = 0;
  1136. } else {
  1137. numPreviousErrors = holder.numMessages(IMessage.ERROR, true);
  1138. }
  1139. {
  1140. Main newmain = new Main();
  1141. newmain.setHolder(holder);
  1142. newmain.setCompletionRunner(new Runnable() {
  1143. @Override
  1144. public void run() {
  1145. doCompletionTasks();
  1146. }
  1147. });
  1148. if (null != main) {
  1149. MessageUtil.fail(holder, "still running prior main");
  1150. return;
  1151. }
  1152. main = newmain;
  1153. }
  1154. main.runMain(args, false);
  1155. if (failonerror) {
  1156. int errs = holder.numMessages(IMessage.ERROR, false);
  1157. errs -= numPreviousErrors;
  1158. if (0 < errs) {
  1159. String m = errs + " errors";
  1160. MessageUtil.print(System.err, holder, "", MessageUtil.MESSAGE_ALL, MessageUtil.PICK_ERROR, true);
  1161. throw new BuildException(m);
  1162. }
  1163. }
  1164. // Throw BuildException if there are any fail or abort
  1165. // messages.
  1166. // The BuildException message text has a list of class names
  1167. // for the exceptions found in the messages, or the
  1168. // number of fail/abort messages found if there were
  1169. // no exceptions for any of the fail/abort messages.
  1170. // The interceptor message handler should have already
  1171. // printed the messages, including any stack traces.
  1172. // HACK: this ignores the Usage message
  1173. {
  1174. IMessage[] fails = holder.getMessages(IMessage.FAIL, true);
  1175. if (!LangUtil.isEmpty(fails)) {
  1176. StringBuilder sb = new StringBuilder();
  1177. String prefix = "fail due to ";
  1178. int numThrown = 0;
  1179. for (IMessage fail : fails) {
  1180. String message = fail.getMessage();
  1181. if (LangUtil.isEmpty(message)) {
  1182. message = "<no message>";
  1183. } else if (message.contains(USAGE_SUBSTRING)) {
  1184. continue;
  1185. }
  1186. Throwable t = fail.getThrown();
  1187. if (null != t) {
  1188. numThrown++;
  1189. sb.append(prefix);
  1190. sb.append(LangUtil.unqualifiedClassName(t.getClass()));
  1191. String thrownMessage = t.getMessage();
  1192. if (!LangUtil.isEmpty(thrownMessage)) {
  1193. sb.append(" \"" + thrownMessage + "\"");
  1194. }
  1195. }
  1196. sb.append("\"" + message + "\"");
  1197. prefix = ", ";
  1198. }
  1199. if (0 < sb.length()) {
  1200. sb.append(" (" + numThrown + " exceptions)");
  1201. throw new BuildException(sb.toString());
  1202. }
  1203. }
  1204. }
  1205. }
  1206. /**
  1207. * Execute in a separate VM. Differences from normal same-VM execution:
  1208. * <ul>
  1209. * <li>ignores any message holder {class} set</li>
  1210. * <li>No resource-copying between interative runs</li>
  1211. * <li>failonerror fails when process interface fails to return negative values</li>
  1212. * </ul>
  1213. *
  1214. * @param args String[] of the complete compiler command to execute
  1215. *
  1216. * @throws BuildException if ajc aborts (negative value) or if failonerror and there were compile errors.
  1217. */
  1218. protected void executeInOtherVM(String[] args) {
  1219. javaCmd.setClassname(org.aspectj.tools.ajc.Main.class.getName());
  1220. final Path vmClasspath = javaCmd.createClasspath(getProject());
  1221. {
  1222. File aspectjtools = null;
  1223. int vmClasspathSize = vmClasspath.size();
  1224. if ((null != forkclasspath) && (0 != forkclasspath.size())) {
  1225. vmClasspath.addExisting(forkclasspath);
  1226. } else {
  1227. aspectjtools = findAspectjtoolsJar();
  1228. if (null != aspectjtools) {
  1229. vmClasspath.createPathElement().setLocation(aspectjtools);
  1230. }
  1231. }
  1232. int newVmClasspathSize = vmClasspath.size();
  1233. if (vmClasspathSize == newVmClasspathSize) {
  1234. String m = "unable to find aspectjtools to fork - ";
  1235. if (null != aspectjtools) {
  1236. m += "tried " + aspectjtools.toString();
  1237. } else if (null != forkclasspath) {
  1238. m += "tried " + forkclasspath.toString();
  1239. } else {
  1240. m += "define forkclasspath or put aspectjtools on classpath";
  1241. }
  1242. throw new BuildException(m);
  1243. }
  1244. }
  1245. if (null != maxMem) {
  1246. javaCmd.setMaxmemory(maxMem);
  1247. }
  1248. File tempFile = null;
  1249. int numArgs = args.length;
  1250. args = GuardedCommand.limitTo(args, MAX_COMMANDLINE, getLocation());
  1251. if (args.length != numArgs) {
  1252. tempFile = new File(args[1]);
  1253. }
  1254. try {
  1255. boolean setMessageHolderOnForking = (this.messageHolder != null);
  1256. String[] javaArgs = javaCmd.getCommandline();
  1257. String[] both = new String[javaArgs.length + args.length + (setMessageHolderOnForking ? 2 : 0)];
  1258. System.arraycopy(javaArgs, 0, both, 0, javaArgs.length);
  1259. System.arraycopy(args, 0, both, javaArgs.length, args.length);
  1260. if (setMessageHolderOnForking) {
  1261. both[both.length - 2] = "-messageHolder";
  1262. both[both.length - 1] = this.messageHolder.getClass().getName();
  1263. }
  1264. // try to use javaw instead on windows
  1265. if (both[0].endsWith("java.exe")) {
  1266. String path = both[0];
  1267. path = path.substring(0, path.length() - 4);
  1268. path = path + "w.exe";
  1269. File javaw = new File(path);
  1270. if (javaw.canRead() && javaw.isFile()) {
  1271. both[0] = path;
  1272. }
  1273. }
  1274. logVerbose("forking " + Arrays.asList(both));
  1275. int result = execInOtherVM(both);
  1276. if (0 > result) {
  1277. throw new BuildException("failure[" + result + "] running ajc");
  1278. } else if (failonerror && (0 < result)) {
  1279. throw new BuildException("compile errors: " + result);
  1280. }
  1281. // when forking, do completion only at end and when successful
  1282. doCompletionTasks();
  1283. } finally {
  1284. if (null != tempFile) {
  1285. tempFile.delete();
  1286. }
  1287. }
  1288. }
  1289. /**
  1290. * Execute in another process using the same JDK and the base directory of the project. XXX correct?
  1291. */
  1292. protected int execInOtherVM(String[] args) {
  1293. try {
  1294. Project project = getProject();
  1295. PumpStreamHandler handler = new LogStreamHandler(this, verbose ? Project.MSG_VERBOSE : Project.MSG_INFO,
  1296. Project.MSG_WARN);
  1297. // replace above two lines with what follows as an aid to debugging when running the unit tests....
  1298. // LogStreamHandler handler = new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN) {
  1299. //
  1300. // ByteArrayOutputStream baos = new ByteArrayOutputStream();
  1301. //
  1302. // /*
  1303. // * @see
  1304. // * org.apache.tools.ant.taskdefs.PumpStreamHandler#createProcessOutputPump(java.
  1305. // * io.InputStream, java.io.OutputStream)
  1306. // */
  1307. // protected void createProcessErrorPump(InputStream is, OutputStream os) {
  1308. // super.createProcessErrorPump(is, baos);
  1309. // }
  1310. //
  1311. // /*
  1312. // * @see org.apache.tools.ant.taskdefs.LogStreamHandler#stop()
  1313. // */
  1314. // public void stop() {
  1315. // byte[] written = baos.toByteArray();
  1316. // System.err.print(new String(written));
  1317. // super.stop();
  1318. // }
  1319. // };
  1320. Execute exe = new Execute(handler);
  1321. exe.setAntRun(project);
  1322. exe.setWorkingDirectory(project.getBaseDir());
  1323. exe.setCommandline(args);
  1324. try {
  1325. if (executingInOtherVM) {
  1326. String s = "already running in other vm?";
  1327. throw new BuildException(s, location);
  1328. }
  1329. executingInOtherVM = true;
  1330. exe.execute();
  1331. } finally {
  1332. executingInOtherVM = false;
  1333. }
  1334. return exe.getExitValue();
  1335. } catch (IOException e) {
  1336. String m = "Error executing command " + Arrays.asList(args);
  1337. throw new BuildException(m, e, location);
  1338. }
  1339. }
  1340. // ------------------------------ setup and reporting
  1341. protected static void addFlaggedPath(String flag, Path path, List<String> list) {
  1342. if (!LangUtil.isEmpty(flag) && ((null != path) && (0 < path.size()))) {
  1343. list.add(flag);
  1344. list.add(path.toString());
  1345. }
  1346. }
  1347. /**
  1348. * Add to list any path or plural arguments.
  1349. */
  1350. protected void addListArgs(List<String> list) throws BuildException {
  1351. addFlaggedPath("-classpath", classpath, list);
  1352. addFlaggedPath("-bootclasspath", bootclasspath, list);
  1353. addFlaggedPath("-extdirs", extdirs, list);
  1354. addFlaggedPath("-aspectpath", aspectpath, list);
  1355. addFlaggedPath("-injars", injars, list);
  1356. addFlaggedPath("-inpath", inpath, list);
  1357. addFlaggedPath("-sourceroots", sourceRoots, list);
  1358. if (this.compilerArgs != null) {
  1359. for (CompilerArg compilerArg:compilerArgs) {
  1360. list.add(compilerArg.toString());
  1361. }
  1362. }
  1363. if (argfiles != null) {
  1364. String[] files = argfiles.list();
  1365. for (String file : files) {
  1366. File argfile = project.resolveFile(file);
  1367. if (check(argfile, file, false, location)) {
  1368. list.add("-argfile");
  1369. list.add(argfile.getAbsolutePath());
  1370. }
  1371. }
  1372. }
  1373. if (inxmlfiles != null) {
  1374. String[] files = inxmlfiles.list();
  1375. for (String file : files) {
  1376. File inxmlfile = project.resolveFile(file);
  1377. if (check(inxmlfile, file, false, location)) {
  1378. list.add("-xmlConfigured");
  1379. list.add(inxmlfile.getAbsolutePath());
  1380. }
  1381. }
  1382. }
  1383. if (srcdir != null) {
  1384. // todo: ignore any srcdir if any argfiles and no explicit includes
  1385. String[] dirs = srcdir.list();
  1386. for (String dir2 : dirs) {
  1387. File dir = project.resolveFile(dir2);
  1388. check(dir, dir2, true, location);
  1389. // relies on compiler to prune non-source files
  1390. String[] files = getDirectoryScanner(dir).getIncludedFiles();
  1391. for (String file2 : files) {
  1392. File file = new File(dir, file2);
  1393. if (FileUtil.hasSourceSuffix(file)) {
  1394. if (!list.contains(file.getAbsolutePath())) {
  1395. list.add(file.getAbsolutePath());
  1396. }
  1397. }
  1398. }
  1399. }
  1400. }
  1401. if (0 < adapterFiles.size()) {
  1402. for (File file : adapterFiles) {
  1403. if (file.canRead() && FileUtil.hasSourceSuffix(file)) {
  1404. list.add(file.getAbsolutePath());
  1405. }
  1406. else {
  1407. this.logger.warning("skipping file: " + file);
  1408. }
  1409. }
  1410. }
  1411. }
  1412. /**
  1413. * Throw BuildException unless file is valid.
  1414. *
  1415. * @param file the File to check
  1416. * @param name the symbolic name to print on error
  1417. * @param isDir if true, verify file is a directory
  1418. * @param loc the Location used to create sensible BuildException
  1419. * @return
  1420. * @throws BuildException unless file valid
  1421. */
  1422. protected final boolean check(File file, String name, boolean isDir, Location loc) {
  1423. loc = loc != null ? loc : location;
  1424. if (file == null) {
  1425. throw new BuildException(name + " is null!", loc);
  1426. }
  1427. if (!file.exists()) {
  1428. throw new BuildException(file + " doesn't exist!", loc);
  1429. }
  1430. if (isDir ^ file.isDirectory()) {
  1431. String e = file + " should" + (isDir ? "" : "n't") + " be a directory!";
  1432. throw new BuildException(e, loc);
  1433. }
  1434. return true;
  1435. }
  1436. /**
  1437. * Called when compile or incremental compile is completing, this completes the output jar or directory by copying resources if
  1438. * requested. Note: this is a callback run synchronously by the compiler. That means exceptions thrown here are caught by
  1439. * Main.run(..) and passed to the message handler.
  1440. */
  1441. protected void doCompletionTasks() {
  1442. if (!executing) {
  1443. throw new IllegalStateException("should be executing");
  1444. }
  1445. if (null != outjar) {
  1446. completeOutjar();
  1447. } else {
  1448. completeDestdir();
  1449. }
  1450. if (null != xdoneSignal) {
  1451. MessageUtil.info(messageHolder, xdoneSignal);
  1452. }
  1453. }
  1454. /**
  1455. * Complete the destination directory by copying resources from the source root directories (if the filter is specified) and
  1456. * non-.class files from the input jars (if XCopyInjars is enabled).
  1457. */
  1458. private void completeDestdir() {
  1459. if (!copyInjars && (null == sourceRootCopyFilter) && (null == inpathDirCopyFilter)) {
  1460. return;
  1461. } else if ((destDir == DEFAULT_DESTDIR) || !destDir.canWrite()) {
  1462. String s = "unable to copy resources to destDir: " + destDir;
  1463. throw new BuildException(s);
  1464. }
  1465. final Project project = getProject();
  1466. if (copyInjars) { // XXXX remove as unused since 1.1.1
  1467. if (null != inpath) {
  1468. log("copyInjars does not support inpath.\n", Project.MSG_WARN);
  1469. }
  1470. String taskName = getTaskName() + " - unzip";
  1471. String[] paths = injars.list();
  1472. if (!LangUtil.isEmpty(paths)) {
  1473. PatternSet patternSet = new PatternSet();
  1474. patternSet.setProject(project);
  1475. patternSet.setIncludes("**/*");
  1476. patternSet.setExcludes("**/*.class");
  1477. for (String path : paths) {
  1478. Expand unzip = new Expand();
  1479. unzip.setProject(project);
  1480. unzip.setTaskName(taskName);
  1481. unzip.setDest(destDir);
  1482. unzip.setSrc(new File(path));
  1483. unzip.addPatternset(patternSet);
  1484. unzip.execute();
  1485. }
  1486. }
  1487. }
  1488. if ((null != sourceRootCopyFilter) && (null != sourceRoots)) {
  1489. String[] paths = sourceRoots.list();
  1490. if (!LangUtil.isEmpty(paths)) {
  1491. Copy copy = new Copy();
  1492. copy.setProject(project);
  1493. copy.setTodir(destDir);
  1494. for (String path : paths) {
  1495. FileSet fileSet = new FileSet();
  1496. fileSet.setDir(new File(path));
  1497. fileSet.setIncludes("**/*");
  1498. fileSet.setExcludes(sourceRootCopyFilter);
  1499. copy.addFileset(fileSet);
  1500. }
  1501. copy.execute();
  1502. }
  1503. }
  1504. if ((null != inpathDirCopyFilter) && (null != inpath)) {
  1505. String[] paths = inpath.list();
  1506. if (!LangUtil.isEmpty(paths)) {
  1507. Copy copy = new Copy();
  1508. copy.setProject(project);
  1509. copy.setTodir(destDir);
  1510. boolean gotDir = false;
  1511. for (String path : paths) {
  1512. File inpathDir = new File(path);
  1513. if (inpathDir.isDirectory() && inpathDir.canRead()) {
  1514. if (!gotDir) {
  1515. gotDir = true;
  1516. }
  1517. FileSet fileSet = new FileSet();
  1518. fileSet.setDir(inpathDir);
  1519. fileSet.setIncludes("**/*");
  1520. fileSet.setExcludes(inpathDirCopyFilter);
  1521. copy.addFileset(fileSet);
  1522. }
  1523. }
  1524. if (gotDir) {
  1525. copy.execute();
  1526. }
  1527. }
  1528. }
  1529. }
  1530. /**
  1531. * Complete the output jar by copying resources from the source root directories if the filter is specified. and non-.class
  1532. * files from the input jars if enabled.
  1533. */
  1534. private void completeOutjar() {
  1535. if (((null == tmpOutjar) || !tmpOutjar.canRead())
  1536. || (!copyInjars && (null == sourceRootCopyFilter) && (null == inpathDirCopyFilter))) {
  1537. return;
  1538. }
  1539. Zip zip = new Zip();
  1540. Project project = getProject();
  1541. zip.setProject(project);
  1542. zip.setTaskName(getTaskName() + " - zip");
  1543. zip.setDestFile(outjar);
  1544. ZipFileSet zipfileset = new ZipFileSet();
  1545. zipfileset.setProject(project);
  1546. zipfileset.setSrc(tmpOutjar);
  1547. zipfileset.setIncludes("**/*.class");
  1548. zip.addZipfileset(zipfileset);
  1549. if (copyInjars) {
  1550. String[] paths = injars.list();
  1551. if (!LangUtil.isEmpty(paths)) {
  1552. for (String path : paths) {
  1553. File jarFile = new File(path);
  1554. zipfileset = new ZipFileSet();
  1555. zipfileset.setProject(project);
  1556. zipfileset.setSrc(jarFile);
  1557. zipfileset.setIncludes("**/*");
  1558. zipfileset.setExcludes("**/*.class");
  1559. zip.addZipfileset(zipfileset);
  1560. }
  1561. }
  1562. }
  1563. if ((null != sourceRootCopyFilter) && (null != sourceRoots)) {
  1564. String[] paths = sourceRoots.list();
  1565. if (!LangUtil.isEmpty(paths)) {
  1566. for (String path : paths) {
  1567. File srcRoot = new File(path);
  1568. FileSet fileset = new FileSet();
  1569. fileset.setProject(project);
  1570. fileset.setDir(srcRoot);
  1571. fileset.setIncludes("**/*");
  1572. fileset.setExcludes(sourceRootCopyFilter);
  1573. zip.addFileset(fileset);
  1574. }
  1575. }
  1576. }
  1577. if ((null != inpathDirCopyFilter) && (null != inpath)) {
  1578. String[] paths = inpath.list();
  1579. if (!LangUtil.isEmpty(paths)) {
  1580. for (String path : paths) {
  1581. File inpathDir = new File(path);
  1582. if (inpathDir.isDirectory() && inpathDir.canRead()) {
  1583. FileSet fileset = new FileSet();
  1584. fileset.setProject(project);
  1585. fileset.setDir(inpathDir);
  1586. fileset.setIncludes("**/*");
  1587. fileset.setExcludes(inpathDirCopyFilter);
  1588. zip.addFileset(fileset);
  1589. }
  1590. }
  1591. }
  1592. }
  1593. zip.execute();
  1594. }
  1595. // -------------------------- compiler adapter interface extras
  1596. /**
  1597. * Add specified source files.
  1598. */
  1599. void addFiles(File[] paths) {
  1600. for (File path : paths) {
  1601. addFile(path);
  1602. }
  1603. }
  1604. /**
  1605. * Add specified source file.
  1606. */
  1607. void addFile(File path) {
  1608. if (null != path) {
  1609. adapterFiles.add(path);
  1610. }
  1611. }
  1612. /**
  1613. * Read arguments in as if from a command line, mainly to support compiler adapter compilerarg subelement.
  1614. *
  1615. * @param args the String[] of arguments to read
  1616. */
  1617. public void readArguments(String[] args) { // XXX slow, stupid, unmaintainable
  1618. if ((null == args) || (0 == args.length)) {
  1619. return;
  1620. }
  1621. /** String[] wrapper with increment, error reporting */
  1622. class Args {
  1623. final String[] args;
  1624. int index = 0;
  1625. Args(String[] args) {
  1626. this.args = args; // not null or empty
  1627. }
  1628. boolean hasNext() {
  1629. return index < args.length;
  1630. }
  1631. String next() {
  1632. String err = null;
  1633. if (!hasNext()) {
  1634. err = "need arg for flag " + args[args.length - 1];
  1635. } else {
  1636. String s = args[index++];
  1637. if (null == s) {
  1638. err = "null value";
  1639. } else {
  1640. s = s.trim();
  1641. if (0 == s.trim().length()) {
  1642. err = "no value";
  1643. } else {
  1644. return s;
  1645. }
  1646. }
  1647. }
  1648. err += " at [" + index + "] of " + Arrays.asList(args);
  1649. throw new BuildException(err);
  1650. }
  1651. } // class Args
  1652. Args in = new Args(args);
  1653. String flag;
  1654. while (in.hasNext()) {
  1655. flag = in.next();
  1656. if ("-1.3".equals(flag)) {
  1657. setCompliance(flag);
  1658. } else if ("-1.4".equals(flag)) {
  1659. setCompliance(flag);
  1660. } else if ("-1.5".equals(flag)) {
  1661. setCompliance("1.5");
  1662. } else if ("-argfile".equals(flag)) {
  1663. setArgfiles(new Path(project, in.next()));
  1664. } else if ("-aspectpath".equals(flag)) {
  1665. setAspectpath(new Path(project, in.next()));
  1666. } else if ("-classpath".equals(flag)) {
  1667. setClasspath(new Path(project, in.next()));
  1668. } else if ("-extdirs".equals(flag)) {
  1669. setExtdirs(new Path(project, in.next()));
  1670. } else if ("-Xcopyinjars".equals(flag)) {
  1671. setCopyInjars(true); // ignored - will be flagged by setter
  1672. } else if ("-g".equals(flag)) {
  1673. setDebug(true);
  1674. } else if (flag.startsWith("-g:")) {
  1675. setDebugLevel(flag.substring(2));
  1676. } else if ("-deprecation".equals(flag)) {
  1677. setDeprecation(true);
  1678. } else if ("-d".equals(flag)) {
  1679. setDestdir(new File(in.next()));
  1680. } else if ("-crossrefs".equals(flag)) {
  1681. setCrossrefs(true);
  1682. } else if ("-emacssym".equals(flag)) {
  1683. setEmacssym(true);
  1684. } else if ("-encoding".equals(flag)) {
  1685. setEncoding(in.next());
  1686. } else if ("-Xfailonerror".equals(flag)) {
  1687. setFailonerror(true);
  1688. } else if ("-fork".equals(flag)) {
  1689. setFork(true);
  1690. } else if ("-forkclasspath".equals(flag)) {
  1691. setForkclasspath(new Path(project, in.next()));
  1692. } else if ("-help".equals(flag)) {
  1693. setHelp(true);
  1694. } else if ("-incremental".equals(flag)) {
  1695. setIncremental(true);
  1696. } else if ("-injars".equals(flag)) {
  1697. setInjars(new Path(project, in.next()));
  1698. } else if ("-inpath".equals(flag)) {
  1699. setInpath(new Path(project, in.next()));
  1700. } else if ("-Xlistfileargs".equals(flag)) {
  1701. setListFileArgs(true);
  1702. } else if ("-Xmaxmem".equals(flag)) {
  1703. setMaxmem(in.next());
  1704. } else if ("-Xmessageholderclass".equals(flag)) {
  1705. setMessageHolderClass(in.next());
  1706. } else if ("-noexit".equals(flag)) {
  1707. setNoExit(true);
  1708. } else if ("-noimport".equals(flag)) {
  1709. setNoExit(true);
  1710. } else if ("-noExit".equals(flag)) {
  1711. setNoExit(true);
  1712. } else if ("-noImportError".equals(flag)) {
  1713. setNoImportError(true);
  1714. } else if ("-noWarn".equals(flag)) {
  1715. setNowarn(true);
  1716. } else if ("-noexit".equals(flag)) {
  1717. setNoExit(true);
  1718. } else if ("-outjar".equals(flag)) {
  1719. setOutjar(new File(in.next()));
  1720. } else if ("-outxml".equals(flag)) {
  1721. setOutxml(true);
  1722. } else if ("-outxmlfile".equals(flag)) {
  1723. setOutxmlfile(in.next());
  1724. } else if ("-preserveAllLocals".equals(flag)) {
  1725. setPreserveAllLocals(true);
  1726. } else if ("-proceedOnError".equals(flag)) {
  1727. setProceedOnError(true);
  1728. } else if ("-referenceInfo".equals(flag)) {
  1729. setReferenceInfo(true);
  1730. } else if ("-source".equals(flag)) {
  1731. setSource(in.next());
  1732. } else if ("-Xsourcerootcopyfilter".equals(flag)) {
  1733. setSourceRootCopyFilter(in.next());
  1734. } else if ("-sourceroots".equals(flag)) {
  1735. setSourceRoots(new Path(project, in.next()));
  1736. } else if ("-Xsrcdir".equals(flag)) {
  1737. setSrcDir(new Path(project, in.next()));
  1738. } else if ("-Xtagfile".equals(flag)) {
  1739. setTagFile(new File(in.next()));
  1740. } else if ("-target".equals(flag)) {
  1741. setTarget(in.next());
  1742. } else if ("-time".equals(flag)) {
  1743. setTime(true);
  1744. } else if ("-time".equals(flag)) {
  1745. setTime(true);
  1746. } else if ("-verbose".equals(flag)) {
  1747. setVerbose(true);
  1748. } else if ("-showWeaveInfo".equals(flag)) {
  1749. setShowWeaveInfo(true);
  1750. } else if ("-version".equals(flag)) {
  1751. setVersion(true);
  1752. } else if ("-warn".equals(flag)) {
  1753. setWarn(in.next());
  1754. } else if (flag.startsWith("-warn:")) {
  1755. setWarn(flag.substring(6));
  1756. } else if ("-Xlint".equals(flag)) {
  1757. setXlintwarnings(true);
  1758. } else if (flag.startsWith("-Xlint:")) {
  1759. setXlint(flag.substring(7));
  1760. } else if ("-Xlintfile".equals(flag)) {
  1761. setXlintfile(new File(in.next()));
  1762. } else if ("-XterminateAfterCompilation".equals(flag)) {
  1763. setXTerminateAfterCompilation(true);
  1764. } else if ("-Xreweavable".equals(flag)) {
  1765. setXReweavable(true);
  1766. } else if ("-XnotReweavable".equals(flag)) {
  1767. setXNotReweavable(true);
  1768. } else if (flag.startsWith("@")) {
  1769. File file = new File(flag.substring(1));
  1770. if (file.canRead()) {
  1771. setArgfiles(new Path(project, file.getPath()));
  1772. } else {
  1773. ignore(flag);
  1774. }
  1775. } else {
  1776. File file = new File(flag);
  1777. if (file.isFile() && file.canRead() && FileUtil.hasSourceSuffix(file)) {
  1778. addFile(file);
  1779. } else {
  1780. ignore(flag);
  1781. }
  1782. }
  1783. }
  1784. }
  1785. protected void logVerbose(String text) {
  1786. if (this.verbose) {
  1787. this.logger.info(text);
  1788. } else {
  1789. this.logger.verbose(text);
  1790. }
  1791. }
  1792. /**
  1793. * Commandline wrapper that only permits addition of non-empty values and converts to argfile form if necessary.
  1794. */
  1795. public static class GuardedCommand {
  1796. Commandline command;
  1797. // int size;
  1798. static boolean isEmpty(String s) {
  1799. return ((null == s) || (0 == s.trim().length()));
  1800. }
  1801. GuardedCommand() {
  1802. command = new Commandline();
  1803. }
  1804. void addFlag(String flag, boolean doAdd) {
  1805. if (doAdd && !isEmpty(flag)) {
  1806. command.createArgument().setValue(flag);
  1807. // size += 1 + flag.length();
  1808. }
  1809. }
  1810. /** @return null if added or ignoreString otherwise */
  1811. String addOption(String prefix, String[] validOptions, String input) {
  1812. if (isEmpty(input)) {
  1813. return null;
  1814. }
  1815. for (String validOption : validOptions) {
  1816. if (input.equals(validOption)) {
  1817. if (isEmpty(prefix)) {
  1818. addFlag(input, true);
  1819. } else {
  1820. addFlagged(prefix, input);
  1821. }
  1822. return null;
  1823. }
  1824. }
  1825. return (null == prefix ? input : prefix + " " + input);
  1826. }
  1827. void addFlagged(String flag, String argument) {
  1828. if (!isEmpty(flag) && !isEmpty(argument)) {
  1829. command.addArguments(new String[] { flag, argument });
  1830. // size += 1 + flag.length() + argument.length();
  1831. }
  1832. }
  1833. // private void addFile(File file) {
  1834. // if (null != file) {
  1835. // String path = file.getAbsolutePath();
  1836. // addFlag(path, true);
  1837. // }
  1838. // }
  1839. List extractArguments() {
  1840. List<String> result = new ArrayList<>();
  1841. String[] cmds = command.getArguments();
  1842. if (!LangUtil.isEmpty(cmds)) {
  1843. result.addAll(Arrays.asList(cmds));
  1844. }
  1845. return result;
  1846. }
  1847. /**
  1848. * Adjust args for size if necessary by creating an argument file, which should be deleted by the client after the compiler
  1849. * run has completed.
  1850. *
  1851. * @param max the int maximum length of the command line (in char)
  1852. * @return the temp File for the arguments (if generated), for deletion when done.
  1853. * @throws IllegalArgumentException if max is negative
  1854. */
  1855. static String[] limitTo(String[] args, int max, Location location) {
  1856. if (max < 0) {
  1857. throw new IllegalArgumentException("negative max: " + max);
  1858. }
  1859. // sigh - have to count anyway for now
  1860. int size = 0;
  1861. for (int i = 0; (i < args.length) && (size < max); i++) {
  1862. size += 1 + (null == args[i] ? 0 : args[i].length());
  1863. }
  1864. if (size <= max) {
  1865. return args;
  1866. }
  1867. File tmpFile = null;
  1868. PrintWriter out = null;
  1869. // adapted from DefaultCompilerAdapter.executeExternalCompile
  1870. try {
  1871. String userDirName = System.getProperty("user.dir");
  1872. File userDir = new File(userDirName);
  1873. tmpFile = File.createTempFile("argfile", "", userDir);
  1874. out = new PrintWriter(new FileWriter(tmpFile));
  1875. for (String arg : args) {
  1876. out.println(arg);
  1877. }
  1878. out.flush();
  1879. return new String[] { "-argfile", tmpFile.getAbsolutePath() };
  1880. } catch (IOException e) {
  1881. throw new BuildException("Error creating temporary file", e, location);
  1882. } finally {
  1883. if (out != null) {
  1884. try {
  1885. out.close();
  1886. } catch (Throwable t) {
  1887. }
  1888. }
  1889. }
  1890. }
  1891. }
  1892. private static class AntMessageHandler implements IMessageHandler {
  1893. private TaskLogger logger;
  1894. private final boolean taskLevelVerbose;
  1895. private final boolean handledMessage;
  1896. public AntMessageHandler(TaskLogger logger, boolean taskVerbose, boolean handledMessage) {
  1897. this.logger = logger;
  1898. this.taskLevelVerbose = taskVerbose;
  1899. this.handledMessage = handledMessage;
  1900. }
  1901. /*
  1902. * (non-Javadoc)
  1903. *
  1904. * @see org.aspectj.bridge.IMessageHandler#handleMessage(org.aspectj.bridge.IMessage)
  1905. */
  1906. @Override
  1907. public boolean handleMessage(IMessage message) throws AbortException {
  1908. Kind messageKind = message.getKind();
  1909. String messageText = message.toString();
  1910. if (messageKind == IMessage.ABORT) {
  1911. this.logger.error(messageText);
  1912. } else if (messageKind == IMessage.DEBUG) {
  1913. this.logger.debug(messageText);
  1914. } else if (messageKind == IMessage.ERROR) {
  1915. this.logger.error(messageText);
  1916. } else if (messageKind == IMessage.FAIL) {
  1917. this.logger.error(messageText);
  1918. } else if (messageKind == IMessage.INFO) {
  1919. if (this.taskLevelVerbose) {
  1920. this.logger.info(messageText);
  1921. } else {
  1922. this.logger.verbose(messageText);
  1923. }
  1924. } else if (messageKind == IMessage.WARNING) {
  1925. this.logger.warning(messageText);
  1926. } else if (messageKind == IMessage.WEAVEINFO) {
  1927. this.logger.info(messageText);
  1928. } else if (messageKind == IMessage.TASKTAG) {
  1929. // ignore
  1930. } else {
  1931. throw new BuildException("Unknown message kind from AspectJ compiler: " + messageKind.toString());
  1932. }
  1933. return handledMessage;
  1934. }
  1935. /*
  1936. * (non-Javadoc)
  1937. *
  1938. * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
  1939. */
  1940. @Override
  1941. public boolean isIgnoring(Kind kind) {
  1942. return false;
  1943. }
  1944. /*
  1945. * (non-Javadoc)
  1946. *
  1947. * @see org.aspectj.bridge.IMessageHandler#dontIgnore(org.aspectj.bridge.IMessage.Kind)
  1948. */
  1949. @Override
  1950. public void dontIgnore(Kind kind) {
  1951. }
  1952. /*
  1953. * (non-Javadoc)
  1954. *
  1955. * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind)
  1956. */
  1957. @Override
  1958. public void ignore(Kind kind) {
  1959. }
  1960. }
  1961. }