diff --git a/docs/manual/OptionalTasks/jdepend.html b/docs/manual/OptionalTasks/jdepend.html index 61d3893eb..54fcdf79c 100644 --- a/docs/manual/OptionalTasks/jdepend.html +++ b/docs/manual/OptionalTasks/jdepend.html @@ -71,6 +71,12 @@ href="#nested">nested elements.

The directory to invoke the VM in. (Ignored if fork is disabled) No + + includeruntime + Implicitly add the classes required to run jdepend + in forked mode. (Ignored if fork is disabled). Since ant 1.6. + No, default is "no". + classpathref the classpath to use, given as reference to a PATH defined elsewhere. diff --git a/src/etc/testcases/taskdefs/optional/jdepend/jdepend.xml b/src/etc/testcases/taskdefs/optional/jdepend/jdepend.xml new file mode 100644 index 000000000..fb468ce29 --- /dev/null +++ b/src/etc/testcases/taskdefs/optional/jdepend/jdepend.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java index 522aa9047..450aa3d9f 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java @@ -61,6 +61,7 @@ import java.io.PrintWriter; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Vector; +import java.util.Enumeration; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; @@ -73,6 +74,7 @@ import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.PatternSet; import org.apache.tools.ant.types.Reference; +import org.apache.tools.ant.util.LoaderUtils; /** * Runs JDepend tests. @@ -99,7 +101,7 @@ public class JDependTask extends Task { private Path compileClasspath; private boolean haltonerror = false; private boolean fork = false; - //private Integer _timeout = null; + private Long timeout = null; private String jvm = null; private String format = "text"; @@ -108,6 +110,9 @@ public class JDependTask extends Task { private static Constructor packageFilterC; private static Method setFilter; + private boolean includeRuntime = false; + private Path runtimeClasses = null; + static { try { Class packageFilter = @@ -124,15 +129,36 @@ public class JDependTask extends Task { } } - /* - public void setTimeout(Integer value) { - _timeout = value; - } + /** + * If true, + * include jdepend.jar in the forked VM. + * + * @param b include ant run time yes or no + * @since Ant 1.6 + */ + public void setIncluderuntime(boolean b) { + includeRuntime = b; + } + + /** + * Set the timeout value (in milliseconds). + * + *

If the operation is running for more than this value, the jdepend + * will be canceled. (works only when in 'fork' mode).

+ * @param value the maximum time (in milliseconds) allowed before + * declaring the test as 'timed-out' + * @see #setFork(boolean) + */ + public void setTimeout(Long value) { + timeout = value; + } - public Integer getTimeout() { - return _timeout; - } - */ + /** + * @return the timeout value + */ + public Long getTimeout() { + return timeout; + } /** * The output file name. @@ -350,6 +376,43 @@ public class JDependTask extends Task { */ private static final int ERRORS = 1; + /** + * Search for the given resource and add the directory or archive + * that contains it to the classpath. + * + *

Doesn't work for archives in JDK 1.1 as the URL returned by + * getResource doesn't contain the name of the archive.

+ * + * @param resource resource that one wants to lookup + * @since Ant 1.6 + */ + private void addClasspathEntry(String resource) { + /* + * pre Ant 1.6 this method used to call getClass().getResource + * while Ant 1.6 will call ClassLoader.getResource(). + * + * The difference is that Class.getResource expects a leading + * slash for "absolute" resources and will strip it before + * delegating to ClassLoader.getResource - so we now have to + * emulate Class's behavior. + */ + if (resource.startsWith("/")) { + resource = resource.substring(1); + } else { + resource = "org/apache/tools/ant/taskdefs/optional/jdepend/" + + resource; + } + + File f = LoaderUtils.getResourceSource(getClass().getClassLoader(), + resource); + if (f != null) { + log("Found " + f.getAbsolutePath(), Project.MSG_DEBUG); + runtimeClasses.createPath().setLocation(f); + } else { + log("Couldn\'t find " + resource, Project.MSG_DEBUG); + } + } + /** * execute the task * @@ -380,7 +443,7 @@ public class JDependTask extends Task { // execute the test and get the return code int exitValue = JDependTask.ERRORS; - //boolean wasKilled = false; + boolean wasKilled = false; if (!getFork()) { exitValue = executeInVM(commandline); } else { @@ -388,21 +451,22 @@ public class JDependTask extends Task { exitValue = executeAsForked(commandline, watchdog); // null watchdog means no timeout, you'd better not check with null if (watchdog != null) { - //info will be used in later version do nothing for now - //wasKilled = watchdog.killedProcess(); + wasKilled = watchdog.killedProcess(); } } // if there is an error/failure and that it should halt, stop // everything otherwise just log a statement - boolean errorOccurred = exitValue == JDependTask.ERRORS; + boolean errorOccurred = exitValue == JDependTask.ERRORS || wasKilled; if (errorOccurred) { + String errorMessage = "JDepend FAILED" + + (wasKilled ? " - Timed out" : ""); + if (getHaltonerror()) { - throw new BuildException("JDepend failed", - getLocation()); + throw new BuildException(errorMessage, getLocation()); } else { - log("JDepend FAILED", Project.MSG_ERR); + log(errorMessage, Project.MSG_ERR); } } } @@ -540,6 +604,9 @@ public class JDependTask extends Task { // JL: comment extracted from JUnitTask (and slightly modified) public int executeAsForked(CommandlineJava commandline, ExecuteWatchdog watchdog) throws BuildException { + runtimeClasses = new Path(getProject()); + addClasspathEntry("/jdepend/textui/JDepend.class"); + // if not set, auto-create the ClassPath from the project createClasspath(); @@ -550,6 +617,24 @@ public class JDependTask extends Task { createJvmarg(commandline).setValue(getClasspath().toString()); } + if (includeRuntime) { + Vector v = Execute.getProcEnvironment(); + Enumeration e = v.elements(); + while (e.hasMoreElements()) { + String s = (String) e.nextElement(); + if (s.startsWith("CLASSPATH=")) { + commandline.createClasspath(getProject()).createPath() + .append(new Path(getProject(), + s.substring("CLASSPATH=".length() + ))); + } + } + log("Implicitly adding " + runtimeClasses + " to CLASSPATH", + Project.MSG_VERBOSE); + commandline.createClasspath(getProject()).createPath() + .append(runtimeClasses); + } + if (getOutputFile() != null) { // having a space between the file and its path causes commandline // to add quotes around the argument thus making JDepend not taking @@ -620,13 +705,9 @@ public class JDependTask extends Task { * @throws BuildException in case of error */ protected ExecuteWatchdog createWatchdog() throws BuildException { - - return null; - /* - if (getTimeout() == null) { - return null; - } - return new ExecuteWatchdog(getTimeout().intValue()); - */ + if (getTimeout() == null) { + return null; + } + return new ExecuteWatchdog(getTimeout().longValue()); } } diff --git a/src/testcases/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTest.java b/src/testcases/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTest.java new file mode 100644 index 000000000..b745474b9 --- /dev/null +++ b/src/testcases/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTest.java @@ -0,0 +1,155 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2003 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "Ant" and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.taskdefs.optional.jdepend; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Date; +import java.util.Vector; +import java.util.Enumeration; +import java.util.Hashtable; +import org.apache.tools.ant.BuildFileTest; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.DirectoryScanner; + +/** + * Testcase for the JDepend optional task. + * + * @author Peter Reilly + */ +public class JDependTest extends BuildFileTest { + public static final String RESULT_FILESET = "result"; + + public JDependTest(String name) { + super(name); + } + + public void setUp() { + configureProject( + "src/etc/testcases/taskdefs/optional/jdepend/jdepend.xml"); + } + + /** + * Test simple + */ + public void testSimple() { + expectOutputContaining( + "simple", "Package: org.apache.tools.ant.util.facade"); + } + + /** + * Test xml + */ + public void testXml() { + expectOutputContaining( + "xml", "java.lang"); + } + + /** + * Test fork + * - forked output goes to log + */ + public void testFork() { + expectLogContaining( + "fork", "Package: org.apache.tools.ant.util.facade"); + } + + /** + * Test fork xml + */ + public void testForkXml() { + expectLogContaining( + "fork-xml", "java.lang"); + } + + /** + * Test timeout + */ + public void testTimeout() { + expectLogContaining( + "fork-timeout", "JDepend FAILED - Timed out"); + } + + + /** + * Test timeout without timing out + */ + public void testTimeoutNot() { + expectLogContaining( + "fork-timeout-not", "Package: org.apache.tools.ant.util.facade"); + } + + /** + * Assert that the given substring is in the output messages + */ + + protected void assertOutputContaining(String substring) { + String realOutput = getOutput(); + assertTrue("expecting output to contain \"" + substring + "\" output was \"" + + realOutput + "\"", + realOutput.indexOf(substring) >= 0); + } + + /** + * Assert that the given message has been outputted + */ + protected void expectOutputContaining(String target, String substring) { + executeTarget(target); + assertOutputContaining(substring); + } + +}