Over a million developers have joined DZone.

Functional JarClassLoader - Warning, Really Awful

DZone's Guide to

Functional JarClassLoader - Warning, Really Awful

Free Resource
Some really awful functional style Java...

Note that this depends on a bunch of other classes in the playground namespace. If you actually want to use it ask me and I'll send you the source - I didn't really feel like snippetting all the needed code. 

package playground.library.classloader;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import playground.library.functional.FunctionalUtils;
import playground.library.functional.Pair;
import playground.library.functional.iterator.FilterIterator;
import playground.library.functional.iterator.IteratorTransformer;
import playground.library.functional.Predicate;
import playground.library.functional.Transformer;
import playground.library.functional.iterator.DelegatingIterator;
import playground.library.functional.iterator.LinkingIterator;
import playground.library.jar.JarEntryIterator;
import playground.library.utils.IteratorUtils;
import playground.library.utils.IOUtils;

 * ClassLoader for loading from Jar files.
 * @author david
public class JarClassLoader extends ClassLoader
    public JarClassLoader(ClassLoader parent) { super(parent); }    
    public JarClassLoader()                   { super(); }
    private final List
        files = new ArrayList
     * Provides an iterator over all pairs of (file, entry) of JarFiles associated
     * with this class loader and entries of those jar files.
    private Iterator
     > getResources(){
        return new LinkingIterator
            new IteratorTransformer
                new Transformer
                public Iterator
         > transform(JarFile file){
                    return FunctionalUtils.merge(file, new JarEntryIterator(file));}})
     * Searches through the available jar files to try and find a class with the given name.
    protected Class
          findClass(String name) throws ClassNotFoundException{
        final Iterator
          > resources = this.getResources();
        while (resources.hasNext()){
            final Pair
            resource = resources.next();
                    try { return this.load(resource.first.getInputStream(resource.second));}
                    catch (IOException e) { e.printStackTrace(); }}}
        throw new ClassNotFoundException();}
     * Loads the contents of the InputStream as a class. This doesn't validate
     * the contents, so will fail messily if you pass it something that isn't a
     * valid class file.
    private Class
            load(final InputStream input){
        try {
            final ByteArrayOutputStream output = new ByteArrayOutputStream();
            final byte[] bytes = IOUtils.copy(input, new ByteArrayOutputStream()).toByteArray();
            return this.defineClass(null, bytes, 0, bytes.length); }
        catch (IOException e){ throw new RuntimeException(e); }
            try{ input.close(); }
            catch (IOException e){ throw new RuntimeException(e);}}}
     * Provides an iterator which lazily loads the contents of the jar file as
     * classes. Will also register the jar file with the class loader's file list.
     * When the iterator is exhausted the jar file will be removed from the file list.
    public Iterator
            > load(final JarFile file) throws IOException{
            new DelegatingIterator
                new IteratorTransformer
                    new Transformer
                        public Class transform(JarEntry stream){
                            InputStream fileStream = null;

                            try{return JarClassLoader.this.load(fileStream = file.getInputStream(stream)); }
                            catch(IOException e){throw new RuntimeException(e);}
                            finally{IOUtils.close(fileStream); }}})
                    new FilterIterator( 
                       new Predicate
                           public boolean satisfies(JarEntry entry){
                               return entry.getName().endsWith(".class");}},
                       new JarEntryIterator(file)))){
                public Class
                    final Class
                 clazz = super.next();
                    if (!this.hasNext()) JarClassLoader.this.files.remove(file);                    
                    return clazz;}
                public boolean hasNext(){
                    final boolean hasNext = super.hasNext();
                    if (!hasNext) JarClassLoader.this.files.remove(file);
                    return hasNext;}};}

     * Loads all class files from the jar and returns a set of them.
    public Set
                 > loadAll(final JarFile file) throws IOException
        return IteratorUtils.fill(new HashSet
                  >(), this.load(file));


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}