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