Changeset 3966

Show
Ignore:
Timestamp:
28/09/08 20:49:05 (3 years ago)
Author:
michael
Message:

Changes to support deploying as an OSGi bundle.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/build.properties

    r3739 r3966  
    11project.name=xtc 
    2 project.rev=0.4.4 
     2project.rev=0.5 
    33project.status=release 
  • trunk/build.xml

    r3739 r3966  
    2828                                <exclude name="org/sarugo/xtc/restlet/**/*.class" /> 
    2929                        </fileset> 
    30                         <fileset dir="${build.dir}/main/resources" /> 
     30                        <fileset dir="${build.dir}/main/resources"> 
     31                                <exclude name="META-INF/MANIFEST.MF" /> 
     32                        </fileset> 
    3133                </jar> 
    3234                <jar destfile="${dist.dir}/${project.name}-restlet-${build.rev}.jar"> 
     
    4042                        </fileset> 
    4143                </jar> 
     44        <ivy:retrieve pattern="${build.dir}/main/osgi/[artifact]-[revision].[ext]" conf="osgi" useOrigin="true" /> 
     45        <jar destfile="${dist.dir}/${project.name}-osgi-${build.rev}.jar" filesetmanifest="merge"> 
     46            <fileset dir="${build.dir}/main/java" /> 
     47            <fileset dir="${build.dir}/main/resources" /> 
     48            <fileset dir="${build.dir}/main/osgi" /> 
     49        </jar> 
    4250                <!-- Use ivy to copy the runtime dependencies to distribution directory --> 
    4351                <ivy:retrieve pattern="${dist.dir}/[artifact]-[revision].[ext]" conf="default" useOrigin="true" /> 
  • trunk/ivy.xml

    r3739 r3966  
    77    <conf name="restlet" description="XTC-Restlet integration" extends="default"/> 
    88    <conf name="fop" description="Apache FOP integration" extends="restlet"/> 
     9    <conf name="osgi" description="OSGi Bundle version"/> 
    910    <conf name="compile" visibility="private" extends="default,restlet,fop"/> 
    1011    <conf name="test" visibility="private" extends="compile"/> 
     
    1415        <artifact name="${project.name}-restlet" conf="restlet" /> 
    1516        <artifact name="${project.name}-fop" conf="fop" /> 
     17    <artifact name="${project.name}-osgi" conf="osgi" /> 
    1618  </publications> 
    1719  <dependencies> 
    18     <dependency org="de.odysseus.juel" name="juel" rev="2.1.0" conf="default"/> 
    19     <dependency org="org.restlet" name="org.restlet" rev="1.1-M2" conf="restlet,compile->default"/> 
    20     <dependency org="com.noelios.restlet" name="com.noelios.restlet.ext.simple" rev="1.1-M2" conf="compile->default"/> 
     20    <dependency org="de.odysseus.juel" name="juel" rev="2.1.0" conf="default,osgi->default"/> 
     21    <dependency org="org.restlet" name="org.restlet" rev="1.1-RC1" conf="restlet,compile->default"/> 
     22    <dependency org="com.noelios.restlet" name="com.noelios.restlet.ext.jetty" rev="1.1-RC1" conf="compile->default"/> 
    2123    <dependency org="javax.servlet" name="servlet-api" rev="2.5" conf="compile->default" /> 
    22     <dependency org="com.noelios.restlet" name="com.noelios.restlet.ext.net" rev="1.1-M2" conf="test->default"/> 
     24    <dependency org="com.noelios.restlet" name="com.noelios.restlet.ext.net" rev="1.1-RC1" conf="test->default"/> 
    2325    <dependency org="junit" name="junit" rev="3.8.1" conf="test->default"/> 
    2426    <dependency org="xmlunit" name="xmlunit" rev="1.0" conf="test->default"/> 
     
    2628      <!-- TODO exclude un-needed dependencies --> 
    2729    </dependency> 
     30    <dependency org="org.eclipse" name="osgi" rev="3.4.0.v20080605-1900" conf="compile->default"/> 
    2831  </dependencies> 
    2932</ivy-module> 
  • trunk/src/main/java/org/sarugo/xtc/Resolver.java

    r3011 r3966  
    11package org.sarugo.xtc; 
    22 
     3import java.io.File; 
     4import java.io.IOException; 
     5import java.io.InputStream; 
     6import java.net.JarURLConnection; 
    37import java.net.URL; 
     8import java.net.URLConnection; 
     9import java.util.Arrays; 
     10import java.util.Collection; 
     11import java.util.Enumeration; 
     12import java.util.HashSet; 
     13import java.util.List; 
     14import java.util.Set; 
     15import java.util.jar.JarEntry; 
     16import java.util.jar.JarFile; 
    417 
    518/** 
    6  * The resolver is used by a {@link TemplateFactory} to load resources. 
     19 * The resolver is used to load resources and classes. 
    720 *  
    8  * The default resolver for the default factory uses the class loader
     21 * The default resolver for uses the available class loaders
    922 *  
    1023 * @author Michael Terrington 
    1124 */ 
    12 public interface Resolver { 
     25public class Resolver { 
    1326 
    14         public URL resolveUrl(String path); 
     27        private ClassLoader userClassLoader; 
     28 
     29        public URL getResource(String name) { 
     30                URL result = null; 
     31                for (ClassLoader cl : getClassLoaders()) { 
     32                        if (cl == null) 
     33                                continue; 
     34                        result = cl.getResource(name); 
     35                        if (result != null) 
     36                                break; 
     37                } 
     38                return result; 
     39        } 
     40 
     41        public InputStream getResourceAsStream(String name) { 
     42                InputStream result = null; 
     43                for (ClassLoader cl : getClassLoaders()) { 
     44                        if (cl == null) 
     45                                continue; 
     46                        result = cl.getResourceAsStream(name); 
     47                        if (result != null) 
     48                                break; 
     49                } 
     50                return result; 
     51        } 
     52 
     53        public Collection<URL> search(String prefix, String suffix) 
     54                        throws IOException { 
     55                Set<URL> results = new HashSet<URL>(); 
     56                for (ClassLoader cl : getClassLoaders()) { 
     57                        if (cl == null) 
     58                                continue; 
     59                        search(results, cl, prefix, suffix); 
     60                } 
     61                return results; 
     62        } 
     63 
     64        public Class<?> loadClass(String name) throws ClassNotFoundException { 
     65                Class<?> result = null; 
     66                try { 
     67                        result = Class.forName(name); 
     68                } catch (ClassNotFoundException e) { 
     69                        // ignore 
     70                } 
     71                for (ClassLoader cl : getClassLoaders()) { 
     72                        if (cl == null) 
     73                                continue; 
     74                        try { 
     75                                result = cl.loadClass(name); 
     76                                break; 
     77                        } catch (ClassNotFoundException e) { 
     78                                // ignore 
     79                        } 
     80                } 
     81                if (result == null) { 
     82                        throw new ClassNotFoundException(name); 
     83                } 
     84                return result; 
     85        } 
     86 
     87        public void setUserClassLoader(ClassLoader cl) { 
     88                this.userClassLoader = cl; 
     89        } 
     90 
     91        protected List<ClassLoader> getClassLoaders() { 
     92                return Arrays.asList(userClassLoader, Thread.currentThread() 
     93                                .getContextClassLoader(), getClass().getClassLoader(), 
     94                                ClassLoader.getSystemClassLoader()); 
     95        } 
     96 
     97        protected URL localise(URL url) { 
     98                return url; 
     99        } 
     100 
     101        private void search(Collection<URL> results, ClassLoader cl, String prefix, 
     102                        String suffix) throws IOException { 
     103                Enumeration<URL> e = cl.getResources(prefix); 
     104                URL url; 
     105                URLConnection conn; 
     106                JarFile jarFile; 
     107                while (e.hasMoreElements()) { 
     108                        url = localise((URL) e.nextElement()); 
     109                        conn = url.openConnection(); 
     110                        conn.setUseCaches(false); 
     111                        conn.setDefaultUseCaches(false); 
     112                        if (conn instanceof JarURLConnection) { 
     113                                jarFile = ((JarURLConnection) conn).getJarFile(); 
     114                        } else { 
     115                                jarFile = getAlternativeJarFile(url); 
     116                        } 
     117                        if (jarFile != null) { 
     118                                searchJar(cl, results, jarFile, prefix, suffix); 
     119                        } else { 
     120                                searchDir(results, new File(url.getFile()), suffix); 
     121                        } 
     122                } 
     123        } 
     124 
     125        private static void searchDir(Collection<URL> result, File file, 
     126                        String suffix) throws IOException { 
     127                if (file.exists() && file.isDirectory()) { 
     128                        File[] fc = file.listFiles(); 
     129                        String path; 
     130                        for (int i = 0; i < fc.length; i++) { 
     131                                path = fc[i].getAbsolutePath(); 
     132                                if (fc[i].isDirectory()) { 
     133                                        searchDir(result, fc[i], suffix); 
     134                                } else if (path.endsWith(suffix)) { 
     135                                        // result.add(new URL("file:/" + path)); 
     136                                        result.add(fc[i].toURI().toURL()); 
     137                                } 
     138                        } 
     139                } 
     140        } 
     141 
     142        /** 
     143         * For URLs to JARs that do not use JarURLConnection - allowed by the 
     144         * servlet spec - attempt to produce a JarFile object all the same. Known 
     145         * servlet engines that function like this include Weblogic and OC4J. This 
     146         * is not a full solution, since an unpacked WAR or EAR will not have JAR 
     147         * "files" as such. 
     148         */ 
     149        private static JarFile getAlternativeJarFile(URL url) throws IOException { 
     150                String urlFile = url.getFile(); 
     151                // Trim off any suffix - which is prefixed by "!/" on Weblogic 
     152                int separatorIndex = urlFile.indexOf("!/"); 
     153 
     154                // OK, didn't find that. Try the less safe "!", used on OC4J 
     155                if (separatorIndex == -1) { 
     156                        separatorIndex = urlFile.indexOf('!'); 
     157                } 
     158 
     159                if (separatorIndex != -1) { 
     160                        String jarFileUrl = urlFile.substring(0, separatorIndex); 
     161                        // And trim off any "file:" prefix. 
     162                        if (jarFileUrl.startsWith("file:")) { 
     163                                jarFileUrl = jarFileUrl.substring("file:".length()); 
     164                        } 
     165                        return new JarFile(jarFileUrl); 
     166                } 
     167                return null; 
     168        } 
     169 
     170        private static void searchJar(ClassLoader cl, Collection<URL> result, 
     171                        JarFile file, String prefix, String suffix) throws IOException { 
     172                Enumeration<JarEntry> e = file.entries(); 
     173                JarEntry entry; 
     174                String name; 
     175                while (e.hasMoreElements()) { 
     176                        try { 
     177                                entry = e.nextElement(); 
     178                        } catch (Throwable t) { 
     179                                continue; 
     180                        } 
     181                        name = entry.getName(); 
     182                        if (name.startsWith(prefix) && name.endsWith(suffix)) { 
     183                                Enumeration<URL> e2 = cl.getResources(name); 
     184                                while (e2.hasMoreElements()) { 
     185                                        result.add(e2.nextElement()); 
     186                                } 
     187                        } 
     188                } 
     189        } 
    15190 
    16191} 
  • trunk/src/main/java/org/sarugo/xtc/TemplateFactory.java

    r3011 r3966  
    3131public abstract class TemplateFactory { 
    3232 
     33        private static volatile Resolver resolver = new Resolver(); 
     34 
    3335        private static ThreadLocal<TemplateFactory> instance = new ThreadLocal<TemplateFactory>(); 
    3436 
     
    3840         * Return a Template instance as specified by the file at the passed URI. 
    3941         * The {@link DefaultTemplateFactory default implementation} of this class 
    40          * resolves URI's beginning with "/" using the classloader. 
     42         * resolves URI's beginning with "/" using the 
     43         * {@link #setResolver(Resolver) resolver}. 
    4144         *  
    4245         * @param uri 
     
    5255        public abstract Template getTemplate(String uri) throws IOException, 
    5356                        TemplateException, ELException; 
     57 
     58        /** 
     59         * Specifies the period after which templates should be checked for changes. 
     60         *  
     61         * @param refreshPeriod 
     62         *            length of time in milliseconds. 
     63         */ 
     64        public abstract void setRefreshPeriod(long refreshPeriod); 
    5465 
    5566        /** 
     
    8596         * @param resolver 
    8697         */ 
    87         public abstract void setResolver(Resolver resolver); 
     98        public static void setResolver(Resolver resolver) { 
     99                TemplateFactory.resolver = resolver; 
     100        } 
     101 
     102        public static Resolver getResolver() { 
     103                return resolver; 
     104        } 
    88105 
    89106} 
  • trunk/src/main/java/org/sarugo/xtc/compiler/Compiler.java

    r2915 r3966  
    145145                if (type != null) { 
    146146                        try { 
    147                                 return Class.forName(type, true, 
    148                                                 Thread.currentThread().getContextClassLoader()) 
     147                                return TemplateFactory.getResolver().loadClass(type) 
    149148                                                .newInstance(); 
    150149                        } catch (Throwable t) { 
  • trunk/src/main/java/org/sarugo/xtc/compiler/ReflectionUtil.java

    r2684 r3966  
    1717import java.lang.reflect.Array; 
    1818import java.util.Arrays; 
     19 
     20import org.sarugo.xtc.TemplateFactory; 
    1921 
    2022/** 
     
    5052            if (name.endsWith("[]")) { 
    5153                String nc = name.substring(0, name.length() - 2); 
    52                 c = Class.forName(nc, true, Thread.currentThread().getContextClassLoader()); 
     54                c = TemplateFactory.getResolver().loadClass(nc); 
    5355                c = Array.newInstance(c, 0).getClass(); 
    5456            } else { 
    55                 c = Class.forName(name, true, Thread.currentThread().getContextClassLoader()); 
     57                c = TemplateFactory.getResolver().loadClass(name); 
    5658            } 
    5759        } 
  • trunk/src/main/java/org/sarugo/xtc/compiler/SAXCompiler.java

    r2915 r3966  
    2727import javax.xml.parsers.SAXParserFactory; 
    2828 
     29import org.sarugo.xtc.TemplateFactory; 
    2930import org.sarugo.xtc.TemplateException; 
    3031import org.sarugo.xtc.TemplateHandler; 
     
    151152                return new InputSource(systemId); 
    152153            }*/ 
    153             URL url = Thread.currentThread().getContextClassLoader() 
    154                     .getResource(dtd); 
     154            URL url = TemplateFactory.getResolver().getResource(dtd); 
    155155            return new InputSource(url.toString()); 
    156156        } 
  • trunk/src/main/java/org/sarugo/xtc/compiler/TagLibraryConfig.java

    r2915 r3966  
    1919import java.lang.reflect.Method; 
    2020import java.net.URL; 
     21import java.util.Collection; 
    2122import java.util.logging.Level; 
    2223import java.util.logging.Logger; 
     
    2627import javax.xml.parsers.SAXParserFactory; 
    2728 
     29import org.sarugo.xtc.TemplateFactory; 
    2830import org.sarugo.xtc.tag.AbstractTagLibrary; 
    2931import org.sarugo.xtc.tag.TagHandler; 
     
    239241            if ("-//Sarugo Pty. Ltd.//DTD XTC Taglib 1.0//EN" 
    240242                    .equals(publicId)) { 
    241                 URL url = Thread.currentThread().getContextClassLoader() 
     243                URL url = TemplateFactory.getResolver() 
    242244                        .getResource("xtc-taglib_1_0.dtd"); 
    243245                return new InputSource(url.toExternalForm()); 
     
    316318 
    317319    public void loadImplicit(Compiler compiler) throws IOException { 
    318         ClassLoader cl = Thread.currentThread().getContextClassLoader(); 
    319         URL[] urls = Classpath.search(cl, "META-INF/", SUFFIX); 
    320         for (int i = 0; i < urls.length; i++) { 
     320        Collection<URL> urls = TemplateFactory.getResolver().search("META-INF/", SUFFIX); 
     321        for (URL url: urls) { 
    321322            try { 
    322                 compiler.addTagLibrary(create(urls[i])); 
    323                 log.info("Added Library from: " + urls[i]); 
     323                compiler.addTagLibrary(create(url)); 
     324                log.info("Added Library from: " + url); 
    324325            } catch (Exception e) { 
    325                 log.log(Level.SEVERE, "Error Loading Library: " + urls[i], e); 
     326                log.log(Level.SEVERE, "Error Loading Library: " + url, e); 
    326327            } 
    327328        } 
  • trunk/src/main/java/org/sarugo/xtc/impl/DefaultTemplateFactory.java

    r3472 r3966  
    4949    private Map relativeLocations; 
    5050 
    51     private Resolver resolver; 
    52  
    5351    private long refreshPeriod; 
    5452 
    5553    public DefaultTemplateFactory() throws IOException { 
    56         this(Compiler.getInstance(), new ClassLoaderResolver()); 
    57     } 
    58  
    59     public DefaultTemplateFactory(Compiler compiler, Resolver resolver
     54        this(Compiler.getInstance()); 
     55    } 
     56 
     57    public DefaultTemplateFactory(Compiler compiler
    6058            throws IOException { 
    61         this(compiler, resolver, -1); 
    62     } 
    63  
    64     public DefaultTemplateFactory(Compiler compiler, Resolver resolver, 
    65             long refreshPeriod) { 
     59        this(compiler, -1); 
     60    } 
     61 
     62    public DefaultTemplateFactory(Compiler compiler, long refreshPeriod) { 
    6663        ParameterCheck.notNull("compiler", compiler); 
    67         ParameterCheck.notNull("resolver", resolver); 
    6864        this.compiler = compiler; 
    6965        this.templates = new HashMap(); 
    7066        this.relativeLocations = new HashMap(); 
    71         setResolver(resolver); 
    72         // this.location = url; 
    73         log.fine("Using ResourceResolver: " + resolver); 
    7467        this.refreshPeriod = (refreshPeriod > 0) ? refreshPeriod * 1000 : -1; 
    7568        log.fine("Using Refresh Period: " + this.refreshPeriod); 
    76     } 
    77  
    78     public void setResolver(Resolver resolver) { 
    79         this.resolver = resolver; 
    8069    } 
    8170 
     
    11099    public URL resolveURL(URL source, String path) throws IOException { 
    111100        if (path.startsWith("/")) { 
    112             URL url = this.resolver.resolveUrl(path); 
     101            URL url = getResolver().getResource(path); 
    113102            if (url == null) { 
    114103                throw new FileNotFoundException(path 
  • trunk/src/main/java/org/sarugo/xtc/restlet/fop/FOPRepresentation.java

    r3746 r3966  
    2424import org.restlet.data.MediaType; 
    2525import org.sarugo.xtc.Template; 
     26import org.sarugo.xtc.TemplateFactory; 
    2627import org.sarugo.xtc.restlet.TemplateRepresentation; 
    2728 
     
    4344                    if (href.startsWith("clap:")) { 
    4445                        String resource; 
    45                         ClassLoader loader; 
    46                         if (href.startsWith("clap://class/")) { 
    47                             resource = href.substring(13); 
    48                             loader = getClass().getClassLoader(); 
    49                         } else { 
     46                        if (!href.startsWith("clap://class/")) { 
    5047                            throw new TransformerException("Bad URI " + href); 
    5148                        } 
    52                         URL url = loader.getResource(resource); 
    53                         InputStream is = loader.getResourceAsStream(resource); 
     49                        resource = href.substring(13); 
     50                        URL url = TemplateFactory.getResolver().getResource(resource); 
     51                        InputStream is = TemplateFactory.getResolver().getResourceAsStream(resource); 
    5452                        if (url != null) { 
    5553                            return new StreamSource(is, url.toExternalForm()); 
  • trunk/src/main/java/org/sarugo/xtc/servlet/ServletResolver.java

    r3011 r3966  
    88import org.sarugo.xtc.Resolver; 
    99 
    10 public class ServletResolver implements Resolver { 
     10public class ServletResolver extends Resolver { 
    1111         
    1212        private ServletContext servletContext; 
     
    1616        } 
    1717 
    18         public URL resolveUrl(String path) { 
     18        @Override 
     19        public URL getResource(String name) { 
    1920                try { 
    20                         return servletContext.getResource(path); 
     21                        return servletContext.getResource(name); 
    2122                } catch (MalformedURLException e) { 
    2223                        return null; 
  • trunk/src/main/java/org/sarugo/xtc/util/Classpath.java

    r2783 r3966  
    4545                String providerClassName = null; 
    4646 
    47                 // Try the default classloader 
    48                 ClassLoader cl = TemplateFactory.class.getClassLoader(); 
    49                 URL configURL = cl.getResource(providerResource); 
    50  
    51                 if (configURL == null) { 
    52                         // Try the current thread's classloader 
    53                         cl = Thread.currentThread().getContextClassLoader(); 
    54                         configURL = cl.getResource(providerResource); 
    55                 } 
    56  
    57                 if (configURL == null) { 
    58                         // Try the system classloader 
    59                         cl = ClassLoader.getSystemClassLoader(); 
    60                         configURL = cl.getResource(providerResource); 
    61                 } 
     47                URL configURL = TemplateFactory.getResolver().getResource(providerResource); 
    6248 
    6349                if (configURL != null) { 
     
    9076                // Instantiate the provider 
    9177                if (providerClassName != null) { 
    92                         return Class.forName(providerClassName).newInstance(); 
     78                        return TemplateFactory.getResolver().loadClass(providerClassName).newInstance(); 
    9379                } else { 
    9480                        return null; 
     
    9682        } 
    9783 
    98         public static URL[] search(String prefix, String suffix) throws IOException { 
    99                 return search(Thread.currentThread().getContextClassLoader(), prefix, 
    100                                 suffix); 
    101         } 
    102  
    103         public static URL[] search(ClassLoader cl, String prefix, String suffix) 
    104                         throws IOException { 
    105                 Enumeration<URL> e = cl.getResources(prefix); 
    106                 Set<URL> all = new HashSet<URL>(); 
    107                 URL url; 
    108                 URLConnection conn; 
    109                 JarFile jarFile; 
    110                 while (e.hasMoreElements()) { 
    111                         url = (URL) e.nextElement(); 
    112                         conn = url.openConnection(); 
    113                         conn.setUseCaches(false); 
    114                         conn.setDefaultUseCaches(false); 
    115                         if (conn instanceof JarURLConnection) { 
    116                                 jarFile = ((JarURLConnection) conn).getJarFile(); 
    117                         } else { 
    118                                 jarFile = getAlternativeJarFile(url); 
    119                         } 
    120                         if (jarFile != null) { 
    121                                 searchJar(cl, all, jarFile, prefix, suffix); 
    122                         } else { 
    123                                 searchDir(all, new File(url.getFile()), suffix); 
    124                         } 
    125                 } 
    126                 URL[] urlArray = (URL[]) all.toArray(new URL[all.size()]); 
    127                 return urlArray; 
    128         } 
    129  
    130         private static void searchDir(Set<URL> result, File file, String suffix) 
    131                         throws IOException { 
    132                 if (file.exists() && file.isDirectory()) { 
    133                         File[] fc = file.listFiles(); 
    134                         String path; 
    135                         for (int i = 0; i < fc.length; i++) { 
    136                                 path = fc[i].getAbsolutePath(); 
    137                                 if (fc[i].isDirectory()) { 
    138                                         searchDir(result, fc[i], suffix); 
    139                                 } else if (path.endsWith(suffix)) { 
    140                                         // result.add(new URL("file:/" + path)); 
    141                                         result.add(fc[i].toURL()); 
    142                                 } 
    143                         } 
    144                 } 
    145         } 
    146  
    147         /** 
    148          * For URLs to JARs that do not use JarURLConnection - allowed by the 
    149          * servlet spec - attempt to produce a JarFile object all the same. Known 
    150          * servlet engines that function like this include Weblogic and OC4J. This 
    151          * is not a full solution, since an unpacked WAR or EAR will not have JAR 
    152          * "files" as such. 
    153          */ 
    154         private static JarFile getAlternativeJarFile(URL url) throws IOException { 
    155                 String urlFile = url.getFile(); 
    156                 // Trim off any suffix - which is prefixed by "!/" on Weblogic 
    157                 int separatorIndex = urlFile.indexOf("!/"); 
    158  
    159                 // OK, didn't find that. Try the less safe "!", used on OC4J 
    160                 if (separatorIndex == -1) { 
    161                         separatorIndex = urlFile.indexOf('!'); 
    162                 } 
    163  
    164                 if (separatorIndex != -1) { 
    165                         String jarFileUrl = urlFile.substring(0, separatorIndex); 
    166                         // And trim off any "file:" prefix. 
    167                         if (jarFileUrl.startsWith("file:")) { 
    168                                 jarFileUrl = jarFileUrl.substring("file:".length()); 
    169                         } 
    170                         return new JarFile(jarFileUrl); 
    171                 } 
    172                 return null; 
    173         } 
    174  
    175         private static void searchJar(ClassLoader cl, Set<URL> result, 
    176                         JarFile file, String prefix, String suffix) throws IOException { 
    177                 Enumeration e = file.entries(); 
    178                 JarEntry entry; 
    179                 String name; 
    180                 while (e.hasMoreElements()) { 
    181                         try { 
    182                                 entry = (JarEntry) e.nextElement(); 
    183                         } catch (Throwable t) { 
    184                                 continue; 
    185                         } 
    186                         name = entry.getName(); 
    187                         if (name.startsWith(prefix) && name.endsWith(suffix)) { 
    188                                 Enumeration<URL> e2 = cl.getResources(name); 
    189                                 while (e2.hasMoreElements()) { 
    190                                         result.add(e2.nextElement()); 
    191                                 } 
    192                         } 
    193                 } 
    194         } 
    19584 
    19685}