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.

пре 21 година
пре 20 година
пре 21 година
пре 18 година
пре 21 година
пре 18 година
пре 21 година
пре 20 година
пре 21 година
пре 18 година
пре 18 година
пре 18 година
пре 18 година
пре 21 година
пре 18 година
пре 21 година
пре 15 година
пре 15 година
пре 21 година
пре 15 година
пре 21 година
пре 15 година
пре 21 година
пре 15 година
пре 21 година
пре 15 година
пре 15 година
пре 21 година
пре 15 година
пре 21 година
пре 15 година
пре 15 година
пре 21 година
пре 15 година
пре 21 година
пре 15 година
пре 14 година
пре 15 година
пре 21 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
пре 21 година
пре 15 година
пре 21 година
пре 15 година
пре 21 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
пре 21 година
пре 15 година
пре 21 година
пре 15 година
пре 21 година
пре 15 година
пре 15 година
пре 21 година
пре 15 година
пре 14 година
пре 15 година
пре 15 година
пре 15 година
пре 20 година
пре 15 година
пре 20 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
пре 14 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
пре 15 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085
  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" };
  240. static final String[] SOURCE_INPUTS = new String[] { "1.3", "1.4", "1.5", "1.6" };
  241. static final String[] COMPLIANCE_INPUTS = new String[] { "-1.3", "-1.4", "-1.5", "-1.6" };
  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. public void setIncremental(boolean incremental) {
  414. cmd.addFlag("-incremental", incremental);
  415. inIncrementalMode = incremental;
  416. }
  417. public void setLogCommand(boolean logCommand) {
  418. this.logCommand = logCommand;
  419. }
  420. public void setHelp(boolean help) {
  421. cmd.addFlag("-help", help);
  422. }
  423. public void setVersion(boolean version) {
  424. cmd.addFlag("-version", version);
  425. }
  426. public void setXTerminateAfterCompilation(boolean b) {
  427. cmd.addFlag("-XterminateAfterCompilation", b);
  428. }
  429. public void setXReweavable(boolean reweavable) {
  430. cmd.addFlag("-Xreweavable", reweavable);
  431. }
  432. public void setXmlConfigured(boolean xmlConfigured) {
  433. cmd.addFlag("-xmlConfigured", xmlConfigured);
  434. }
  435. public void setXJoinpoints(String optionalJoinpoints) {
  436. cmd.addFlag("-Xjoinpoints:" + optionalJoinpoints, true);
  437. }
  438. public void setCheckRuntimeVersion(boolean b) {
  439. cmd.addFlag("-checkRuntimeVersion:" + b, true);
  440. }
  441. public void setXNoWeave(boolean b) {
  442. if (logger != null) {
  443. logger.warning("the noweave option is no longer required and is being ignored");
  444. }
  445. }
  446. public void setNoWeave(boolean b) {
  447. if (logger != null) {
  448. logger.warning("the noweave option is no longer required and is being ignored");
  449. }
  450. }
  451. public void setXNotReweavable(boolean notReweavable) {
  452. cmd.addFlag("-XnotReweavable", notReweavable);
  453. }
  454. public void setXaddSerialVersionUID(boolean addUID) {
  455. cmd.addFlag("-XaddSerialVersionUID", addUID);
  456. }
  457. public void setXNoInline(boolean noInline) {
  458. cmd.addFlag("-XnoInline", noInline);
  459. }
  460. public void setShowWeaveInfo(boolean showweaveinfo) {
  461. cmd.addFlag("-showWeaveInfo", showweaveinfo);
  462. }
  463. public void setNowarn(boolean nowarn) {
  464. cmd.addFlag("-nowarn", nowarn);
  465. }
  466. public void setDeprecation(boolean deprecation) {
  467. cmd.addFlag("-deprecation", deprecation);
  468. }
  469. public void setWarn(String warnings) {
  470. warnings = validCommaList(warnings, VALID_WARNINGS, "warn");
  471. cmd.addFlag("-warn:" + warnings, (null != warnings));
  472. }
  473. public void setDebug(boolean debug) {
  474. cmd.addFlag("-g", debug);
  475. }
  476. public void setDebugLevel(String level) {
  477. level = validCommaList(level, VALID_DEBUG, "g");
  478. cmd.addFlag("-g:" + level, (null != level));
  479. }
  480. public void setEmacssym(boolean emacssym) {
  481. cmd.addFlag("-emacssym", emacssym);
  482. }
  483. public void setCrossrefs(boolean on) {
  484. cmd.addFlag("-crossrefs", on);
  485. }
  486. /**
  487. * -Xlint - set default level of -Xlint messages to warning (same as </code>-Xlint:warning</code>)
  488. */
  489. public void setXlintwarnings(boolean xlintwarnings) {
  490. cmd.addFlag("-Xlint", xlintwarnings);
  491. }
  492. /**
  493. * -Xlint:{error|warning|info} - set default level for -Xlint messages
  494. *
  495. * @param xlint the String with one of error, warning, ignored
  496. */
  497. public void setXlint(String xlint) {
  498. xlint = validCommaList(xlint, VALID_XLINT, "Xlint", 1);
  499. cmd.addFlag("-Xlint:" + xlint, (null != xlint));
  500. }
  501. /**
  502. * -Xlintfile {lint.properties} - enable or disable specific forms of -Xlint messages based on a lint properties file (default
  503. * is <code>org/aspectj/weaver/XLintDefault.properties</code>)
  504. *
  505. * @param xlintFile the File with lint properties
  506. */
  507. public void setXlintfile(File xlintFile) {
  508. cmd.addFlagged("-Xlintfile", xlintFile.getAbsolutePath());
  509. }
  510. public void setPreserveAllLocals(boolean preserveAllLocals) {
  511. cmd.addFlag("-preserveAllLocals", preserveAllLocals);
  512. }
  513. public void setNoImportError(boolean noImportError) {
  514. cmd.addFlag("-warn:-unusedImport", noImportError);
  515. }
  516. public void setEncoding(String encoding) {
  517. cmd.addFlagged("-encoding", encoding);
  518. }
  519. public void setLog(File file) {
  520. cmd.addFlagged("-log", file.getAbsolutePath());
  521. }
  522. public void setProceedOnError(boolean proceedOnError) {
  523. cmd.addFlag("-proceedOnError", proceedOnError);
  524. }
  525. public void setVerbose(boolean verbose) {
  526. cmd.addFlag("-verbose", verbose);
  527. this.verbose = verbose;
  528. }
  529. public void setTimers(boolean timers) {
  530. cmd.addFlag("-timers", timers);
  531. this.timers = timers;
  532. }
  533. public void setListFileArgs(boolean listFileArgs) {
  534. this.listFileArgs = listFileArgs;
  535. }
  536. public void setReferenceInfo(boolean referenceInfo) {
  537. cmd.addFlag("-referenceInfo", referenceInfo);
  538. }
  539. public void setTime(boolean time) {
  540. cmd.addFlag("-time", time);
  541. }
  542. public void setNoExit(boolean noExit) {
  543. cmd.addFlag("-noExit", noExit);
  544. }
  545. public void setFailonerror(boolean failonerror) {
  546. this.failonerror = failonerror;
  547. }
  548. /**
  549. * @return true if fork was set
  550. */
  551. public boolean isForked() {
  552. return fork;
  553. }
  554. public void setFork(boolean fork) {
  555. this.fork = fork;
  556. }
  557. public void setMaxmem(String maxMem) {
  558. this.maxMem = maxMem;
  559. }
  560. /** support for nested &lt;jvmarg&gt; elements */
  561. public Commandline.Argument createJvmarg() {
  562. return this.javaCmd.createVmArgument();
  563. }
  564. // ----------------
  565. public void setTagFile(File file) {
  566. inIncrementalMode = true;
  567. cmd.addFlagged(Main.CommandController.TAG_FILE_OPTION, file.getAbsolutePath());
  568. inIncrementalFileMode = true;
  569. }
  570. public void setOutjar(File file) {
  571. if (DEFAULT_DESTDIR != destDir) {
  572. String e = "specifying both output jar (" + file + ") and destination dir (" + destDir + ")";
  573. throw new BuildException(e);
  574. }
  575. outjar = file;
  576. outjarFixedup = false;
  577. tmpOutjar = null;
  578. }
  579. public void setOutxml(boolean outxml) {
  580. cmd.addFlag("-outxml", outxml);
  581. }
  582. public void setOutxmlfile(String name) {
  583. cmd.addFlagged("-outxmlfile", name);
  584. }
  585. public void setDestdir(File dir) {
  586. if (null != outjar) {
  587. String e = "specifying both output jar (" + outjar + ") and destination dir (" + dir + ")";
  588. throw new BuildException(e);
  589. }
  590. cmd.addFlagged("-d", dir.getAbsolutePath());
  591. destDir = dir;
  592. }
  593. /**
  594. * @param input a String in TARGET_INPUTS
  595. */
  596. public void setTarget(String input) {
  597. String ignore = cmd.addOption("-target", TARGET_INPUTS, input);
  598. if (null != ignore) {
  599. ignore(ignore);
  600. }
  601. }
  602. /**
  603. * Language compliance level. If not set explicitly, eclipse default holds.
  604. *
  605. * @param input a String in COMPLIANCE_INPUTS
  606. */
  607. public void setCompliance(String input) {
  608. String ignore = cmd.addOption(null, COMPLIANCE_INPUTS, input);
  609. if (null != ignore) {
  610. ignore(ignore);
  611. }
  612. }
  613. /**
  614. * Source compliance level. If not set explicitly, eclipse default holds.
  615. *
  616. * @param input a String in SOURCE_INPUTS
  617. */
  618. public void setSource(String input) {
  619. String ignore = cmd.addOption("-source", SOURCE_INPUTS, input);
  620. if (null != ignore) {
  621. ignore(ignore);
  622. }
  623. }
  624. /**
  625. * Flag to copy all non-.class contents of injars to outjar after compile completes. Requires both injars and outjar.
  626. *
  627. * @param doCopy
  628. */
  629. public void setCopyInjars(boolean doCopy) {
  630. ignore("copyInJars");
  631. log("copyInjars not required since 1.1.1.\n", Project.MSG_WARN);
  632. // this.copyInjars = doCopy;
  633. }
  634. /**
  635. * Option to copy all files from all source root directories except those specified here. If this is specified and sourceroots
  636. * are specified, then this will copy all files except those specified in the filter pattern. Requires sourceroots.
  637. *
  638. * @param filter a String acceptable as an excludes filter for an Ant Zip fileset.
  639. */
  640. public void setSourceRootCopyFilter(String filter) {
  641. this.sourceRootCopyFilter = filter;
  642. }
  643. /**
  644. * Option to copy all files from all inpath directories except the files specified here. If this is specified and inpath
  645. * directories are specified, then this will copy all files except those specified in the filter pattern. Requires inpath. If
  646. * the input does not contain "**\/*.class", then this prepends it, to avoid overwriting woven classes with unwoven input.
  647. *
  648. * @param filter a String acceptable as an excludes filter for an Ant Zip fileset.
  649. */
  650. public void setInpathDirCopyFilter(String filter) {
  651. if (null != filter) {
  652. if (-1 == filter.indexOf("**/*.class")) {
  653. filter = "**/*.class," + filter;
  654. }
  655. }
  656. this.inpathDirCopyFilter = filter;
  657. }
  658. public void setX(String input) { // ajc-only eajc-also docDone
  659. StringTokenizer tokens = new StringTokenizer(input, ",", false);
  660. while (tokens.hasMoreTokens()) {
  661. String token = tokens.nextToken().trim();
  662. if (1 < token.length()) {
  663. // new special case: allow -Xset:anything
  664. if (VALID_XOPTIONS.contains(token) || token.indexOf("set:") == 0 || token.indexOf("joinpoints:") == 0) {
  665. cmd.addFlag("-X" + token, true);
  666. } else {
  667. ignore("-X" + token);
  668. }
  669. }
  670. }
  671. }
  672. public void setXDoneSignal(String doneSignal) {
  673. this.xdoneSignal = doneSignal;
  674. }
  675. /** direct API for testing */
  676. public void setMessageHolder(IMessageHolder holder) {
  677. this.messageHolder = holder;
  678. }
  679. /**
  680. * Setup custom message handling.
  681. *
  682. * @param className the String fully-qualified-name of a class reachable from this object's class loader, implementing
  683. * IMessageHolder, and having a public no-argument constructor.
  684. * @throws BuildException if unable to create instance of className
  685. */
  686. public void setMessageHolderClass(String className) {
  687. try {
  688. Class mclass = Class.forName(className);
  689. IMessageHolder holder = (IMessageHolder) mclass.newInstance();
  690. setMessageHolder(holder);
  691. } catch (Throwable t) {
  692. String m = "unable to instantiate message holder: " + className;
  693. throw new BuildException(m, t);
  694. }
  695. }
  696. /** direct API for testing */
  697. public void setCommandEditor(ICommandEditor editor) {
  698. this.commandEditor = editor;
  699. }
  700. /**
  701. * Setup command-line filter. To do this staticly, define the environment variable
  702. * <code>org.aspectj.tools.ant.taskdefs.AjcTask.COMMAND_EDITOR</code> with the <code>className</code> parameter.
  703. *
  704. * @param className the String fully-qualified-name of a class reachable from this object's class loader, implementing
  705. * ICommandEditor, and having a public no-argument constructor.
  706. * @throws BuildException if unable to create instance of className
  707. */
  708. public void setCommandEditorClass(String className) { // skip Ant interface?
  709. try {
  710. Class mclass = Class.forName(className);
  711. setCommandEditor((ICommandEditor) mclass.newInstance());
  712. } catch (Throwable t) {
  713. String m = "unable to instantiate command editor: " + className;
  714. throw new BuildException(m, t);
  715. }
  716. }
  717. // ---------------------- Path lists
  718. /**
  719. * Add path elements to source path and return result. Elements are added even if they do not exist.
  720. *
  721. * @param source the Path to add to - may be null
  722. * @param toAdd the Path to add - may be null
  723. * @return the (never-null) Path that results
  724. */
  725. protected Path incPath(Path source, Path toAdd) {
  726. if (null == source) {
  727. source = new Path(project);
  728. }
  729. if (null != toAdd) {
  730. source.append(toAdd);
  731. }
  732. return source;
  733. }
  734. public void setSourcerootsref(Reference ref) {
  735. createSourceRoots().setRefid(ref);
  736. }
  737. public void setSourceRoots(Path roots) {
  738. sourceRoots = incPath(sourceRoots, roots);
  739. }
  740. public Path createSourceRoots() {
  741. if (sourceRoots == null) {
  742. sourceRoots = new Path(project);
  743. }
  744. return sourceRoots.createPath();
  745. }
  746. public void setXWeaveDir(File file) {
  747. if ((null != file) && file.isDirectory() && file.canRead()) {
  748. xweaveDir = file;
  749. }
  750. }
  751. public void setInjarsref(Reference ref) {
  752. createInjars().setRefid(ref);
  753. }
  754. public void setInpathref(Reference ref) {
  755. createInpath().setRefid(ref);
  756. }
  757. public void setInjars(Path path) {
  758. injars = incPath(injars, path);
  759. }
  760. public void setInpath(Path path) {
  761. inpath = incPath(inpath, path);
  762. }
  763. public Path createInjars() {
  764. if (injars == null) {
  765. injars = new Path(project);
  766. }
  767. return injars.createPath();
  768. }
  769. public Path createInpath() {
  770. if (inpath == null) {
  771. inpath = new Path(project);
  772. }
  773. return inpath.createPath();
  774. }
  775. public void setClasspath(Path path) {
  776. classpath = incPath(classpath, path);
  777. }
  778. public void setClasspathref(Reference classpathref) {
  779. createClasspath().setRefid(classpathref);
  780. }
  781. public Path createClasspath() {
  782. if (classpath == null) {
  783. classpath = new Path(project);
  784. }
  785. return classpath.createPath();
  786. }
  787. public void setBootclasspath(Path path) {
  788. bootclasspath = incPath(bootclasspath, path);
  789. }
  790. public void setBootclasspathref(Reference bootclasspathref) {
  791. createBootclasspath().setRefid(bootclasspathref);
  792. }
  793. public Path createBootclasspath() {
  794. if (bootclasspath == null) {
  795. bootclasspath = new Path(project);
  796. }
  797. return bootclasspath.createPath();
  798. }
  799. public void setForkclasspath(Path path) {
  800. forkclasspath = incPath(forkclasspath, path);
  801. }
  802. public void setForkclasspathref(Reference forkclasspathref) {
  803. createForkclasspath().setRefid(forkclasspathref);
  804. }
  805. public Path createForkclasspath() {
  806. if (forkclasspath == null) {
  807. forkclasspath = new Path(project);
  808. }
  809. return forkclasspath.createPath();
  810. }
  811. public void setExtdirs(Path path) {
  812. extdirs = incPath(extdirs, path);
  813. }
  814. public void setExtdirsref(Reference ref) {
  815. createExtdirs().setRefid(ref);
  816. }
  817. public Path createExtdirs() {
  818. if (extdirs == null) {
  819. extdirs = new Path(project);
  820. }
  821. return extdirs.createPath();
  822. }
  823. public void setAspectpathref(Reference ref) {
  824. createAspectpath().setRefid(ref);
  825. }
  826. public void setAspectpath(Path path) {
  827. aspectpath = incPath(aspectpath, path);
  828. }
  829. public Path createAspectpath() {
  830. if (aspectpath == null) {
  831. aspectpath = new Path(project);
  832. }
  833. return aspectpath.createPath();
  834. }
  835. public void setSrcDir(Path path) {
  836. srcdir = incPath(srcdir, path);
  837. }
  838. public Path createSrc() {
  839. return createSrcdir();
  840. }
  841. public Path createSrcdir() {
  842. if (srcdir == null) {
  843. srcdir = new Path(project);
  844. }
  845. return srcdir.createPath();
  846. }
  847. /** @return true if in incremental mode (command-line or file) */
  848. public boolean isInIncrementalMode() {
  849. return inIncrementalMode;
  850. }
  851. /** @return true if in incremental file mode */
  852. public boolean isInIncrementalFileMode() {
  853. return inIncrementalFileMode;
  854. }
  855. public void setArgfilesref(Reference ref) {
  856. createArgfiles().setRefid(ref);
  857. }
  858. public void setArgfiles(Path path) { // ajc-only eajc-also docDone
  859. argfiles = incPath(argfiles, path);
  860. }
  861. public Path createArgfiles() {
  862. if (argfiles == null) {
  863. argfiles = new Path(project);
  864. }
  865. return argfiles.createPath();
  866. }
  867. public void setInxmlref(Reference ref) {
  868. createArgfiles().setRefid(ref);
  869. }
  870. public void setInxml(Path path) { // ajc-only eajc-also docDone
  871. inxmlfiles = incPath(inxmlfiles, path);
  872. }
  873. public Path createInxml() {
  874. if (inxmlfiles == null) {
  875. inxmlfiles = new Path(project);
  876. }
  877. return inxmlfiles.createPath();
  878. }
  879. // ------------------------------ run
  880. /**
  881. * Compile using ajc per settings.
  882. *
  883. * @exception BuildException if the compilation has problems or if there were compiler errors and failonerror is true.
  884. */
  885. public void execute() throws BuildException {
  886. this.logger = new TaskLogger(this);
  887. if (executing) {
  888. throw new IllegalStateException("already executing");
  889. } else {
  890. executing = true;
  891. }
  892. setupOptions();
  893. verifyOptions();
  894. try {
  895. String[] args = makeCommand();
  896. if (logCommand) {
  897. log("ajc " + Arrays.asList(args));
  898. } else {
  899. logVerbose("ajc " + Arrays.asList(args));
  900. }
  901. if (!fork) {
  902. executeInSameVM(args);
  903. } else { // when forking, Adapter handles failonerror
  904. executeInOtherVM(args);
  905. }
  906. } catch (BuildException e) {
  907. throw e;
  908. } catch (Throwable x) {
  909. this.logger.error(Main.renderExceptionForUser(x));
  910. throw new BuildException("IGNORE -- See " + LangUtil.unqualifiedClassName(x) + " rendered to ant logger");
  911. } finally {
  912. executing = false;
  913. if (null != tmpOutjar) {
  914. tmpOutjar.delete();
  915. }
  916. }
  917. }
  918. /**
  919. * Halt processing. This tells main in the same vm to quit. It fails when running in forked mode.
  920. *
  921. * @return true if not in forked mode and main has quit or been told to quit
  922. */
  923. public boolean quit() {
  924. if (executingInOtherVM) {
  925. return false;
  926. }
  927. Main me = main;
  928. if (null != me) {
  929. me.quit();
  930. }
  931. return true;
  932. }
  933. // package-private for testing
  934. String[] makeCommand() {
  935. ArrayList result = new ArrayList();
  936. if (0 < ignored.size()) {
  937. for (Iterator iter = ignored.iterator(); iter.hasNext();) {
  938. logVerbose("ignored: " + iter.next());
  939. }
  940. }
  941. // when copying resources, use temp jar for class output
  942. // then copy temp jar contents and resources to output jar
  943. if ((null != outjar) && !outjarFixedup) {
  944. if (copyInjars || copyInpath || (null != sourceRootCopyFilter) || (null != inpathDirCopyFilter)) {
  945. String path = outjar.getAbsolutePath();
  946. int len = FileUtil.zipSuffixLength(path);
  947. path = path.substring(0, path.length() - len) + ".tmp.jar";
  948. tmpOutjar = new File(path);
  949. }
  950. if (null == tmpOutjar) {
  951. cmd.addFlagged("-outjar", outjar.getAbsolutePath());
  952. } else {
  953. cmd.addFlagged("-outjar", tmpOutjar.getAbsolutePath());
  954. }
  955. outjarFixedup = true;
  956. }
  957. result.addAll(cmd.extractArguments());
  958. addListArgs(result);
  959. String[] command = (String[]) result.toArray(new String[0]);
  960. if (null != commandEditor) {
  961. command = commandEditor.editCommand(command);
  962. } else if (null != COMMAND_EDITOR) {
  963. command = COMMAND_EDITOR.editCommand(command);
  964. }
  965. return command;
  966. }
  967. /**
  968. * Create any pseudo-options required to implement some of the macro options
  969. *
  970. * @throws BuildException if options conflict
  971. */
  972. protected void setupOptions() {
  973. if (null != xweaveDir) {
  974. if (DEFAULT_DESTDIR != destDir) {
  975. throw new BuildException("weaveDir forces destdir");
  976. }
  977. if (null != outjar) {
  978. throw new BuildException("weaveDir forces outjar");
  979. }
  980. if (null != injars) {
  981. throw new BuildException("weaveDir incompatible with injars now");
  982. }
  983. if (null != inpath) {
  984. throw new BuildException("weaveDir incompatible with inpath now");
  985. }
  986. File injar = zipDirectory(xweaveDir);
  987. setInjars(new Path(getProject(), injar.getAbsolutePath()));
  988. setDestdir(xweaveDir);
  989. }
  990. }
  991. protected File zipDirectory(File dir) {
  992. File tempDir = new File(".");
  993. try {
  994. tempDir = File.createTempFile("AjcTest", ".tmp");
  995. tempDir.mkdirs();
  996. tempDir.deleteOnExit(); // XXX remove zip explicitly..
  997. } catch (IOException e) {
  998. // ignore
  999. }
  1000. // File result = new File(tempDir,
  1001. String filename = "AjcTask-" + System.currentTimeMillis() + ".zip";
  1002. File result = new File(filename);
  1003. Zip zip = new Zip();
  1004. zip.setProject(getProject());
  1005. zip.setDestFile(result);
  1006. zip.setTaskName(getTaskName() + " - zip");
  1007. FileSet fileset = new FileSet();
  1008. fileset.setDir(dir);
  1009. zip.addFileset(fileset);
  1010. zip.execute();
  1011. Delete delete = new Delete();
  1012. delete.setProject(getProject());
  1013. delete.setTaskName(getTaskName() + " - delete");
  1014. delete.setDir(dir);
  1015. delete.execute();
  1016. Mkdir mkdir = new Mkdir();
  1017. mkdir.setProject(getProject());
  1018. mkdir.setTaskName(getTaskName() + " - mkdir");
  1019. mkdir.setDir(dir);
  1020. mkdir.execute();
  1021. return result;
  1022. }
  1023. /**
  1024. * @throw BuildException if options conflict
  1025. */
  1026. protected void verifyOptions() {
  1027. StringBuffer sb = new StringBuffer();
  1028. if (fork && isInIncrementalMode() && !isInIncrementalFileMode()) {
  1029. sb.append("can fork incremental only using tag file.\n");
  1030. }
  1031. if (((null != inpathDirCopyFilter) || (null != sourceRootCopyFilter)) && (null == outjar) && (DEFAULT_DESTDIR == destDir)) {
  1032. final String REQ = " requires dest dir or output jar.\n";
  1033. if (null == inpathDirCopyFilter) {
  1034. sb.append("sourceRootCopyFilter");
  1035. } else if (null == sourceRootCopyFilter) {
  1036. sb.append("inpathDirCopyFilter");
  1037. } else {
  1038. sb.append("sourceRootCopyFilter and inpathDirCopyFilter");
  1039. }
  1040. sb.append(REQ);
  1041. }
  1042. if (0 < sb.length()) {
  1043. throw new BuildException(sb.toString());
  1044. }
  1045. }
  1046. /**
  1047. * Run the compile in the same VM by loading the compiler (Main), setting up any message holders, doing the compile, and
  1048. * converting abort/failure and error messages to BuildException, as appropriate.
  1049. *
  1050. * @throws BuildException if abort or failure messages or if errors and failonerror.
  1051. *
  1052. */
  1053. protected void executeInSameVM(String[] args) {
  1054. if (null != maxMem) {
  1055. log("maxMem ignored unless forked: " + maxMem, Project.MSG_WARN);
  1056. }
  1057. IMessageHolder holder = messageHolder;
  1058. int numPreviousErrors;
  1059. if (null == holder) {
  1060. MessageHandler mhandler = new MessageHandler(true);
  1061. final IMessageHandler delegate;
  1062. delegate = new AntMessageHandler(this.logger, this.verbose, false);
  1063. mhandler.setInterceptor(delegate);
  1064. holder = mhandler;
  1065. numPreviousErrors = 0;
  1066. } else {
  1067. numPreviousErrors = holder.numMessages(IMessage.ERROR, true);
  1068. }
  1069. {
  1070. Main newmain = new Main();
  1071. newmain.setHolder(holder);
  1072. newmain.setCompletionRunner(new Runnable() {
  1073. public void run() {
  1074. doCompletionTasks();
  1075. }
  1076. });
  1077. if (null != main) {
  1078. MessageUtil.fail(holder, "still running prior main");
  1079. return;
  1080. }
  1081. main = newmain;
  1082. }
  1083. main.runMain(args, false);
  1084. if (failonerror) {
  1085. int errs = holder.numMessages(IMessage.ERROR, false);
  1086. errs -= numPreviousErrors;
  1087. if (0 < errs) {
  1088. String m = errs + " errors";
  1089. MessageUtil.print(System.err, holder, "", MessageUtil.MESSAGE_ALL, MessageUtil.PICK_ERROR, true);
  1090. throw new BuildException(m);
  1091. }
  1092. }
  1093. // Throw BuildException if there are any fail or abort
  1094. // messages.
  1095. // The BuildException message text has a list of class names
  1096. // for the exceptions found in the messages, or the
  1097. // number of fail/abort messages found if there were
  1098. // no exceptions for any of the fail/abort messages.
  1099. // The interceptor message handler should have already
  1100. // printed the messages, including any stack traces.
  1101. // HACK: this ignores the Usage message
  1102. {
  1103. IMessage[] fails = holder.getMessages(IMessage.FAIL, true);
  1104. if (!LangUtil.isEmpty(fails)) {
  1105. StringBuffer sb = new StringBuffer();
  1106. String prefix = "fail due to ";
  1107. int numThrown = 0;
  1108. for (int i = 0; i < fails.length; i++) {
  1109. String message = fails[i].getMessage();
  1110. if (LangUtil.isEmpty(message)) {
  1111. message = "<no message>";
  1112. } else if (-1 != message.indexOf(USAGE_SUBSTRING)) {
  1113. continue;
  1114. }
  1115. Throwable t = fails[i].getThrown();
  1116. if (null != t) {
  1117. numThrown++;
  1118. sb.append(prefix);
  1119. sb.append(LangUtil.unqualifiedClassName(t.getClass()));
  1120. String thrownMessage = t.getMessage();
  1121. if (!LangUtil.isEmpty(thrownMessage)) {
  1122. sb.append(" \"" + thrownMessage + "\"");
  1123. }
  1124. }
  1125. sb.append("\"" + message + "\"");
  1126. prefix = ", ";
  1127. }
  1128. if (0 < sb.length()) {
  1129. sb.append(" (" + numThrown + " exceptions)");
  1130. throw new BuildException(sb.toString());
  1131. }
  1132. }
  1133. }
  1134. }
  1135. /**
  1136. * Execute in a separate VM. Differences from normal same-VM execution:
  1137. * <ul>
  1138. * <li>ignores any message holder {class} set</li>
  1139. * <li>No resource-copying between interative runs</li>
  1140. * <li>failonerror fails when process interface fails to return negative values</li>
  1141. * </ul>
  1142. *
  1143. * @param args String[] of the complete compiler command to execute
  1144. *
  1145. * @see DefaultCompilerAdapter#executeExternalCompile(String[], int)
  1146. * @throws BuildException if ajc aborts (negative value) or if failonerror and there were compile errors.
  1147. */
  1148. protected void executeInOtherVM(String[] args) {
  1149. javaCmd.setClassname(org.aspectj.tools.ajc.Main.class.getName());
  1150. final Path vmClasspath = javaCmd.createClasspath(getProject());
  1151. {
  1152. File aspectjtools = null;
  1153. int vmClasspathSize = vmClasspath.size();
  1154. if ((null != forkclasspath) && (0 != forkclasspath.size())) {
  1155. vmClasspath.addExisting(forkclasspath);
  1156. } else {
  1157. aspectjtools = findAspectjtoolsJar();
  1158. if (null != aspectjtools) {
  1159. vmClasspath.createPathElement().setLocation(aspectjtools);
  1160. }
  1161. }
  1162. int newVmClasspathSize = vmClasspath.size();
  1163. if (vmClasspathSize == newVmClasspathSize) {
  1164. String m = "unable to find aspectjtools to fork - ";
  1165. if (null != aspectjtools) {
  1166. m += "tried " + aspectjtools.toString();
  1167. } else if (null != forkclasspath) {
  1168. m += "tried " + forkclasspath.toString();
  1169. } else {
  1170. m += "define forkclasspath or put aspectjtools on classpath";
  1171. }
  1172. throw new BuildException(m);
  1173. }
  1174. }
  1175. if (null != maxMem) {
  1176. javaCmd.setMaxmemory(maxMem);
  1177. }
  1178. File tempFile = null;
  1179. int numArgs = args.length;
  1180. args = GuardedCommand.limitTo(args, MAX_COMMANDLINE, getLocation());
  1181. if (args.length != numArgs) {
  1182. tempFile = new File(args[1]);
  1183. }
  1184. try {
  1185. boolean setMessageHolderOnForking = (this.messageHolder != null);
  1186. String[] javaArgs = javaCmd.getCommandline();
  1187. String[] both = new String[javaArgs.length + args.length + (setMessageHolderOnForking ? 2 : 0)];
  1188. System.arraycopy(javaArgs, 0, both, 0, javaArgs.length);
  1189. System.arraycopy(args, 0, both, javaArgs.length, args.length);
  1190. if (setMessageHolderOnForking) {
  1191. both[both.length - 2] = "-messageHolder";
  1192. both[both.length - 1] = this.messageHolder.getClass().getName();
  1193. }
  1194. // try to use javaw instead on windows
  1195. if (both[0].endsWith("java.exe")) {
  1196. String path = both[0];
  1197. path = path.substring(0, path.length() - 4);
  1198. path = path + "w.exe";
  1199. File javaw = new File(path);
  1200. if (javaw.canRead() && javaw.isFile()) {
  1201. both[0] = path;
  1202. }
  1203. }
  1204. logVerbose("forking " + Arrays.asList(both));
  1205. int result = execInOtherVM(both);
  1206. if (0 > result) {
  1207. throw new BuildException("failure[" + result + "] running ajc");
  1208. } else if (failonerror && (0 < result)) {
  1209. throw new BuildException("compile errors: " + result);
  1210. }
  1211. // when forking, do completion only at end and when successful
  1212. doCompletionTasks();
  1213. } finally {
  1214. if (null != tempFile) {
  1215. tempFile.delete();
  1216. }
  1217. }
  1218. }
  1219. /**
  1220. * Execute in another process using the same JDK and the base directory of the project. XXX correct?
  1221. *
  1222. * @param args
  1223. * @return
  1224. */
  1225. protected int execInOtherVM(String[] args) {
  1226. try {
  1227. Project project = getProject();
  1228. PumpStreamHandler handler = new LogStreamHandler(this, verbose ? Project.MSG_VERBOSE : Project.MSG_INFO,
  1229. Project.MSG_WARN);
  1230. // replace above two lines with what follows as an aid to debugging when running the unit tests....
  1231. // LogStreamHandler handler = new LogStreamHandler(this,
  1232. // Project.MSG_INFO, Project.MSG_WARN) {
  1233. //
  1234. // ByteArrayOutputStream baos = new ByteArrayOutputStream();
  1235. // /* (non-Javadoc)
  1236. // * @see org.apache.tools.ant.taskdefs.PumpStreamHandler#createProcessOutputPump(java.io.InputStream,
  1237. // java.io.OutputStream)
  1238. // */
  1239. // protected void createProcessErrorPump(InputStream is,
  1240. // OutputStream os) {
  1241. // super.createProcessErrorPump(is, baos);
  1242. // }
  1243. //
  1244. // /* (non-Javadoc)
  1245. // * @see org.apache.tools.ant.taskdefs.LogStreamHandler#stop()
  1246. // */
  1247. // public void stop() {
  1248. // byte[] written = baos.toByteArray();
  1249. // System.err.print(new String(written));
  1250. // super.stop();
  1251. // }
  1252. // };
  1253. Execute exe = new Execute(handler);
  1254. exe.setAntRun(project);
  1255. exe.setWorkingDirectory(project.getBaseDir());
  1256. exe.setCommandline(args);
  1257. try {
  1258. if (executingInOtherVM) {
  1259. String s = "already running in other vm?";
  1260. throw new BuildException(s, location);
  1261. }
  1262. executingInOtherVM = true;
  1263. exe.execute();
  1264. } finally {
  1265. executingInOtherVM = false;
  1266. }
  1267. return exe.getExitValue();
  1268. } catch (IOException e) {
  1269. String m = "Error executing command " + Arrays.asList(args);
  1270. throw new BuildException(m, e, location);
  1271. }
  1272. }
  1273. // ------------------------------ setup and reporting
  1274. /** @return null if path null or empty, String rendition otherwise */
  1275. protected static void addFlaggedPath(String flag, Path path, List list) {
  1276. if (!LangUtil.isEmpty(flag) && ((null != path) && (0 < path.size()))) {
  1277. list.add(flag);
  1278. list.add(path.toString());
  1279. }
  1280. }
  1281. /**
  1282. * Add to list any path or plural arguments.
  1283. */
  1284. protected void addListArgs(List list) throws BuildException {
  1285. addFlaggedPath("-classpath", classpath, list);
  1286. addFlaggedPath("-bootclasspath", bootclasspath, list);
  1287. addFlaggedPath("-extdirs", extdirs, list);
  1288. addFlaggedPath("-aspectpath", aspectpath, list);
  1289. addFlaggedPath("-injars", injars, list);
  1290. addFlaggedPath("-inpath", inpath, list);
  1291. addFlaggedPath("-sourceroots", sourceRoots, list);
  1292. if (argfiles != null) {
  1293. String[] files = argfiles.list();
  1294. for (int i = 0; i < files.length; i++) {
  1295. File argfile = project.resolveFile(files[i]);
  1296. if (check(argfile, files[i], false, location)) {
  1297. list.add("-argfile");
  1298. list.add(argfile.getAbsolutePath());
  1299. }
  1300. }
  1301. }
  1302. if (inxmlfiles != null) {
  1303. String[] files = inxmlfiles.list();
  1304. for (int i = 0; i < files.length; i++) {
  1305. File inxmlfile = project.resolveFile(files[i]);
  1306. if (check(inxmlfile, files[i], false, location)) {
  1307. list.add("-xmlConfigured");
  1308. list.add(inxmlfile.getAbsolutePath());
  1309. }
  1310. }
  1311. }
  1312. if (srcdir != null) {
  1313. // todo: ignore any srcdir if any argfiles and no explicit includes
  1314. String[] dirs = srcdir.list();
  1315. for (int i = 0; i < dirs.length; i++) {
  1316. File dir = project.resolveFile(dirs[i]);
  1317. check(dir, dirs[i], true, location);
  1318. // relies on compiler to prune non-source files
  1319. String[] files = getDirectoryScanner(dir).getIncludedFiles();
  1320. for (int j = 0; j < files.length; j++) {
  1321. File file = new File(dir, files[j]);
  1322. if (FileUtil.hasSourceSuffix(file)) {
  1323. if (!list.contains(file.getAbsolutePath())) {
  1324. list.add(file.getAbsolutePath());
  1325. }
  1326. }
  1327. }
  1328. }
  1329. }
  1330. if (0 < adapterFiles.size()) {
  1331. for (Iterator iter = adapterFiles.iterator(); iter.hasNext();) {
  1332. File file = (File) iter.next();
  1333. if (file.canRead() && FileUtil.hasSourceSuffix(file)) {
  1334. list.add(file.getAbsolutePath());
  1335. } else {
  1336. this.logger.warning("skipping file: " + file);
  1337. }
  1338. }
  1339. }
  1340. }
  1341. /**
  1342. * Throw BuildException unless file is valid.
  1343. *
  1344. * @param file the File to check
  1345. * @param name the symbolic name to print on error
  1346. * @param isDir if true, verify file is a directory
  1347. * @param loc the Location used to create sensible BuildException
  1348. * @return
  1349. * @throws BuildException unless file valid
  1350. */
  1351. protected final boolean check(File file, String name, boolean isDir, Location loc) {
  1352. loc = loc != null ? loc : location;
  1353. if (file == null) {
  1354. throw new BuildException(name + " is null!", loc);
  1355. }
  1356. if (!file.exists()) {
  1357. throw new BuildException(file + " doesn't exist!", loc);
  1358. }
  1359. if (isDir ^ file.isDirectory()) {
  1360. String e = file + " should" + (isDir ? "" : "n't") + " be a directory!";
  1361. throw new BuildException(e, loc);
  1362. }
  1363. return true;
  1364. }
  1365. /**
  1366. * Called when compile or incremental compile is completing, this completes the output jar or directory by copying resources if
  1367. * requested. Note: this is a callback run synchronously by the compiler. That means exceptions thrown here are caught by
  1368. * Main.run(..) and passed to the message handler.
  1369. */
  1370. protected void doCompletionTasks() {
  1371. if (!executing) {
  1372. throw new IllegalStateException("should be executing");
  1373. }
  1374. if (null != outjar) {
  1375. completeOutjar();
  1376. } else {
  1377. completeDestdir();
  1378. }
  1379. if (null != xdoneSignal) {
  1380. MessageUtil.info(messageHolder, xdoneSignal);
  1381. }
  1382. }
  1383. /**
  1384. * Complete the destination directory by copying resources from the source root directories (if the filter is specified) and
  1385. * non-.class files from the input jars (if XCopyInjars is enabled).
  1386. */
  1387. private void completeDestdir() {
  1388. if (!copyInjars && (null == sourceRootCopyFilter) && (null == inpathDirCopyFilter)) {
  1389. return;
  1390. } else if ((destDir == DEFAULT_DESTDIR) || !destDir.canWrite()) {
  1391. String s = "unable to copy resources to destDir: " + destDir;
  1392. throw new BuildException(s);
  1393. }
  1394. final Project project = getProject();
  1395. if (copyInjars) { // XXXX remove as unused since 1.1.1
  1396. if (null != inpath) {
  1397. log("copyInjars does not support inpath.\n", Project.MSG_WARN);
  1398. }
  1399. String taskName = getTaskName() + " - unzip";
  1400. String[] paths = injars.list();
  1401. if (!LangUtil.isEmpty(paths)) {
  1402. PatternSet patternSet = new PatternSet();
  1403. patternSet.setProject(project);
  1404. patternSet.setIncludes("**/*");
  1405. patternSet.setExcludes("**/*.class");
  1406. for (int i = 0; i < paths.length; i++) {
  1407. Expand unzip = new Expand();
  1408. unzip.setProject(project);
  1409. unzip.setTaskName(taskName);
  1410. unzip.setDest(destDir);
  1411. unzip.setSrc(new File(paths[i]));
  1412. unzip.addPatternset(patternSet);
  1413. unzip.execute();
  1414. }
  1415. }
  1416. }
  1417. if ((null != sourceRootCopyFilter) && (null != sourceRoots)) {
  1418. String[] paths = sourceRoots.list();
  1419. if (!LangUtil.isEmpty(paths)) {
  1420. Copy copy = new Copy();
  1421. copy.setProject(project);
  1422. copy.setTodir(destDir);
  1423. for (int i = 0; i < paths.length; i++) {
  1424. FileSet fileSet = new FileSet();
  1425. fileSet.setDir(new File(paths[i]));
  1426. fileSet.setIncludes("**/*");
  1427. fileSet.setExcludes(sourceRootCopyFilter);
  1428. copy.addFileset(fileSet);
  1429. }
  1430. copy.execute();
  1431. }
  1432. }
  1433. if ((null != inpathDirCopyFilter) && (null != inpath)) {
  1434. String[] paths = inpath.list();
  1435. if (!LangUtil.isEmpty(paths)) {
  1436. Copy copy = new Copy();
  1437. copy.setProject(project);
  1438. copy.setTodir(destDir);
  1439. boolean gotDir = false;
  1440. for (int i = 0; i < paths.length; i++) {
  1441. File inpathDir = new File(paths[i]);
  1442. if (inpathDir.isDirectory() && inpathDir.canRead()) {
  1443. if (!gotDir) {
  1444. gotDir = true;
  1445. }
  1446. FileSet fileSet = new FileSet();
  1447. fileSet.setDir(inpathDir);
  1448. fileSet.setIncludes("**/*");
  1449. fileSet.setExcludes(inpathDirCopyFilter);
  1450. copy.addFileset(fileSet);
  1451. }
  1452. }
  1453. if (gotDir) {
  1454. copy.execute();
  1455. }
  1456. }
  1457. }
  1458. }
  1459. /**
  1460. * Complete the output jar by copying resources from the source root directories if the filter is specified. and non-.class
  1461. * files from the input jars if enabled.
  1462. */
  1463. private void completeOutjar() {
  1464. if (((null == tmpOutjar) || !tmpOutjar.canRead())
  1465. || (!copyInjars && (null == sourceRootCopyFilter) && (null == inpathDirCopyFilter))) {
  1466. return;
  1467. }
  1468. Zip zip = new Zip();
  1469. Project project = getProject();
  1470. zip.setProject(project);
  1471. zip.setTaskName(getTaskName() + " - zip");
  1472. zip.setDestFile(outjar);
  1473. ZipFileSet zipfileset = new ZipFileSet();
  1474. zipfileset.setProject(project);
  1475. zipfileset.setSrc(tmpOutjar);
  1476. zipfileset.setIncludes("**/*.class");
  1477. zip.addZipfileset(zipfileset);
  1478. if (copyInjars) {
  1479. String[] paths = injars.list();
  1480. if (!LangUtil.isEmpty(paths)) {
  1481. for (int i = 0; i < paths.length; i++) {
  1482. File jarFile = new File(paths[i]);
  1483. zipfileset = new ZipFileSet();
  1484. zipfileset.setProject(project);
  1485. zipfileset.setSrc(jarFile);
  1486. zipfileset.setIncludes("**/*");
  1487. zipfileset.setExcludes("**/*.class");
  1488. zip.addZipfileset(zipfileset);
  1489. }
  1490. }
  1491. }
  1492. if ((null != sourceRootCopyFilter) && (null != sourceRoots)) {
  1493. String[] paths = sourceRoots.list();
  1494. if (!LangUtil.isEmpty(paths)) {
  1495. for (int i = 0; i < paths.length; i++) {
  1496. File srcRoot = new File(paths[i]);
  1497. FileSet fileset = new FileSet();
  1498. fileset.setProject(project);
  1499. fileset.setDir(srcRoot);
  1500. fileset.setIncludes("**/*");
  1501. fileset.setExcludes(sourceRootCopyFilter);
  1502. zip.addFileset(fileset);
  1503. }
  1504. }
  1505. }
  1506. if ((null != inpathDirCopyFilter) && (null != inpath)) {
  1507. String[] paths = inpath.list();
  1508. if (!LangUtil.isEmpty(paths)) {
  1509. for (int i = 0; i < paths.length; i++) {
  1510. File inpathDir = new File(paths[i]);
  1511. if (inpathDir.isDirectory() && inpathDir.canRead()) {
  1512. FileSet fileset = new FileSet();
  1513. fileset.setProject(project);
  1514. fileset.setDir(inpathDir);
  1515. fileset.setIncludes("**/*");
  1516. fileset.setExcludes(inpathDirCopyFilter);
  1517. zip.addFileset(fileset);
  1518. }
  1519. }
  1520. }
  1521. }
  1522. zip.execute();
  1523. }
  1524. // -------------------------- compiler adapter interface extras
  1525. /**
  1526. * Add specified source files.
  1527. */
  1528. void addFiles(File[] paths) {
  1529. for (int i = 0; i < paths.length; i++) {
  1530. addFile(paths[i]);
  1531. }
  1532. }
  1533. /**
  1534. * Add specified source file.
  1535. */
  1536. void addFile(File path) {
  1537. if (null != path) {
  1538. adapterFiles.add(path);
  1539. }
  1540. }
  1541. /**
  1542. * Read arguments in as if from a command line, mainly to support compiler adapter compilerarg subelement.
  1543. *
  1544. * @param args the String[] of arguments to read
  1545. */
  1546. public void readArguments(String[] args) { // XXX slow, stupid, unmaintainable
  1547. if ((null == args) || (0 == args.length)) {
  1548. return;
  1549. }
  1550. /** String[] wrapper with increment, error reporting */
  1551. class Args {
  1552. final String[] args;
  1553. int index = 0;
  1554. Args(String[] args) {
  1555. this.args = args; // not null or empty
  1556. }
  1557. boolean hasNext() {
  1558. return index < args.length;
  1559. }
  1560. String next() {
  1561. String err = null;
  1562. if (!hasNext()) {
  1563. err = "need arg for flag " + args[args.length - 1];
  1564. } else {
  1565. String s = args[index++];
  1566. if (null == s) {
  1567. err = "null value";
  1568. } else {
  1569. s = s.trim();
  1570. if (0 == s.trim().length()) {
  1571. err = "no value";
  1572. } else {
  1573. return s;
  1574. }
  1575. }
  1576. }
  1577. err += " at [" + index + "] of " + Arrays.asList(args);
  1578. throw new BuildException(err);
  1579. }
  1580. } // class Args
  1581. Args in = new Args(args);
  1582. String flag;
  1583. while (in.hasNext()) {
  1584. flag = in.next();
  1585. if ("-1.3".equals(flag)) {
  1586. setCompliance(flag);
  1587. } else if ("-1.4".equals(flag)) {
  1588. setCompliance(flag);
  1589. } else if ("-1.5".equals(flag)) {
  1590. setCompliance("1.5");
  1591. } else if ("-argfile".equals(flag)) {
  1592. setArgfiles(new Path(project, in.next()));
  1593. } else if ("-aspectpath".equals(flag)) {
  1594. setAspectpath(new Path(project, in.next()));
  1595. } else if ("-classpath".equals(flag)) {
  1596. setClasspath(new Path(project, in.next()));
  1597. } else if ("-extdirs".equals(flag)) {
  1598. setExtdirs(new Path(project, in.next()));
  1599. } else if ("-Xcopyinjars".equals(flag)) {
  1600. setCopyInjars(true); // ignored - will be flagged by setter
  1601. } else if ("-g".equals(flag)) {
  1602. setDebug(true);
  1603. } else if (flag.startsWith("-g:")) {
  1604. setDebugLevel(flag.substring(2));
  1605. } else if ("-deprecation".equals(flag)) {
  1606. setDeprecation(true);
  1607. } else if ("-d".equals(flag)) {
  1608. setDestdir(new File(in.next()));
  1609. } else if ("-crossrefs".equals(flag)) {
  1610. setCrossrefs(true);
  1611. } else if ("-emacssym".equals(flag)) {
  1612. setEmacssym(true);
  1613. } else if ("-encoding".equals(flag)) {
  1614. setEncoding(in.next());
  1615. } else if ("-Xfailonerror".equals(flag)) {
  1616. setFailonerror(true);
  1617. } else if ("-fork".equals(flag)) {
  1618. setFork(true);
  1619. } else if ("-forkclasspath".equals(flag)) {
  1620. setForkclasspath(new Path(project, in.next()));
  1621. } else if ("-help".equals(flag)) {
  1622. setHelp(true);
  1623. } else if ("-incremental".equals(flag)) {
  1624. setIncremental(true);
  1625. } else if ("-injars".equals(flag)) {
  1626. setInjars(new Path(project, in.next()));
  1627. } else if ("-inpath".equals(flag)) {
  1628. setInpath(new Path(project, in.next()));
  1629. } else if ("-Xlistfileargs".equals(flag)) {
  1630. setListFileArgs(true);
  1631. } else if ("-Xmaxmem".equals(flag)) {
  1632. setMaxmem(in.next());
  1633. } else if ("-Xmessageholderclass".equals(flag)) {
  1634. setMessageHolderClass(in.next());
  1635. } else if ("-noexit".equals(flag)) {
  1636. setNoExit(true);
  1637. } else if ("-noimport".equals(flag)) {
  1638. setNoExit(true);
  1639. } else if ("-noExit".equals(flag)) {
  1640. setNoExit(true);
  1641. } else if ("-noImportError".equals(flag)) {
  1642. setNoImportError(true);
  1643. } else if ("-noWarn".equals(flag)) {
  1644. setNowarn(true);
  1645. } else if ("-noexit".equals(flag)) {
  1646. setNoExit(true);
  1647. } else if ("-outjar".equals(flag)) {
  1648. setOutjar(new File(in.next()));
  1649. } else if ("-outxml".equals(flag)) {
  1650. setOutxml(true);
  1651. } else if ("-outxmlfile".equals(flag)) {
  1652. setOutxmlfile(in.next());
  1653. } else if ("-preserveAllLocals".equals(flag)) {
  1654. setPreserveAllLocals(true);
  1655. } else if ("-proceedOnError".equals(flag)) {
  1656. setProceedOnError(true);
  1657. } else if ("-referenceInfo".equals(flag)) {
  1658. setReferenceInfo(true);
  1659. } else if ("-source".equals(flag)) {
  1660. setSource(in.next());
  1661. } else if ("-Xsourcerootcopyfilter".equals(flag)) {
  1662. setSourceRootCopyFilter(in.next());
  1663. } else if ("-sourceroots".equals(flag)) {
  1664. setSourceRoots(new Path(project, in.next()));
  1665. } else if ("-Xsrcdir".equals(flag)) {
  1666. setSrcDir(new Path(project, in.next()));
  1667. } else if ("-Xtagfile".equals(flag)) {
  1668. setTagFile(new File(in.next()));
  1669. } else if ("-target".equals(flag)) {
  1670. setTarget(in.next());
  1671. } else if ("-time".equals(flag)) {
  1672. setTime(true);
  1673. } else if ("-time".equals(flag)) {
  1674. setTime(true);
  1675. } else if ("-verbose".equals(flag)) {
  1676. setVerbose(true);
  1677. } else if ("-showWeaveInfo".equals(flag)) {
  1678. setShowWeaveInfo(true);
  1679. } else if ("-version".equals(flag)) {
  1680. setVersion(true);
  1681. } else if ("-warn".equals(flag)) {
  1682. setWarn(in.next());
  1683. } else if (flag.startsWith("-warn:")) {
  1684. setWarn(flag.substring(6));
  1685. } else if ("-Xlint".equals(flag)) {
  1686. setXlintwarnings(true);
  1687. } else if (flag.startsWith("-Xlint:")) {
  1688. setXlint(flag.substring(7));
  1689. } else if ("-Xlintfile".equals(flag)) {
  1690. setXlintfile(new File(in.next()));
  1691. } else if ("-XterminateAfterCompilation".equals(flag)) {
  1692. setXTerminateAfterCompilation(true);
  1693. } else if ("-Xreweavable".equals(flag)) {
  1694. setXReweavable(true);
  1695. } else if ("-XnotReweavable".equals(flag)) {
  1696. setXNotReweavable(true);
  1697. } else if (flag.startsWith("@")) {
  1698. File file = new File(flag.substring(1));
  1699. if (file.canRead()) {
  1700. setArgfiles(new Path(project, file.getPath()));
  1701. } else {
  1702. ignore(flag);
  1703. }
  1704. } else {
  1705. File file = new File(flag);
  1706. if (file.isFile() && file.canRead() && FileUtil.hasSourceSuffix(file)) {
  1707. addFile(file);
  1708. } else {
  1709. ignore(flag);
  1710. }
  1711. }
  1712. }
  1713. }
  1714. protected void logVerbose(String text) {
  1715. if (this.verbose) {
  1716. this.logger.info(text);
  1717. } else {
  1718. this.logger.verbose(text);
  1719. }
  1720. }
  1721. /**
  1722. * Commandline wrapper that only permits addition of non-empty values and converts to argfile form if necessary.
  1723. */
  1724. public static class GuardedCommand {
  1725. Commandline command;
  1726. // int size;
  1727. static boolean isEmpty(String s) {
  1728. return ((null == s) || (0 == s.trim().length()));
  1729. }
  1730. GuardedCommand() {
  1731. command = new Commandline();
  1732. }
  1733. void addFlag(String flag, boolean doAdd) {
  1734. if (doAdd && !isEmpty(flag)) {
  1735. command.createArgument().setValue(flag);
  1736. // size += 1 + flag.length();
  1737. }
  1738. }
  1739. /** @return null if added or ignoreString otherwise */
  1740. String addOption(String prefix, String[] validOptions, String input) {
  1741. if (isEmpty(input)) {
  1742. return null;
  1743. }
  1744. for (int i = 0; i < validOptions.length; i++) {
  1745. if (input.equals(validOptions[i])) {
  1746. if (isEmpty(prefix)) {
  1747. addFlag(input, true);
  1748. } else {
  1749. addFlagged(prefix, input);
  1750. }
  1751. return null;
  1752. }
  1753. }
  1754. return (null == prefix ? input : prefix + " " + input);
  1755. }
  1756. void addFlagged(String flag, String argument) {
  1757. if (!isEmpty(flag) && !isEmpty(argument)) {
  1758. command.addArguments(new String[] { flag, argument });
  1759. // size += 1 + flag.length() + argument.length();
  1760. }
  1761. }
  1762. // private void addFile(File file) {
  1763. // if (null != file) {
  1764. // String path = file.getAbsolutePath();
  1765. // addFlag(path, true);
  1766. // }
  1767. // }
  1768. List extractArguments() {
  1769. ArrayList result = new ArrayList();
  1770. String[] cmds = command.getArguments();
  1771. if (!LangUtil.isEmpty(cmds)) {
  1772. result.addAll(Arrays.asList(cmds));
  1773. }
  1774. return result;
  1775. }
  1776. /**
  1777. * Adjust args for size if necessary by creating an argument file, which should be deleted by the client after the compiler
  1778. * run has completed.
  1779. *
  1780. * @param max the int maximum length of the command line (in char)
  1781. * @return the temp File for the arguments (if generated), for deletion when done.
  1782. * @throws IllegalArgumentException if max is negative
  1783. */
  1784. static String[] limitTo(String[] args, int max, Location location) {
  1785. if (max < 0) {
  1786. throw new IllegalArgumentException("negative max: " + max);
  1787. }
  1788. // sigh - have to count anyway for now
  1789. int size = 0;
  1790. for (int i = 0; (i < args.length) && (size < max); i++) {
  1791. size += 1 + (null == args[i] ? 0 : args[i].length());
  1792. }
  1793. if (size <= max) {
  1794. return args;
  1795. }
  1796. File tmpFile = null;
  1797. PrintWriter out = null;
  1798. // adapted from DefaultCompilerAdapter.executeExternalCompile
  1799. try {
  1800. String userDirName = System.getProperty("user.dir");
  1801. File userDir = new File(userDirName);
  1802. tmpFile = File.createTempFile("argfile", "", userDir);
  1803. out = new PrintWriter(new FileWriter(tmpFile));
  1804. for (int i = 0; i < args.length; i++) {
  1805. out.println(args[i]);
  1806. }
  1807. out.flush();
  1808. return new String[] { "-argfile", tmpFile.getAbsolutePath() };
  1809. } catch (IOException e) {
  1810. throw new BuildException("Error creating temporary file", e, location);
  1811. } finally {
  1812. if (out != null) {
  1813. try {
  1814. out.close();
  1815. } catch (Throwable t) {
  1816. }
  1817. }
  1818. }
  1819. }
  1820. }
  1821. private static class AntMessageHandler implements IMessageHandler {
  1822. private TaskLogger logger;
  1823. private final boolean taskLevelVerbose;
  1824. private final boolean handledMessage;
  1825. public AntMessageHandler(TaskLogger logger, boolean taskVerbose, boolean handledMessage) {
  1826. this.logger = logger;
  1827. this.taskLevelVerbose = taskVerbose;
  1828. this.handledMessage = handledMessage;
  1829. }
  1830. /*
  1831. * (non-Javadoc)
  1832. *
  1833. * @see org.aspectj.bridge.IMessageHandler#handleMessage(org.aspectj.bridge.IMessage)
  1834. */
  1835. public boolean handleMessage(IMessage message) throws AbortException {
  1836. Kind messageKind = message.getKind();
  1837. String messageText = message.toString();
  1838. if (messageKind == IMessage.ABORT) {
  1839. this.logger.error(messageText);
  1840. } else if (messageKind == IMessage.DEBUG) {
  1841. this.logger.debug(messageText);
  1842. } else if (messageKind == IMessage.ERROR) {
  1843. this.logger.error(messageText);
  1844. } else if (messageKind == IMessage.FAIL) {
  1845. this.logger.error(messageText);
  1846. } else if (messageKind == IMessage.INFO) {
  1847. if (this.taskLevelVerbose) {
  1848. this.logger.info(messageText);
  1849. } else {
  1850. this.logger.verbose(messageText);
  1851. }
  1852. } else if (messageKind == IMessage.WARNING) {
  1853. this.logger.warning(messageText);
  1854. } else if (messageKind == IMessage.WEAVEINFO) {
  1855. this.logger.info(messageText);
  1856. } else if (messageKind == IMessage.TASKTAG) {
  1857. // ignore
  1858. } else {
  1859. throw new BuildException("Unknown message kind from AspectJ compiler: " + messageKind.toString());
  1860. }
  1861. return handledMessage;
  1862. }
  1863. /*
  1864. * (non-Javadoc)
  1865. *
  1866. * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
  1867. */
  1868. public boolean isIgnoring(Kind kind) {
  1869. return false;
  1870. }
  1871. /*
  1872. * (non-Javadoc)
  1873. *
  1874. * @see org.aspectj.bridge.IMessageHandler#dontIgnore(org.aspectj.bridge.IMessage.Kind)
  1875. */
  1876. public void dontIgnore(Kind kind) {
  1877. }
  1878. /*
  1879. * (non-Javadoc)
  1880. *
  1881. * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind)
  1882. */
  1883. public void ignore(Kind kind) {
  1884. }
  1885. }
  1886. }