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

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