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.

Diagnostics.java 14 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /*
  2. * Copyright 2002-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant;
  18. import org.apache.tools.ant.util.LoaderUtils;
  19. import org.apache.tools.ant.launch.Launcher;
  20. import javax.xml.parsers.SAXParserFactory;
  21. import javax.xml.parsers.SAXParser;
  22. import java.io.File;
  23. import java.io.FilenameFilter;
  24. import java.io.PrintStream;
  25. import java.io.InputStream;
  26. import java.io.IOException;
  27. import java.util.Enumeration;
  28. import java.util.Properties;
  29. import java.lang.reflect.Method;
  30. import java.lang.reflect.InvocationTargetException;
  31. /**
  32. * A little diagnostic helper that output some information that may help
  33. * in support. It should quickly give correct information about the
  34. * jar existing in ant.home/lib and the jar versions...
  35. *
  36. * @since Ant 1.5
  37. */
  38. public final class Diagnostics {
  39. private static final String TEST_CLASS
  40. = "org.apache.tools.ant.taskdefs.optional.Test";
  41. /** utility class */
  42. private Diagnostics() {
  43. }
  44. /**
  45. * Check if optional tasks are available. Not that it does not check
  46. * for implementation version. Use <tt>validateVersion()</tt> for this.
  47. * @return <tt>true</tt> if optional tasks are available.
  48. */
  49. public static boolean isOptionalAvailable() {
  50. try {
  51. Class.forName(TEST_CLASS);
  52. } catch (ClassNotFoundException e) {
  53. return false;
  54. }
  55. return true;
  56. }
  57. /**
  58. * Check if core and optional implementation version do match.
  59. * @throws BuildException if the implementation version of optional tasks
  60. * does not match the core implementation version.
  61. */
  62. public static void validateVersion() throws BuildException {
  63. try {
  64. Class optional
  65. = Class.forName("org.apache.tools.ant.taskdefs.optional.Test");
  66. String coreVersion = getImplementationVersion(Main.class);
  67. String optionalVersion = getImplementationVersion(optional);
  68. if (coreVersion != null && !coreVersion.equals(optionalVersion)) {
  69. throw new BuildException("Invalid implementation version "
  70. + "between Ant core and Ant optional tasks.\n"
  71. + " core : " + coreVersion + "\n"
  72. + " optional: " + optionalVersion);
  73. }
  74. } catch (ClassNotFoundException e) {
  75. // ignore
  76. }
  77. }
  78. /**
  79. * return the list of jar files existing in ANT_HOME/lib
  80. * and that must have been picked up by Ant script.
  81. * @return the list of jar files existing in ant.home/lib or
  82. * <tt>null</tt> if an error occurs.
  83. */
  84. public static File[] listLibraries() {
  85. String home = System.getProperty("ant.home");
  86. if (home == null) {
  87. return null;
  88. }
  89. File libDir = new File(home, "lib");
  90. return listJarFiles(libDir);
  91. }
  92. /**
  93. * get a list of all JAR files in a directory
  94. * @param libDir directory
  95. * @return array of files (or null for no such directory)
  96. */
  97. private static File[] listJarFiles(File libDir) {
  98. FilenameFilter filter = new FilenameFilter() {
  99. public boolean accept(File dir, String name) {
  100. return name.endsWith(".jar");
  101. }
  102. };
  103. File[] files = libDir.listFiles(filter);
  104. return files;
  105. }
  106. /**
  107. * main entry point for command line
  108. * @param args command line arguments.
  109. */
  110. public static void main(String[] args) {
  111. doReport(System.out);
  112. }
  113. /**
  114. * Helper method to get the implementation version.
  115. * @param clazz the class to get the information from.
  116. * @return null if there is no package or implementation version.
  117. * '?.?' for JDK 1.0 or 1.1.
  118. */
  119. private static String getImplementationVersion(Class clazz) {
  120. Package pkg = clazz.getPackage();
  121. return pkg.getImplementationVersion();
  122. }
  123. /**
  124. * what parser are we using.
  125. * @return the classname of the parser
  126. */
  127. private static String getXmlParserName() {
  128. SAXParser saxParser = getSAXParser();
  129. if (saxParser == null) {
  130. return "Could not create an XML Parser";
  131. }
  132. // check to what is in the classname
  133. String saxParserName = saxParser.getClass().getName();
  134. return saxParserName;
  135. }
  136. /**
  137. * Create a JAXP SAXParser
  138. * @return parser or null for trouble
  139. */
  140. private static SAXParser getSAXParser() {
  141. SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
  142. if (saxParserFactory == null) {
  143. return null;
  144. }
  145. SAXParser saxParser = null;
  146. try {
  147. saxParser = saxParserFactory.newSAXParser();
  148. } catch (Exception e) {
  149. // ignore
  150. }
  151. return saxParser;
  152. }
  153. /**
  154. * get the location of the parser
  155. * @return path or null for trouble in tracking it down
  156. */
  157. private static String getXMLParserLocation() {
  158. SAXParser saxParser = getSAXParser();
  159. if (saxParser == null) {
  160. return null;
  161. }
  162. String location = getClassLocation(saxParser.getClass());
  163. return location;
  164. }
  165. /**
  166. * get the location of a class. Stolen from axis/webapps/happyaxis.jsp
  167. * @param clazz
  168. * @return the jar file or path where a class was found, or null
  169. */
  170. private static String getClassLocation(Class clazz) {
  171. File f = LoaderUtils.getClassSource(clazz);
  172. return f == null ? null : f.getAbsolutePath();
  173. }
  174. /**
  175. * Print a report to the given stream.
  176. * @param out the stream to print the report to.
  177. */
  178. public static void doReport(PrintStream out) {
  179. out.println("------- Ant diagnostics report -------");
  180. out.println(Main.getAntVersion());
  181. out.println();
  182. out.println("-------------------------------------------");
  183. out.println(" Implementation Version ");
  184. out.println("-------------------------------------------");
  185. out.println("core tasks : " + getImplementationVersion(Main.class));
  186. Class optional = null;
  187. try {
  188. optional = Class.forName(
  189. "org.apache.tools.ant.taskdefs.optional.Test");
  190. out.println("optional tasks : "
  191. + getImplementationVersion(optional));
  192. } catch (ClassNotFoundException e) {
  193. out.println("optional tasks : not available");
  194. }
  195. out.println();
  196. out.println("-------------------------------------------");
  197. out.println(" ANT_HOME/lib jar listing");
  198. out.println("-------------------------------------------");
  199. doReportAntHomeLibraries(out);
  200. out.println();
  201. out.println("-------------------------------------------");
  202. out.println(" USER_HOME/.ant/lib jar listing");
  203. out.println("-------------------------------------------");
  204. doReportUserHomeLibraries(out);
  205. out.println();
  206. out.println("-------------------------------------------");
  207. out.println(" Tasks availability");
  208. out.println("-------------------------------------------");
  209. doReportTasksAvailability(out);
  210. out.println();
  211. out.println("-------------------------------------------");
  212. out.println(" org.apache.env.Which diagnostics");
  213. out.println("-------------------------------------------");
  214. doReportWhich(out);
  215. out.println();
  216. out.println("-------------------------------------------");
  217. out.println(" XML Parser information");
  218. out.println("-------------------------------------------");
  219. doReportParserInfo(out);
  220. out.println();
  221. out.println("-------------------------------------------");
  222. out.println(" System properties");
  223. out.println("-------------------------------------------");
  224. doReportSystemProperties(out);
  225. out.println();
  226. }
  227. /**
  228. * Report a listing of system properties existing in the current vm.
  229. * @param out the stream to print the properties to.
  230. */
  231. private static void doReportSystemProperties(PrintStream out) {
  232. for (Enumeration keys = System.getProperties().propertyNames();
  233. keys.hasMoreElements();) {
  234. String key = (String) keys.nextElement();
  235. out.println(key + " : " + System.getProperty(key));
  236. }
  237. }
  238. /**
  239. * Report the content of ANT_HOME/lib directory
  240. * @param out the stream to print the content to
  241. */
  242. private static void doReportAntHomeLibraries(PrintStream out) {
  243. out.println("ant.home: " + System.getProperty("ant.home"));
  244. File[] libs = listLibraries();
  245. printLibraries(libs, out);
  246. }
  247. /**
  248. * Report the content of ~/.ant/lib directory
  249. *
  250. * @param out the stream to print the content to
  251. */
  252. private static void doReportUserHomeLibraries(PrintStream out) {
  253. String home = System.getProperty(Launcher.USER_HOMEDIR);
  254. out.println("user.home: " + home);
  255. File libDir = new File(home,
  256. Launcher.ANT_PRIVATEDIR+File.separator+Launcher.ANT_PRIVATELIB);
  257. File[] libs=listJarFiles(libDir);
  258. printLibraries(libs, out);
  259. }
  260. /**
  261. * list the libraries
  262. * @param libs array of libraries (can be null)
  263. * @param out output stream
  264. */
  265. private static void printLibraries(File[] libs, PrintStream out) {
  266. if (libs == null) {
  267. out.println("No such directory.");
  268. return;
  269. }
  270. for (int i = 0; i < libs.length; i++) {
  271. out.println(libs[i].getName()
  272. + " (" + libs[i].length() + " bytes)");
  273. }
  274. }
  275. /**
  276. * Call org.apache.env.Which if available
  277. * @param out the stream to print the content to.
  278. */
  279. private static void doReportWhich(PrintStream out) {
  280. Throwable error = null;
  281. try {
  282. Class which = Class.forName("org.apache.env.Which");
  283. Method method
  284. = which.getMethod("main", new Class[]{String[].class});
  285. method.invoke(null, new Object[]{new String[]{}});
  286. } catch (ClassNotFoundException e) {
  287. out.println("Not available.");
  288. out.println("Download it at http://xml.apache.org/commons/");
  289. } catch (InvocationTargetException e) {
  290. error = e.getTargetException() == null ? e : e.getTargetException();
  291. } catch (Throwable e) {
  292. error = e;
  293. }
  294. // report error if something weird happens...this is diagnostic.
  295. if (error != null) {
  296. out.println("Error while running org.apache.env.Which");
  297. error.printStackTrace();
  298. }
  299. }
  300. /**
  301. * Create a report about non-available tasks that are defined in the
  302. * mapping but could not be found via lookup. It might generally happen
  303. * because Ant requires multiple libraries to compile and one of them
  304. * was missing when compiling Ant.
  305. * @param out the stream to print the tasks report to
  306. * <tt>null</tt> for a missing stream (ie mapping).
  307. */
  308. private static void doReportTasksAvailability(PrintStream out) {
  309. InputStream is = Main.class.getResourceAsStream(
  310. "/org/apache/tools/ant/taskdefs/defaults.properties");
  311. if (is == null) {
  312. out.println("None available");
  313. } else {
  314. Properties props = new Properties();
  315. try {
  316. props.load(is);
  317. for (Enumeration keys = props.keys(); keys.hasMoreElements();) {
  318. String key = (String) keys.nextElement();
  319. String classname = props.getProperty(key);
  320. try {
  321. Class.forName(classname);
  322. props.remove(key);
  323. } catch (ClassNotFoundException e) {
  324. out.println(key + " : Not Available");
  325. } catch (NoClassDefFoundError e) {
  326. String pkg = e.getMessage().replace('/', '.');
  327. out.println(key + " : Missing dependency " + pkg);
  328. } catch (Error e) {
  329. out.println(key + " : Initialization error");
  330. }
  331. }
  332. if (props.size() == 0) {
  333. out.println("All defined tasks are available");
  334. }
  335. } catch (IOException e) {
  336. out.println(e.getMessage());
  337. }
  338. }
  339. }
  340. /**
  341. * tell the user about the XML parser
  342. * @param out
  343. */
  344. private static void doReportParserInfo(PrintStream out) {
  345. String parserName = getXmlParserName();
  346. String parserLocation = getXMLParserLocation();
  347. if (parserName == null) {
  348. parserName = "unknown";
  349. }
  350. if (parserLocation == null) {
  351. parserLocation = "unknown";
  352. }
  353. out.println("XML Parser : " + parserName);
  354. out.println("XML Parser Location: " + parserLocation);
  355. }
  356. }