KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > Diagnostics


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;
19
20 import org.apache.tools.ant.util.LoaderUtils;
21 import org.apache.tools.ant.util.FileUtils;
22 import org.apache.tools.ant.util.JAXPUtils;
23 import org.apache.tools.ant.util.ProxySetup;
24 import org.apache.tools.ant.util.JavaEnvUtils;
25 import org.apache.tools.ant.launch.Launcher;
26 import org.xml.sax.XMLReader JavaDoc;
27
28 import javax.xml.parsers.SAXParserFactory JavaDoc;
29 import javax.xml.parsers.SAXParser JavaDoc;
30 import java.io.File JavaDoc;
31 import java.io.FilenameFilter JavaDoc;
32 import java.io.PrintStream JavaDoc;
33 import java.io.InputStream JavaDoc;
34 import java.io.IOException JavaDoc;
35 import java.io.FileOutputStream JavaDoc;
36 import java.util.Enumeration JavaDoc;
37 import java.util.Properties JavaDoc;
38 import java.util.Calendar JavaDoc;
39 import java.util.TimeZone JavaDoc;
40 import java.lang.reflect.Method JavaDoc;
41 import java.lang.reflect.InvocationTargetException JavaDoc;
42
43 /**
44  * A little diagnostic helper that output some information that may help
45  * in support. It should quickly give correct information about the
46  * jar existing in ant.home/lib and the jar versions...
47  *
48  * @since Ant 1.5
49  */

50 public final class Diagnostics {
51
52     /**
53      * value for which a difference between clock and temp file time triggers
54      * a warning.
55      * {@value}
56      */

57     private static final int BIG_DRIFT_LIMIT = 10000;
58     /**
59      * How big a test file to write.
60      * {@value}
61      */

62     private static final int TEST_FILE_SIZE = 32;
63     private static final int KILOBYTE = 1024;
64     private static final int SECONDS_PER_MILLISECOND = 1000;
65     private static final int SECONDS_PER_MINUTE = 60;
66     private static final int MINUTES_PER_HOUR = 60;
67     private static final String JavaDoc TEST_CLASS
68         = "org.apache.tools.ant.taskdefs.optional.Test";
69
70     /**
71      * The error text when a security manager blocks access to a property.
72      * {@value}
73      */

74     protected static final String JavaDoc ERROR_PROPERTY_ACCESS_BLOCKED
75         = "Access to this property blocked by a security manager";
76
77     /** utility class */
78     private Diagnostics() {
79         // hidden constructor
80
}
81
82     /**
83      * Check if optional tasks are available. Not that it does not check
84      * for implementation version. Use <tt>validateVersion()</tt> for this.
85      * @return <tt>true</tt> if optional tasks are available.
86      */

87     public static boolean isOptionalAvailable() {
88         try {
89             Class.forName(TEST_CLASS);
90         } catch (ClassNotFoundException JavaDoc e) {
91             return false;
92         }
93         return true;
94     }
95
96     /**
97      * Check if core and optional implementation version do match.
98      * @throws BuildException if the implementation version of optional tasks
99      * does not match the core implementation version.
100      */

101     public static void validateVersion() throws BuildException {
102         try {
103             Class JavaDoc optional
104                 = Class.forName(TEST_CLASS);
105             String JavaDoc coreVersion = getImplementationVersion(Main.class);
106             String JavaDoc optionalVersion = getImplementationVersion(optional);
107
108             if (coreVersion != null && !coreVersion.equals(optionalVersion)) {
109                 throw new BuildException("Invalid implementation version "
110                     + "between Ant core and Ant optional tasks.\n"
111                     + " core : " + coreVersion + "\n"
112                     + " optional: " + optionalVersion);
113             }
114         } catch (ClassNotFoundException JavaDoc e) {
115             // ignore
116
ignoreThrowable(e);
117         }
118     }
119
120     /**
121      * return the list of jar files existing in ANT_HOME/lib
122      * and that must have been picked up by Ant script.
123      * @return the list of jar files existing in ant.home/lib or
124      * <tt>null</tt> if an error occurs.
125      */

126     public static File JavaDoc[] listLibraries() {
127         String JavaDoc home = System.getProperty(MagicNames.ANT_HOME);
128         if (home == null) {
129             return null;
130         }
131         File JavaDoc libDir = new File JavaDoc(home, "lib");
132         return listJarFiles(libDir);
133
134     }
135
136     /**
137      * get a list of all JAR files in a directory
138      * @param libDir directory
139      * @return array of files (or null for no such directory)
140      */

141     private static File JavaDoc[] listJarFiles(File JavaDoc libDir) {
142         FilenameFilter JavaDoc filter = new FilenameFilter JavaDoc() {
143             public boolean accept(File JavaDoc dir, String JavaDoc name) {
144                 return name.endsWith(".jar");
145             }
146         };
147
148         File JavaDoc[] files = libDir.listFiles(filter);
149         return files;
150     }
151
152     /**
153      * main entry point for command line
154      * @param args command line arguments.
155      */

156     public static void main(String JavaDoc[] args) {
157         doReport(System.out);
158     }
159
160
161     /**
162      * Helper method to get the implementation version.
163      * @param clazz the class to get the information from.
164      * @return null if there is no package or implementation version.
165      * '?.?' for JDK 1.0 or 1.1.
166      */

167     private static String JavaDoc getImplementationVersion(Class JavaDoc clazz) {
168         Package JavaDoc pkg = clazz.getPackage();
169         return pkg.getImplementationVersion();
170     }
171
172     /**
173      * what parser are we using.
174      * @return the classname of the parser
175      */

176     private static String JavaDoc getXmlParserName() {
177         SAXParser JavaDoc saxParser = getSAXParser();
178         if (saxParser == null) {
179             return "Could not create an XML Parser";
180         }
181
182         // check to what is in the classname
183
String JavaDoc saxParserName = saxParser.getClass().getName();
184         return saxParserName;
185     }
186
187     /**
188      * Create a JAXP SAXParser
189      * @return parser or null for trouble
190      */

191     private static SAXParser JavaDoc getSAXParser() {
192         SAXParserFactory JavaDoc saxParserFactory = SAXParserFactory.newInstance();
193         if (saxParserFactory == null) {
194             return null;
195         }
196         SAXParser JavaDoc saxParser = null;
197         try {
198             saxParser = saxParserFactory.newSAXParser();
199         } catch (Exception JavaDoc e) {
200             // ignore
201
ignoreThrowable(e);
202         }
203         return saxParser;
204     }
205
206     /**
207      * get the location of the parser
208      * @return path or null for trouble in tracking it down
209      */

210
211     private static String JavaDoc getXMLParserLocation() {
212         SAXParser JavaDoc saxParser = getSAXParser();
213         if (saxParser == null) {
214             return null;
215         }
216         String JavaDoc location = getClassLocation(saxParser.getClass());
217         return location;
218     }
219
220     private static String JavaDoc getNamespaceParserName() {
221         try {
222             XMLReader JavaDoc reader = JAXPUtils.getNamespaceXMLReader();
223             return reader.getClass().getName();
224         } catch (BuildException e) {
225             //ignore
226
ignoreThrowable(e);
227             return null;
228         }
229     }
230
231     private static String JavaDoc getNamespaceParserLocation() {
232         try {
233             XMLReader JavaDoc reader = JAXPUtils.getNamespaceXMLReader();
234             return getClassLocation(reader.getClass());
235         } catch (BuildException e) {
236             //ignore
237
ignoreThrowable(e);
238             return null;
239         }
240     }
241
242     /**
243      * ignore exceptions. This is to allow future
244      * implementations to log at a verbose level
245      * @param thrown
246      */

247     private static void ignoreThrowable(Throwable JavaDoc thrown) {
248     }
249
250     /**
251      * get the location of a class. Stolen from axis/webapps/happyaxis.jsp
252      * @param clazz
253      * @return the jar file or path where a class was found, or null
254      */

255
256     private static String JavaDoc getClassLocation(Class JavaDoc clazz) {
257         File JavaDoc f = LoaderUtils.getClassSource(clazz);
258         return f == null ? null : f.getAbsolutePath();
259     }
260
261
262     /**
263      * Print a report to the given stream.
264      * @param out the stream to print the report to.
265      */

266     public static void doReport(PrintStream JavaDoc out) {
267         out.println("------- Ant diagnostics report -------");
268         out.println(Main.getAntVersion());
269         header(out, "Implementation Version");
270
271         out.println("core tasks : " + getImplementationVersion(Main.class));
272
273         Class JavaDoc optional = null;
274         try {
275             optional = Class.forName(TEST_CLASS);
276             out.println("optional tasks : "
277                 + getImplementationVersion(optional));
278         } catch (ClassNotFoundException JavaDoc e) {
279             ignoreThrowable(e);
280             out.println("optional tasks : not available");
281         }
282
283         header(out, "ANT PROPERTIES");
284         doReportAntProperties(out);
285
286         header(out, "ANT_HOME/lib jar listing");
287         doReportAntHomeLibraries(out);
288
289         header(out, "USER_HOME/.ant/lib jar listing");
290         doReportUserHomeLibraries(out);
291
292         header(out, "Tasks availability");
293         doReportTasksAvailability(out);
294
295         header(out, "org.apache.env.Which diagnostics");
296         doReportWhich(out);
297
298         header(out, "XML Parser information");
299         doReportParserInfo(out);
300
301         header(out, "System properties");
302         doReportSystemProperties(out);
303
304         header(out, "Temp dir");
305         doReportTempDir(out);
306
307         header(out, "Locale information");
308         doReportLocale(out);
309
310         header(out, "Proxy information");
311         doReportProxy(out);
312
313         out.println();
314     }
315
316     private static void header(PrintStream JavaDoc out, String JavaDoc section) {
317         out.println();
318         out.println("-------------------------------------------");
319         out.print(" ");
320         out.println(section);
321         out.println("-------------------------------------------");
322     }
323
324     /**
325      * Report a listing of system properties existing in the current vm.
326      * @param out the stream to print the properties to.
327      */

328     private static void doReportSystemProperties(PrintStream JavaDoc out) {
329         Properties JavaDoc sysprops = null;
330         try {
331             sysprops = System.getProperties();
332         } catch (SecurityException JavaDoc e) {
333             ignoreThrowable(e);
334             out.println("Access to System.getProperties() blocked "
335                     + "by a security manager");
336         }
337         for (Enumeration JavaDoc keys = sysprops.propertyNames();
338             keys.hasMoreElements();) {
339             String JavaDoc key = (String JavaDoc) keys.nextElement();
340             String JavaDoc value = getProperty(key);
341             out.println(key + " : " + value);
342         }
343     }
344
345     /**
346      * Get the value of a system property. If a security manager
347      * blocks access to a property it fills the result in with an error
348      * @param key
349      * @return the system property's value or error text
350      * @see #ERROR_PROPERTY_ACCESS_BLOCKED
351      */

352     private static String JavaDoc getProperty(String JavaDoc key) {
353         String JavaDoc value;
354         try {
355             value = System.getProperty(key);
356         } catch (SecurityException JavaDoc e) {
357             value = ERROR_PROPERTY_ACCESS_BLOCKED;
358         }
359         return value;
360     }
361
362     /**
363      * Report the content of ANT_HOME/lib directory
364      * @param out the stream to print the content to
365      */

366     private static void doReportAntProperties(PrintStream JavaDoc out) {
367         Project p = new Project();
368         p.initProperties();
369         out.println(MagicNames.ANT_VERSION + ": " + p.getProperty(MagicNames.ANT_VERSION));
370         out.println(MagicNames.ANT_JAVA_VERSION + ": "
371                     + p.getProperty(MagicNames.ANT_JAVA_VERSION));
372         out.println(MagicNames.ANT_LIB + ": " + p.getProperty(MagicNames.ANT_LIB));
373         out.println(MagicNames.ANT_HOME + ": " + p.getProperty(MagicNames.ANT_HOME));
374     }
375
376     /**
377      * Report the content of ANT_HOME/lib directory
378      * @param out the stream to print the content to
379      */

380     private static void doReportAntHomeLibraries(PrintStream JavaDoc out) {
381         out.println(MagicNames.ANT_HOME + ": " + System.getProperty(MagicNames.ANT_HOME));
382         File JavaDoc[] libs = listLibraries();
383         printLibraries(libs, out);
384     }
385
386     /**
387      * Report the content of ~/.ant/lib directory
388      *
389      * @param out the stream to print the content to
390      */

391     private static void doReportUserHomeLibraries(PrintStream JavaDoc out) {
392         String JavaDoc home = System.getProperty(Launcher.USER_HOMEDIR);
393         out.println("user.home: " + home);
394         File JavaDoc libDir = new File JavaDoc(home, Launcher.USER_LIBDIR);
395         File JavaDoc[] libs = listJarFiles(libDir);
396         printLibraries(libs, out);
397     }
398
399     /**
400      * list the libraries
401      * @param libs array of libraries (can be null)
402      * @param out output stream
403      */

404     private static void printLibraries(File JavaDoc[] libs, PrintStream JavaDoc out) {
405         if (libs == null) {
406             out.println("No such directory.");
407             return;
408         }
409         for (int i = 0; i < libs.length; i++) {
410             out.println(libs[i].getName()
411                     + " (" + libs[i].length() + " bytes)");
412         }
413     }
414
415
416     /**
417      * Call org.apache.env.Which if available
418      * @param out the stream to print the content to.
419      */

420     private static void doReportWhich(PrintStream JavaDoc out) {
421         Throwable JavaDoc error = null;
422         try {
423             Class JavaDoc which = Class.forName("org.apache.env.Which");
424             Method JavaDoc method
425                 = which.getMethod("main", new Class JavaDoc[]{String JavaDoc[].class});
426             method.invoke(null, new Object JavaDoc[]{new String JavaDoc[]{}});
427         } catch (ClassNotFoundException JavaDoc e) {
428             out.println("Not available.");
429             out.println("Download it at http://xml.apache.org/commons/");
430         } catch (InvocationTargetException JavaDoc e) {
431             error = e.getTargetException() == null ? e : e.getTargetException();
432         } catch (Throwable JavaDoc e) {
433             error = e;
434         }
435         // report error if something weird happens...this is diagnostic.
436
if (error != null) {
437             out.println("Error while running org.apache.env.Which");
438             error.printStackTrace();
439         }
440     }
441
442     /**
443      * Create a report about non-available tasks that are defined in the
444      * mapping but could not be found via lookup. It might generally happen
445      * because Ant requires multiple libraries to compile and one of them
446      * was missing when compiling Ant.
447      * @param out the stream to print the tasks report to
448      * <tt>null</tt> for a missing stream (ie mapping).
449      */

450     private static void doReportTasksAvailability(PrintStream JavaDoc out) {
451         InputStream JavaDoc is = Main.class.getResourceAsStream(
452                 MagicNames.TASKDEF_PROPERTIES_RESOURCE);
453         if (is == null) {
454             out.println("None available");
455         } else {
456             Properties JavaDoc props = new Properties JavaDoc();
457             try {
458                 props.load(is);
459                 for (Enumeration JavaDoc keys = props.keys(); keys.hasMoreElements();) {
460                     String JavaDoc key = (String JavaDoc) keys.nextElement();
461                     String JavaDoc classname = props.getProperty(key);
462                     try {
463                         Class.forName(classname);
464                         props.remove(key);
465                     } catch (ClassNotFoundException JavaDoc e) {
466                         out.println(key + " : Not Available "
467                                 + "(the implementation class is not present)");
468                     } catch (NoClassDefFoundError JavaDoc e) {
469                         String JavaDoc pkg = e.getMessage().replace('/', '.');
470                         out.println(key + " : Missing dependency " + pkg);
471                     } catch (LinkageError JavaDoc e) {
472                         out.println(key + " : Initialization error");
473                     }
474                 }
475                 if (props.size() == 0) {
476                     out.println("All defined tasks are available");
477                 } else {
478                     out.println("A task being missing/unavailable should only "
479                             + "matter if you are trying to use it");
480                 }
481             } catch (IOException JavaDoc e) {
482                 out.println(e.getMessage());
483             }
484         }
485     }
486
487     /**
488      * tell the user about the XML parser
489      * @param out
490      */

491     private static void doReportParserInfo(PrintStream JavaDoc out) {
492         String JavaDoc parserName = getXmlParserName();
493         String JavaDoc parserLocation = getXMLParserLocation();
494         printParserInfo(out, "XML Parser", parserName, parserLocation);
495         printParserInfo(out, "Namespace-aware parser",
496                 getNamespaceParserName(),
497                 getNamespaceParserLocation());
498     }
499
500     private static void printParserInfo(PrintStream JavaDoc out,
501                                         String JavaDoc parserType,
502                                         String JavaDoc parserName,
503                                         String JavaDoc parserLocation) {
504         if (parserName == null) {
505             parserName = "unknown";
506         }
507         if (parserLocation == null) {
508             parserLocation = "unknown";
509         }
510         out.println(parserType + " : " + parserName);
511         out.println(parserType + " Location: " + parserLocation);
512     }
513
514     /**
515      * try and create a temp file in our temp dir; this
516      * checks that it has space and access.
517      * We also do some clock reporting.
518      * @param out
519      */

520     private static void doReportTempDir(PrintStream JavaDoc out) {
521         String JavaDoc tempdir = System.getProperty("java.io.tmpdir");
522         if (tempdir == null) {
523             out.println("Warning: java.io.tmpdir is undefined");
524             return;
525         }
526         out.println("Temp dir is " + tempdir);
527         File JavaDoc tempDirectory = new File JavaDoc(tempdir);
528         if (!tempDirectory.exists()) {
529             out.println("Warning, java.io.tmpdir directory does not exist: "
530                     + tempdir);
531             return;
532         }
533         //create the file
534
long now = System.currentTimeMillis();
535         File JavaDoc tempFile = null;
536         FileOutputStream JavaDoc fileout = null;
537         try {
538             tempFile = File.createTempFile("diag", "txt", tempDirectory);
539             //do some writing to it
540
fileout = new FileOutputStream JavaDoc(tempFile);
541             byte[] buffer = new byte[KILOBYTE];
542             for (int i = 0; i < TEST_FILE_SIZE; i++) {
543                 fileout.write(buffer);
544             }
545             fileout.close();
546             fileout = null;
547             long filetime = tempFile.lastModified();
548             tempFile.delete();
549             out.println("Temp dir is writeable");
550             long drift = filetime - now;
551             out.println("Temp dir alignment with system clock is " + drift + " ms");
552             if (Math.abs(drift) > BIG_DRIFT_LIMIT) {
553                 out.println("Warning: big clock drift -maybe a network filesystem");
554             }
555         } catch (IOException JavaDoc e) {
556             ignoreThrowable(e);
557             out.println("Failed to create a temporary file in the temp dir "
558                 + tempdir);
559             out.println("File " + tempFile + " could not be created/written to");
560         } finally {
561             FileUtils.close(fileout);
562             if (tempFile != null && tempFile.exists()) {
563                 tempFile.delete();
564             }
565         }
566     }
567
568     /**
569      * Report locale information
570      * @param out stream to print to
571      */

572     private static void doReportLocale(PrintStream JavaDoc out) {
573         //calendar stuff.
574
Calendar JavaDoc cal = Calendar.getInstance();
575         TimeZone JavaDoc tz = cal.getTimeZone();
576         out.println("Timezone " + tz.getDisplayName()
577                 + " offset=" + tz.getOffset(cal.get(Calendar.ERA),
578                         cal.get(Calendar.YEAR),
579                         cal.get(Calendar.MONTH),
580                         cal.get(Calendar.DAY_OF_MONTH),
581                         cal.get(Calendar.DAY_OF_WEEK),
582                         ((cal.get(Calendar.HOUR_OF_DAY) * MINUTES_PER_HOUR
583                          + cal.get(Calendar.MINUTE)) * SECONDS_PER_MINUTE
584                          + cal.get(Calendar.SECOND)) * SECONDS_PER_MILLISECOND
585                          + cal.get(Calendar.MILLISECOND)));
586     }
587
588     /**
589      * print a property name="value" pair if the property is set;
590      * print nothing if it is null
591      * @param out stream to print on
592      * @param key property name
593      */

594     private static void printProperty(PrintStream JavaDoc out, String JavaDoc key) {
595         String JavaDoc value = getProperty(key);
596         if (value != null) {
597             out.print(key);
598             out.print(" = ");
599             out.print('"');
600             out.print(value);
601             out.println('"');
602         }
603     }
604
605     /**
606      * Report proxy information
607      *
608      * @param out stream to print to
609      * @since Ant1.7
610      */

611     private static void doReportProxy(PrintStream JavaDoc out) {
612         printProperty(out, ProxySetup.HTTP_PROXY_HOST);
613         printProperty(out, ProxySetup.HTTP_PROXY_PORT);
614         printProperty(out, ProxySetup.HTTP_PROXY_USERNAME);
615         printProperty(out, ProxySetup.HTTP_PROXY_PASSWORD);
616         printProperty(out, ProxySetup.HTTP_NON_PROXY_HOSTS);
617         printProperty(out, ProxySetup.HTTPS_PROXY_HOST);
618         printProperty(out, ProxySetup.HTTPS_PROXY_PORT);
619         printProperty(out, ProxySetup.HTTPS_NON_PROXY_HOSTS);
620         printProperty(out, ProxySetup.FTP_PROXY_HOST);
621         printProperty(out, ProxySetup.FTP_PROXY_PORT);
622         printProperty(out, ProxySetup.FTP_NON_PROXY_HOSTS);
623         printProperty(out, ProxySetup.SOCKS_PROXY_HOST);
624         printProperty(out, ProxySetup.SOCKS_PROXY_PORT);
625         printProperty(out, ProxySetup.SOCKS_PROXY_USERNAME);
626         printProperty(out, ProxySetup.SOCKS_PROXY_PASSWORD);
627
628         if (JavaEnvUtils.getJavaVersionNumber() < 15) {
629             return;
630         }
631         printProperty(out, ProxySetup.USE_SYSTEM_PROXIES);
632         final String JavaDoc proxyDiagClassname
633             = "org.apache.tools.ant.util.java15.ProxyDiagnostics";
634         try {
635             Class JavaDoc proxyDiagClass = Class.forName(proxyDiagClassname);
636             Object JavaDoc instance = proxyDiagClass.newInstance();
637             out.println("Java1.5+ proxy settings:");
638             out.println(instance.toString());
639         } catch (ClassNotFoundException JavaDoc e) {
640             //not included, do nothing
641
} catch (IllegalAccessException JavaDoc e) {
642             //not included, do nothing
643
} catch (InstantiationException JavaDoc e) {
644             //not included, do nothing
645
} catch (NoClassDefFoundError JavaDoc e) {
646             // not included, to nothing
647
}
648     }
649
650 }
651
Popular Tags