There is the task: I am not too sure if I am using the new ResourceCollection stuff correctly!
Peter /* * Copyright 2006 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs; import java.lang.reflect.Method; import java.util.Set; import java.util.HashSet; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.Reference; import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.ResourceCollection; import org.apache.tools.ant.types.resources.FileResource; import org.apache.tools.ant.types.resources.URLResource; import org.apache.tools.ant.util.FileUtils; /** * A Task to extend the project class path. * This task works by assuming that the project * classloader is a URLClassLoader (or derives * from URLClassloader), and by using reflection * to make the addURL method public. */ public class AppendProjectPath extends Task { private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); /** * URLS in the attributes and the nested elements */ private List urls = new ArrayList(); // --- fields used in the execute method --- /** * Set used to ensure that a URL is only used once */ private Set urlSet; /** * The addURL method on URLClassLoader */ private Method addURLMethod; /** * The classloader of the project class */ private URLClassLoader projectLoader; /** * A nested element class. The element is "url" and * it has one attribute - "url", this is a required * attribute. */ public static class URLElement { private String urlString; /** * Set the url. * * @param urlString the value to set. */ public void setURL(String urlString) { this.urlString = urlString; } /** * Get the url. * * @return the url string. */ public String getURL() { if (urlString == null) { throw new BuildException( "Missing required attribute url " + "for nested url element"); } return urlString; } } /** * Add a url to the list of urls. * This is an attribute of the task. * * @param urlString the value. */ public void setURL(String urlString) { URL url; try { url = new URL(urlString); } catch (Exception ex) { throw new BuildException( "Unable to convert to URL " + urlString); } urls.add(url); } /** * Handle a nested url element. * Get the url from it and call setURL to add to the * list of URLs. * * @param el the nested url element. */ public void addConfiguredURL(URLElement el) { String urlString = el.getURL(); setURL(urlString); } /** * Handle a nested resource collection. * Get the pathelements for the path, convert * them to url strings and call setURL to add * them to the list of urls. * * @param collection a nested path element. */ public void addConfigured(ResourceCollection collection) { for (Iterator iter = collection.iterator(); iter.hasNext();) { Resource r = (Resource) iter.next(); if (r instanceof FileResource) { FileResource file = (FileResource) r; String filePath = file.toString(); try { setURL(FILE_UTILS.toURI(file.toString())); } catch (Exception ex) { throw new BuildException( "Unable to convert to URL " + filePath); } } else if (r instanceof URLResource) { URLResource urlResource = (URLResource) r; urls.add(urlResource.getURL()); } else if (r.isReference()) { addConfigured(r); } else { throw new BuildException( "Do not know how do deal with " + r.getClass()); } } } /** * Handle the "path" attribute. * This converts the path string to a Path object * and uses addConfigured(Path) to add the URLs. * * @param path a path string. */ public void setPath(String path) { addConfigured(new Path(getProject(), path)); } /** * Handle the "pathref" attribute. * This method adds the path referenced by the reference. * * @param ref a reference to an existing path. */ public void setPathRef(Reference ref) { Path path = new Path(getProject()); path.setRefid(ref); addConfigured(path); } /** * The execute method for the task. * This gets the addURL method, gets the project classloader, * iterates over the urls and appends them to the project classloader. */ public void execute() { this.urlSet = new HashSet(); this.addURLMethod = findAddURLMethod(); this.projectLoader = findProjectLoader(); populateCurrentURLS(); for (Iterator iter = urls.iterator(); iter.hasNext();) { appendURLToProject((URL) iter.next()); } } /** * Get the addURL method of the URLClassLoader class. * Change the accessiblity to true and return the method. * @return the addURL method. */ private Method findAddURLMethod() { try { addURLMethod = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class}); addURLMethod.setAccessible(true); } catch (SecurityException ex) { throw new BuildException( "Unable to setAccessible(true) for method addURL", ex); } catch (NoSuchMethodException ex) { throw new BuildException( "Unable to find the addURL method", ex); } return addURLMethod; } /** * Append a url to the project classloader using the * addURL method. If the url is alreaded added, do nothing. * @param url the url to append to the classloader. */ private void appendURLToProject(URL url) { if (!urlSet.add(url)) { return; } try { addURLMethod.invoke(projectLoader, new Object[]{url}); } catch (Exception ex) { throw new BuildException( "Unable to add URL " + url + " to the project classpath", ex); } } /** * Populate the set of urls in the project classloader. */ private void populateCurrentURLS() { URL[] urls = projectLoader.getURLs(); for (int i = 0; i < urls.length; ++i) { urlSet.add(urls[i]); } } /** * Get the classloader of the Project class * and check that it is a URLClassLoader. * @return the project classloader. * @throws BuildException if the project classlaoder is not a URLClassLoader. */ private URLClassLoader findProjectLoader() { ClassLoader loader = getProject().getClass().getClassLoader(); if (!(loader instanceof URLClassLoader)) { throw new BuildException( "project classloader is not a URLClassLoader"); } return (URLClassLoader) loader; } } On 9/12/06, Matt Benson <[EMAIL PROTECTED]> wrote:
The subject line is manually entered b/c I no longer have the mails from the original thread; I'm hoping the mail archive will do the right thing anyway. So (and I make no pretense that this isn't DIRECTLY related to my other thread)... Peter, what's the status of your simplified extension task prototype described here: http://marc.theaimsgroup.com/?l=ant-dev&m=115695299516537&w=2 ? Thanks, Matt __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]