import org.apache.log4j.Logger;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
* Packages loading tool
* 
* @author nikelin
*/
public class PackageLoader {
    private static final Logger log = Logger.getLogger( PackageLoader.class );

    public <T> Class<T>[] getClasses( String pkgName ) throws PackageLoaderException {
        return this.getClasses( pkgName, new InterfacesFilter( new Class[] {} ) );
    }

    public <T> Class<T>[] getClasses( String pkgName, Filter filter ) throws PackageLoaderException {
        Set<Class<T>> classes = new HashSet<Class<T>>();
        for ( String path : System.getProperty("java.class.path").split(":") ) {
            try {
                Class<T>[] collectionPart = this.getClasses( path, pkgName, filter );
                if ( collectionPart != null ) {
                    classes.addAll( Arrays.asList( collectionPart ) );
                }
            } catch ( PackageLoaderException e ) {
                continue;
            }
        }

        return classes.toArray( new Class[classes.size()] );
    }

    public <T> Class<T>[] getClasses( String path, String pkgName ) throws PackageLoaderException {
        return this.getClasses( path, pkgName, new InterfacesFilter( new Class[] {}  ) );
    }

    public <T> Class<T>[] getClasses( String path, String pkgName, Filter filter ) throws PackageLoaderException {
        if ( path.endsWith(".jar") ) {
            return this.getClassesFromJar( path, pkgName, filter );
        } else {
            return this.getClassesFromIdle( path, pkgName, filter );
        }
    }

    protected <T> Class<T>[] getClassesFromJar( String path, String pkgName, Filter filter ) throws PackageLoaderException {
        try {
            String folderName = this.convertToFolderName( pkgName );

            JarFile file = new JarFile( path );
            Enumeration entries = file.entries();
            List<URL> targetEntries = new ArrayList<URL>() ;
            while( entries.hasMoreElements() ) {
                JarEntry testing = (JarEntry) entries.nextElement();

                if ( testing.getName().contains(folderName) &&
                        !testing.isDirectory() ) {
                    if ( testing.getName().endsWith(".class") )  {
                        targetEntries.add( new URL("jar", path + "!/",  testing.getName() ) );
                    }
                }
            }

            List<Class<T>> result = new ArrayList<Class<T>>();
            URLClassLoader loader = new URLClassLoader( targetEntries.toArray( new URL[targetEntries.size()]) );
            for ( URL classUrl : targetEntries ) {
                String clsName = ( classUrl.getPath()
                                        .substring( 0 , classUrl.getPath().lastIndexOf(".") ) )
                                        .replaceAll(".class", "")
                                        .replaceAll( "/", "." );
                Class<T> clazz;
                try {
                    clazz = (Class<T>) loader.loadClass( clsName );
                    if ( filter != null && filter.filter(clazz) ) {
                        result.add(clazz);
                    }
                } catch ( Throwable e ) {
                    log.info( "Unable to load class: " + clsName, e  );
                }
            }

            return result.toArray( new Class[result.size()] );
        } catch ( Throwable e ) {
            log.error( e.getMessage(), e );
            throw new PackageLoaderException( e.getMessage() );
        }
    }

    protected <T> Class<T>[] getClassesFromIdle( String path, String pkgName, Filter filter ) throws PackageLoaderException {
        try {
            List<Class<T>> classes = new ArrayList<Class<T>>();
            String folderName = this.convertToFolderName( pkgName);

            File folder = Registry.getResourcesLoader().loadFile( folderName );
            if (  folder == null || !folder.exists() || !folder.canRead() || ( !folder.isDirectory() && !folder.getPath().endsWith(".jar") ) ) {
                return null;
            }

            if ( folder.getPath().endsWith(".jar") ) {
                classes.addAll( (List) Arrays.asList( this.getClassesFromJar( path, pkgName, filter ) ) );
            } else {
                String[] clsEntries = folder.list();
                for ( int i = 0; i < clsEntries.length; i++ ) {
                    File clsFile = new File( folder.getPath() + File.separator + clsEntries[i] );

                    if ( clsFile.isDirectory() ) {
                        continue;
                    }

                    String className = clsEntries[i].substring( 0, clsEntries[i].indexOf(".") );

                    Class<T> clazz = (Class<T>) ClassLoader.getSystemClassLoader().loadClass( pkgName + "." + className );
                    if ( filter != null && !filter.filter(clazz) ) {
                        continue;
                    }

                    classes.add( clazz );
                }
            }

            return classes.toArray( new Class[ classes.size() ] );
        } catch ( PackageLoaderException e ) {
            log.error( e.getMessage(), e );
            throw e;
        } catch ( Throwable e ) {
            log.error( e.getMessage(), e );
            throw new PackageLoaderException( e.getMessage() );
        }
    }

    private String convertToFolderName( String packageName ) {
        return packageName.replace(".", File.separator );
    }

}

class PackageLoaderException extends Exception {

    public PackageLoaderException( String message ) {
        super(message);
    }
}
2
Contributors
3
Replies
8
Views
7 Years
Discussion Span
Last Post by NormR1
0

When I try to compile I get:

Running: D:\Java\jdk1.6.0_02\bin\javac.exe -Xlint -g -deprecation -classpath D:\JavaDevelopment\;. PackageLoader.java

PackageLoader.java:16: cannot find symbol
symbol  : class Logger
location: class PackageLoader
    private static final Logger log = Logger.getLogger( PackageLoader.class );
                         ^
PackageLoader.java:22: cannot find symbol
symbol  : class Filter
location: class PackageLoader
    public <T> Class<T>[] getClasses( String pkgName, Filter filter ) throws PackageLoaderException {
                                                      ^
PackageLoader.java:42: cannot find symbol
symbol  : class Filter
location: class PackageLoader
    public <T> Class<T>[] getClasses( String path, String pkgName, Filter filter ) throws PackageLoaderException {
                                                                   ^
PackageLoader.java:50: cannot find symbol
symbol  : class Filter
location: class PackageLoader
    protected <T> Class<T>[] getClassesFromJar( String path, String pkgName, Filter filter ) throws PackageLoaderException {
                                                                             ^
PackageLoader.java:93: cannot find symbol
symbol  : class Filter
location: class PackageLoader
    protected <T> Class<T>[] getClassesFromIdle( String path, String pkgName, Filter filter ) throws PackageLoaderException {
                                                                              ^
PackageLoader.java:16: cannot find symbol
symbol  : variable Logger
location: class PackageLoader
    private static final Logger log = Logger.getLogger( PackageLoader.class );
                                      ^
PackageLoader.java:19: cannot find symbol
symbol  : class InterfacesFilter
location: class PackageLoader
        return this.getClasses( pkgName, new InterfacesFilter( new Class[] {} ) );
                                             ^
PackageLoader.java:35: warning: [unchecked] unchecked conversion
found   : java.lang.Class[]
required: java.lang.Class<T>[]
        return classes.toArray( new Class[classes.size()] );
                              ^
PackageLoader.java:39: cannot find symbol
symbol  : class InterfacesFilter
location: class PackageLoader
        return this.getClasses( path, pkgName, new InterfacesFilter( new Class[] {}  ) );
                                                   ^
PackageLoader.java:77: warning: [unchecked] unchecked cast
found   : java.lang.Class<capture#492 of ?>
required: java.lang.Class<T>
                    clazz = (Class<T>) loader.loadClass( clsName );
                                                       ^
PackageLoader.java:86: warning: [unchecked] unchecked conversion
found   : java.lang.Class[]
required: java.lang.Class<T>[]
            return result.toArray( new Class[result.size()] );
                                 ^
PackageLoader.java:98: cannot find symbol
symbol  : variable Registry
location: class PackageLoader
            File folder = Registry.getResourcesLoader().loadFile( folderName );
                          ^
PackageLoader.java:104: warning: [unchecked] unchecked conversion
found   : java.util.List
required: java.util.Collection<? extends java.lang.Class<T>>
                classes.addAll( (List) Arrays.asList( this.getClassesFromJar( path, pkgName, filter ) ) );
                                ^
PackageLoader.java:116: warning: [unchecked] unchecked cast
found   : java.lang.Class<capture#316 of ?>
required: java.lang.Class<T>
                    Class<T> clazz = (Class<T>) ClassLoader.getSystemClassLoader().loadClass( pkgName + "." + className );
                                                                                            ^
PackageLoader.java:125: warning: [unchecked] unchecked conversion
found   : java.lang.Class[]
required: java.lang.Class<T>[]
            return classes.toArray( new Class[ classes.size() ] );
                                  ^
PackageLoader.java:141: warning: [serial] serializable class PackageLoaderException has no definition of serialVersionUID
class PackageLoaderException extends Exception {
^
9 errors
7 warnings

9 error(s)

Edited by mike_2000_17: Fixed formatting

0

I don't have or want the log4j package. Too many extraneous jar files clutters up an app. Do you have a dummy class for the Logging stuff?
Where is the definition or the Filter class?

Remove "deprecated" argument

That doesn't make the code better. It just suppresses warnings.

Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.