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

Rmic.java 27 kB

9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
11 years ago
11 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package org.apache.tools.ant.taskdefs;
  19. import java.io.File;
  20. import java.io.IOException;
  21. import java.rmi.Remote;
  22. import java.util.Vector;
  23. import java.util.stream.Stream;
  24. import org.apache.tools.ant.AntClassLoader;
  25. import org.apache.tools.ant.BuildException;
  26. import org.apache.tools.ant.DirectoryScanner;
  27. import org.apache.tools.ant.Project;
  28. import org.apache.tools.ant.taskdefs.rmic.RmicAdapter;
  29. import org.apache.tools.ant.taskdefs.rmic.RmicAdapterFactory;
  30. import org.apache.tools.ant.types.FilterSetCollection;
  31. import org.apache.tools.ant.types.Path;
  32. import org.apache.tools.ant.types.Reference;
  33. import org.apache.tools.ant.util.FileNameMapper;
  34. import org.apache.tools.ant.util.FileUtils;
  35. import org.apache.tools.ant.util.SourceFileScanner;
  36. import org.apache.tools.ant.util.StringUtils;
  37. import org.apache.tools.ant.util.facade.FacadeTaskHelper;
  38. /**
  39. * <p>Runs the rmic compiler against classes.</p>
  40. *
  41. * <p>Rmic can be run on a single class (as specified with the classname
  42. * attribute) or a number of classes at once (all classes below base that
  43. * are neither _Stub nor _Skel classes). If you want to rmic a single
  44. * class and this class is a class nested into another class, you have to
  45. * specify the classname in the form <code>Outer$$Inner</code> instead of
  46. * <code>Outer.Inner</code>.</p>
  47. *
  48. * <p>It is possible to refine the set of files that are being rmiced. This can
  49. * be done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>,
  50. * <i>excludesfile</i> and <i>defaultexcludes</i>
  51. * attributes. With the <i>includes</i> or <i>includesfile</i> attribute you
  52. * specify the files you want to have included by using patterns. The
  53. * <i>exclude</i> or <i>excludesfile</i> attribute is used to specify
  54. * the files you want to have excluded. This is also done with patterns. And
  55. * finally with the <i>defaultexcludes</i> attribute, you can specify whether
  56. * you want to use default exclusions or not. See the section on
  57. * directory based tasks, on how the
  58. * inclusion/exclusion of files works, and how to write patterns.</p>
  59. *
  60. * <p>This task forms an implicit FileSet and
  61. * supports all attributes of <code>&lt;fileset&gt;</code>
  62. * (<code>dir</code> becomes <code>base</code>) as well as the nested
  63. * <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
  64. * <code>&lt;patternset&gt;</code> elements.</p>
  65. *
  66. * <p>It is possible to use different compilers. This can be selected
  67. * with the &quot;build.rmic&quot; property or the <code>compiler</code>
  68. * attribute. <a name="compilervalues">There are three choices</a>:</p>
  69. *
  70. * <ul>
  71. * <li>sun (the standard compiler of the JDK)</li>
  72. * <li>kaffe (the standard compiler of
  73. * <a href="http://www.kaffe.org">Kaffe</a>)</li>
  74. * <li>weblogic</li>
  75. * </ul>
  76. *
  77. * <p>The <a href="http://dione.zcu.cz/~toman40/miniRMI/">miniRMI</a>
  78. * project contains a compiler implementation for this task as well,
  79. * please consult miniRMI's documentation to learn how to use it.</p>
  80. *
  81. * @since Ant 1.1
  82. *
  83. * @ant.task category="java"
  84. */
  85. public class Rmic extends MatchingTask {
  86. /** rmic failed message */
  87. public static final String ERROR_RMIC_FAILED
  88. = "Rmic failed; see the compiler error output for details.";
  89. /** unable to verify message */
  90. public static final String ERROR_UNABLE_TO_VERIFY_CLASS = "Unable to verify class ";
  91. /** could not be found message */
  92. public static final String ERROR_NOT_FOUND = ". It could not be found.";
  93. /** not defined message */
  94. public static final String ERROR_NOT_DEFINED = ". It is not defined.";
  95. /** loaded error message */
  96. public static final String ERROR_LOADING_CAUSED_EXCEPTION = ". Loading caused Exception: ";
  97. /** base not exists message */
  98. public static final String ERROR_NO_BASE_EXISTS = "base or destdir does not exist: ";
  99. /** base not a directory message */
  100. public static final String ERROR_NOT_A_DIR = "base or destdir is not a directory:";
  101. /** base attribute not set message */
  102. public static final String ERROR_BASE_NOT_SET = "base or destdir attribute must be set!";
  103. private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
  104. private File baseDir;
  105. private File destDir;
  106. private String classname;
  107. private File sourceBase;
  108. private String stubVersion;
  109. private Path compileClasspath;
  110. private Path extDirs;
  111. private boolean verify = false;
  112. private boolean filtering = false;
  113. private boolean iiop = false;
  114. private String iiopOpts;
  115. private boolean idl = false;
  116. private String idlOpts;
  117. private boolean debug = false;
  118. private boolean includeAntRuntime = true;
  119. private boolean includeJavaRuntime = false;
  120. private Vector<String> compileList = new Vector<>();
  121. private AntClassLoader loader = null;
  122. private FacadeTaskHelper facade;
  123. private String executable = null;
  124. private boolean listFiles = false;
  125. private RmicAdapter nestedAdapter = null;
  126. /**
  127. * Constructor for Rmic.
  128. */
  129. public Rmic() {
  130. facade = new FacadeTaskHelper(RmicAdapterFactory.DEFAULT_COMPILER);
  131. }
  132. /**
  133. * Sets the location to store the compiled files; required
  134. * @param base the location to store the compiled files
  135. */
  136. public void setBase(File base) {
  137. this.baseDir = base;
  138. }
  139. /**
  140. * Sets the base directory to output the generated files.
  141. * @param destdir the base directory to output the generated files.
  142. * @since Ant 1.8.0
  143. */
  144. public void setDestdir(File destdir) {
  145. this.destDir = destdir;
  146. }
  147. /**
  148. * Gets the base directory to output the generated files.
  149. * @return the base directory to output the generated files.
  150. * @since Ant 1.8.0
  151. */
  152. public File getDestdir() {
  153. return this.destDir;
  154. }
  155. /**
  156. * Gets the base directory to output the generated files,
  157. * favoring destdir if set, otherwise defaulting to basedir.
  158. * @return the actual directory to output to (either destdir or basedir)
  159. * @since Ant 1.8.0
  160. */
  161. public File getOutputDir() {
  162. if (getDestdir() != null) {
  163. return getDestdir();
  164. }
  165. return getBase();
  166. }
  167. /**
  168. * Gets the base directory to output generated class.
  169. * @return the location of the compiled files
  170. */
  171. public File getBase() {
  172. return this.baseDir;
  173. }
  174. /**
  175. * Sets the class to run <code>rmic</code> against;
  176. * optional
  177. * @param classname the name of the class for rmic to create code for
  178. */
  179. public void setClassname(String classname) {
  180. this.classname = classname;
  181. }
  182. /**
  183. * Gets the class name to compile.
  184. * @return the name of the class to compile
  185. */
  186. public String getClassname() {
  187. return classname;
  188. }
  189. /**
  190. * optional directory to save generated source files to.
  191. * @param sourceBase the directory to save source files to.
  192. */
  193. public void setSourceBase(File sourceBase) {
  194. this.sourceBase = sourceBase;
  195. }
  196. /**
  197. * Gets the source dirs to find the source java files.
  198. * @return sourceBase the directory containing the source files.
  199. */
  200. public File getSourceBase() {
  201. return sourceBase;
  202. }
  203. /**
  204. * Specify the JDK version for the generated stub code.
  205. * Specify &quot;1.1&quot; to pass the &quot;-v1.1&quot; option to rmic.
  206. * @param stubVersion the JDK version
  207. */
  208. public void setStubVersion(String stubVersion) {
  209. this.stubVersion = stubVersion;
  210. }
  211. /**
  212. * Gets the JDK version for the generated stub code.
  213. * @return stubVersion
  214. */
  215. public String getStubVersion() {
  216. return stubVersion;
  217. }
  218. /**
  219. * Sets token filtering [optional], default=false
  220. * @param filter turn on token filtering
  221. */
  222. public void setFiltering(boolean filter) {
  223. this.filtering = filter;
  224. }
  225. /**
  226. * Gets whether token filtering is set
  227. * @return filtering
  228. */
  229. public boolean getFiltering() {
  230. return filtering;
  231. }
  232. /**
  233. * Generate debug info (passes -g to rmic);
  234. * optional, defaults to false
  235. * @param debug turn on debug info
  236. */
  237. public void setDebug(boolean debug) {
  238. this.debug = debug;
  239. }
  240. /**
  241. * Gets the debug flag.
  242. * @return debug
  243. */
  244. public boolean getDebug() {
  245. return debug;
  246. }
  247. /**
  248. * Set the classpath to be used for this compilation.
  249. * @param classpath the classpath used for this compilation
  250. */
  251. public synchronized void setClasspath(Path classpath) {
  252. if (compileClasspath == null) {
  253. compileClasspath = classpath;
  254. } else {
  255. compileClasspath.append(classpath);
  256. }
  257. }
  258. /**
  259. * Creates a nested classpath element.
  260. * @return classpath
  261. */
  262. public synchronized Path createClasspath() {
  263. if (compileClasspath == null) {
  264. compileClasspath = new Path(getProject());
  265. }
  266. return compileClasspath.createPath();
  267. }
  268. /**
  269. * Adds to the classpath a reference to
  270. * a &lt;path&gt; defined elsewhere.
  271. * @param pathRef the reference to add to the classpath
  272. */
  273. public void setClasspathRef(Reference pathRef) {
  274. createClasspath().setRefid(pathRef);
  275. }
  276. /**
  277. * Gets the classpath.
  278. * @return the classpath
  279. */
  280. public Path getClasspath() {
  281. return compileClasspath;
  282. }
  283. /**
  284. * Flag to enable verification so that the classes
  285. * found by the directory match are
  286. * checked to see if they implement java.rmi.Remote.
  287. * optional; This defaults to false if not set.
  288. * @param verify turn on verification for classes
  289. */
  290. public void setVerify(boolean verify) {
  291. this.verify = verify;
  292. }
  293. /**
  294. * Get verify flag.
  295. * @return verify
  296. */
  297. public boolean getVerify() {
  298. return verify;
  299. }
  300. /**
  301. * Indicates that IIOP compatible stubs should
  302. * be generated; optional, defaults to false
  303. * if not set.
  304. * @param iiop generate IIOP compatible stubs
  305. */
  306. public void setIiop(boolean iiop) {
  307. this.iiop = iiop;
  308. }
  309. /**
  310. * Gets iiop flags.
  311. * @return iiop
  312. */
  313. public boolean getIiop() {
  314. return iiop;
  315. }
  316. /**
  317. * Set additional arguments for iiop
  318. * @param iiopOpts additional arguments for iiop
  319. */
  320. public void setIiopopts(String iiopOpts) {
  321. this.iiopOpts = iiopOpts;
  322. }
  323. /**
  324. * Gets additional arguments for iiop.
  325. * @return iiopOpts
  326. */
  327. public String getIiopopts() {
  328. return iiopOpts;
  329. }
  330. /**
  331. * Indicates that IDL output should be
  332. * generated. This defaults to false
  333. * if not set.
  334. * @param idl generate IDL output
  335. */
  336. public void setIdl(boolean idl) {
  337. this.idl = idl;
  338. }
  339. /**
  340. * Gets IDL flags.
  341. * @return the idl flag
  342. */
  343. public boolean getIdl() {
  344. return idl;
  345. }
  346. /**
  347. * pass additional arguments for IDL compile
  348. * @param idlOpts additional IDL arguments
  349. */
  350. public void setIdlopts(String idlOpts) {
  351. this.idlOpts = idlOpts;
  352. }
  353. /**
  354. * Gets additional arguments for idl compile.
  355. * @return the idl options
  356. */
  357. public String getIdlopts() {
  358. return idlOpts;
  359. }
  360. /**
  361. * Gets file list to compile.
  362. * @return the list of files to compile.
  363. */
  364. public Vector<String> getFileList() {
  365. return compileList;
  366. }
  367. /**
  368. * Sets whether or not to include ant's own classpath in this task's
  369. * classpath.
  370. * Optional; default is <code>true</code>.
  371. * @param include if true include ant's classpath
  372. */
  373. public void setIncludeantruntime(boolean include) {
  374. includeAntRuntime = include;
  375. }
  376. /**
  377. * Gets whether or not the ant classpath is to be included in the
  378. * task's classpath.
  379. * @return true if ant's classpath is to be included
  380. */
  381. public boolean getIncludeantruntime() {
  382. return includeAntRuntime;
  383. }
  384. /**
  385. * task's classpath.
  386. * Enables or disables including the default run-time
  387. * libraries from the executing VM; optional,
  388. * defaults to false
  389. * @param include if true include default run-time libraries
  390. */
  391. public void setIncludejavaruntime(boolean include) {
  392. includeJavaRuntime = include;
  393. }
  394. /**
  395. * Gets whether or not the java runtime should be included in this
  396. * task's classpath.
  397. * @return true if default run-time libraries are included
  398. */
  399. public boolean getIncludejavaruntime() {
  400. return includeJavaRuntime;
  401. }
  402. /**
  403. * Sets the extension directories that will be used during the
  404. * compilation; optional.
  405. * @param extDirs the extension directories to be used
  406. */
  407. public synchronized void setExtdirs(Path extDirs) {
  408. if (this.extDirs == null) {
  409. this.extDirs = extDirs;
  410. } else {
  411. this.extDirs.append(extDirs);
  412. }
  413. }
  414. /**
  415. * Maybe creates a nested extdirs element.
  416. * @return path object to be configured with the extension directories
  417. */
  418. public synchronized Path createExtdirs() {
  419. if (extDirs == null) {
  420. extDirs = new Path(getProject());
  421. }
  422. return extDirs.createPath();
  423. }
  424. /**
  425. * Gets the extension directories that will be used during the
  426. * compilation.
  427. * @return the extension directories to be used
  428. */
  429. public Path getExtdirs() {
  430. return extDirs;
  431. }
  432. /**
  433. * @return the compile list.
  434. */
  435. public Vector<String> getCompileList() {
  436. return compileList;
  437. }
  438. /**
  439. * Sets the compiler implementation to use; optional,
  440. * defaults to the value of the <code>build.rmic</code> property,
  441. * or failing that, default compiler for the current VM
  442. * @param compiler the compiler implementation to use
  443. * @since Ant 1.5
  444. */
  445. public void setCompiler(String compiler) {
  446. if (!compiler.isEmpty()) {
  447. facade.setImplementation(compiler);
  448. }
  449. }
  450. /**
  451. * get the name of the current compiler
  452. * @return the name of the compiler
  453. * @since Ant 1.5
  454. */
  455. public String getCompiler() {
  456. facade.setMagicValue(getProject().getProperty("build.rmic"));
  457. return facade.getImplementation();
  458. }
  459. /**
  460. * Adds an implementation specific command line argument.
  461. * @return an object to be configured with a command line argument
  462. * @since Ant 1.5
  463. */
  464. public ImplementationSpecificArgument createCompilerArg() {
  465. ImplementationSpecificArgument arg = new ImplementationSpecificArgument();
  466. facade.addImplementationArgument(arg);
  467. return arg;
  468. }
  469. /**
  470. * Get the additional implementation specific command line arguments.
  471. * @return array of command line arguments, guaranteed to be non-null.
  472. * @since Ant 1.5
  473. */
  474. public String[] getCurrentCompilerArgs() {
  475. getCompiler();
  476. return facade.getArgs();
  477. }
  478. /**
  479. * Name of the executable to use when forking.
  480. *
  481. * @param ex String
  482. * @since Ant 1.8.0
  483. */
  484. public void setExecutable(String ex) {
  485. executable = ex;
  486. }
  487. /**
  488. * Explicitly specified name of the executable to use when forking
  489. * - if any.
  490. *
  491. * @return String
  492. * @since Ant 1.8.0
  493. */
  494. public String getExecutable() {
  495. return executable;
  496. }
  497. /**
  498. * The classpath to use when loading the compiler implementation
  499. * if it is not a built-in one.
  500. *
  501. * @return Path
  502. * @since Ant 1.8.0
  503. */
  504. public Path createCompilerClasspath() {
  505. return facade.getImplementationClasspath(getProject());
  506. }
  507. /**
  508. * If true, list the source files being handed off to the compiler.
  509. *
  510. * @param list if true list the source files
  511. * @since Ant 1.8.0
  512. */
  513. public void setListfiles(boolean list) {
  514. listFiles = list;
  515. }
  516. /**
  517. * Set the compiler adapter explicitly.
  518. *
  519. * @param adapter RmicAdapter
  520. * @since Ant 1.8.0
  521. */
  522. public void add(RmicAdapter adapter) {
  523. if (nestedAdapter != null) {
  524. throw new BuildException("Can't have more than one rmic adapter");
  525. }
  526. nestedAdapter = adapter;
  527. }
  528. /**
  529. * execute by creating an instance of an implementation
  530. * class and getting to do the work
  531. * @throws BuildException
  532. * if there's a problem with baseDir or RMIC
  533. */
  534. @Override
  535. public void execute() throws BuildException {
  536. try {
  537. compileList.clear();
  538. File outputDir = getOutputDir();
  539. if (outputDir == null) {
  540. throw new BuildException(ERROR_BASE_NOT_SET, getLocation());
  541. }
  542. if (!outputDir.exists()) {
  543. throw new BuildException(ERROR_NO_BASE_EXISTS + outputDir,
  544. getLocation());
  545. }
  546. if (!outputDir.isDirectory()) {
  547. throw new BuildException(ERROR_NOT_A_DIR + outputDir, getLocation());
  548. }
  549. if (verify) {
  550. log("Verify has been turned on.", Project.MSG_VERBOSE);
  551. }
  552. RmicAdapter adapter =
  553. nestedAdapter != null ? nestedAdapter :
  554. RmicAdapterFactory.getRmic(getCompiler(), this,
  555. createCompilerClasspath());
  556. // now we need to populate the compiler adapter
  557. adapter.setRmic(this);
  558. Path classpath = adapter.getClasspath();
  559. loader = getProject().createClassLoader(classpath);
  560. // scan base dirs to build up compile lists only if a
  561. // specific classname is not given
  562. if (classname == null) {
  563. DirectoryScanner ds = this.getDirectoryScanner(baseDir);
  564. String[] files = ds.getIncludedFiles();
  565. scanDir(baseDir, files, adapter.getMapper());
  566. } else {
  567. // otherwise perform a timestamp comparison - at least
  568. String path = classname.replace('.', File.separatorChar)
  569. + ".class";
  570. File f = new File(baseDir, path);
  571. if (f.isFile()) {
  572. scanDir(baseDir, new String[] {path}, adapter.getMapper());
  573. } else {
  574. // Does not exist, so checking whether it is up to
  575. // date makes no sense. Compilation will fail
  576. // later anyway, but tests expect a certain
  577. // output.
  578. compileList.add(classname);
  579. }
  580. }
  581. int fileCount = compileList.size();
  582. if (fileCount > 0) {
  583. log("RMI Compiling " + fileCount + " class"
  584. + (fileCount > 1 ? "es" : "") + " to "
  585. + outputDir, Project.MSG_INFO);
  586. if (listFiles) {
  587. compileList.forEach(this::log);
  588. }
  589. // finally, lets execute the compiler!!
  590. if (!adapter.execute()) {
  591. throw new BuildException(ERROR_RMIC_FAILED, getLocation());
  592. }
  593. }
  594. /*
  595. * Move the generated source file to the base directory. If
  596. * base directory and sourcebase are the same, the generated
  597. * sources are already in place.
  598. */
  599. if (null != sourceBase && !outputDir.equals(sourceBase)
  600. && fileCount > 0) {
  601. if (idl) {
  602. log("Cannot determine sourcefiles in idl mode, ",
  603. Project.MSG_WARN);
  604. log("sourcebase attribute will be ignored.",
  605. Project.MSG_WARN);
  606. } else {
  607. compileList.forEach(f -> moveGeneratedFile(outputDir,
  608. sourceBase, f, adapter));
  609. }
  610. }
  611. } finally {
  612. cleanup();
  613. }
  614. }
  615. /**
  616. * Cleans up resources.
  617. *
  618. * @since Ant 1.8.0
  619. */
  620. protected void cleanup() {
  621. if (loader != null) {
  622. loader.cleanup();
  623. loader = null;
  624. }
  625. }
  626. /**
  627. * Move the generated source file(s) to the base directory
  628. *
  629. * @throws BuildException When error
  630. * copying/removing files.
  631. */
  632. private void moveGeneratedFile(File baseDir, File sourceBaseFile, String classname,
  633. RmicAdapter adapter) throws BuildException {
  634. String classFileName = classname.replace('.', File.separatorChar)
  635. + ".class";
  636. String[] generatedFiles = adapter.getMapper().mapFileName(classFileName);
  637. if (generatedFiles == null) {
  638. return;
  639. }
  640. for (String generatedFile : generatedFiles) {
  641. if (!generatedFile.endsWith(".class")) {
  642. // don't know how to handle that - a IDL file doesn't
  643. // have a corresponding Java source for example.
  644. continue;
  645. }
  646. String sourceFileName =
  647. StringUtils.removeSuffix(generatedFile, ".class") + ".java";
  648. File oldFile = new File(baseDir, sourceFileName);
  649. if (!oldFile.exists()) {
  650. // no source file generated, nothing to move
  651. continue;
  652. }
  653. File newFile = new File(sourceBaseFile, sourceFileName);
  654. try {
  655. if (filtering) {
  656. FILE_UTILS.copyFile(oldFile, newFile,
  657. new FilterSetCollection(getProject()
  658. .getGlobalFilterSet()));
  659. } else {
  660. FILE_UTILS.copyFile(oldFile, newFile);
  661. }
  662. oldFile.delete();
  663. } catch (IOException ioe) {
  664. throw new BuildException("Failed to copy " + oldFile + " to "
  665. + newFile + " due to " + ioe.getMessage(), ioe,
  666. getLocation());
  667. }
  668. }
  669. }
  670. /**
  671. * Scans the directory looking for class files to be compiled.
  672. * The result is returned in the class variable compileList.
  673. * @param baseDir the base direction
  674. * @param files the list of files to scan
  675. * @param mapper the mapper of files to target files
  676. */
  677. protected void scanDir(File baseDir, String[] files, FileNameMapper mapper) {
  678. String[] newFiles = files;
  679. if (idl) {
  680. log("will leave uptodate test to rmic implementation in idl mode.",
  681. Project.MSG_VERBOSE);
  682. } else if (iiop && iiopOpts != null && iiopOpts.contains("-always")) {
  683. log("no uptodate test as -always option has been specified",
  684. Project.MSG_VERBOSE);
  685. } else {
  686. SourceFileScanner sfs = new SourceFileScanner(this);
  687. newFiles = sfs.restrict(files, baseDir, getOutputDir(), mapper);
  688. }
  689. Stream.of(newFiles).map(s -> s.replace(File.separatorChar, '.'))
  690. .map(s -> s.substring(0, s.lastIndexOf(".class")))
  691. .forEach(compileList::add);
  692. }
  693. /**
  694. * Load named class and test whether it can be rmic'ed
  695. * @param classname the name of the class to be tested
  696. * @return true if the class can be rmic'ed
  697. */
  698. public boolean isValidRmiRemote(String classname) {
  699. try {
  700. Class<?> testClass = loader.loadClass(classname);
  701. // One cannot RMIC an interface for "classic" RMI (JRMP)
  702. if (testClass.isInterface() && !iiop && !idl) {
  703. return false;
  704. }
  705. return isValidRmiRemote(testClass);
  706. } catch (ClassNotFoundException e) {
  707. log(ERROR_UNABLE_TO_VERIFY_CLASS + classname + ERROR_NOT_FOUND,
  708. Project.MSG_WARN);
  709. } catch (NoClassDefFoundError e) {
  710. log(ERROR_UNABLE_TO_VERIFY_CLASS + classname + ERROR_NOT_DEFINED,
  711. Project.MSG_WARN);
  712. } catch (Throwable t) {
  713. log(ERROR_UNABLE_TO_VERIFY_CLASS + classname
  714. + ERROR_LOADING_CAUSED_EXCEPTION + t.getMessage(),
  715. Project.MSG_WARN);
  716. }
  717. // we only get here if an exception has been thrown
  718. return false;
  719. }
  720. /**
  721. * Returns the topmost interface that extends Remote for a given
  722. * class - if one exists.
  723. * @param testClass the class to be tested
  724. * @return the topmost interface that extends Remote, or null if there
  725. * is none.
  726. */
  727. public Class<?> getRemoteInterface(Class<?> testClass) {
  728. return Stream.of(testClass.getInterfaces())
  729. .filter(Remote.class::isAssignableFrom).findFirst().orElse(null);
  730. }
  731. /**
  732. * Check to see if the class or (super)interfaces implement
  733. * java.rmi.Remote.
  734. */
  735. private boolean isValidRmiRemote(Class<?> testClass) {
  736. return Remote.class.isAssignableFrom(testClass);
  737. }
  738. /**
  739. * Classloader for the user-specified classpath.
  740. * @return the classloader
  741. */
  742. public ClassLoader getLoader() {
  743. return loader;
  744. }
  745. /**
  746. * Adds an "compiler" attribute to Commandline$Attribute used to
  747. * filter command line attributes based on the current
  748. * implementation.
  749. */
  750. public class ImplementationSpecificArgument extends
  751. org.apache.tools.ant.util.facade.ImplementationSpecificArgument {
  752. /**
  753. * Only pass the specified argument if the
  754. * chosen compiler implementation matches the
  755. * value of this attribute. Legal values are
  756. * the same as those in the above list of
  757. * valid compilers.)
  758. * @param impl the compiler to be used.
  759. */
  760. public void setCompiler(String impl) {
  761. super.setImplementation(impl);
  762. }
  763. }
  764. }