package org.liufei.neta.lib;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.apache.log4j.Logger;
import org.liufei.neta.util.FileSystemUtils;
/**
* ClassLoader工厂。
*
* @author 刘飞
*/
public final class ClassLoaderFactory {
private static final Logger LOG = Logger
.getLogger ( ClassLoaderFactory.class );
/**
* 加载目录文件和jar文件到JVM中。
*
* @param path
* 目录文件
* @param parent
* 父级ClassLoader
* @return
* @throws Exception
*/
public static ClassLoader createClassLoader ( String[] path,
final ClassLoader parent ) throws Exception {
if ( LOG.isDebugEnabled () ) LOG.debug ( "Creating new class loader" );
/**
* 为该ClassLoader构建Classpath
*/
Set<URL> set = new LinkedHashSet<URL> ();
if ( path != null ) {
if ( path.length > 0 ) {
for ( String p : path ) {
File file = new File ( p );
List<File> list = new ArrayList<File> ();
FileSystemUtils.listAllFiles ( file, list );
for ( File f : list ) {
URL url = f.toURI ().toURL ();
if ( LOG.isDebugEnabled () ) LOG
.debug ( " Including file " + url );
set.add ( url );
}
}
}
else {
return Thread.currentThread ().getContextClassLoader ();
}
}
else {
return Thread.currentThread ().getContextClassLoader ();
}
/**
* 构建一个新的ClassLoader返回。
*/
final URL[] array = set.toArray ( new URL[ set.size () ] );
return AccessController
.doPrivileged ( new PrivilegedAction<StandardClassLoader> () {
@Override
public StandardClassLoader run () {
if ( parent == null ) return new StandardClassLoader (
array );
else return new StandardClassLoader ( array, parent );
}
} );
}
/**
* 加载目录文件和jar文件到JVM中。
*
* @param unpacked
* 未打包的目录
* @param packed
* 打包的jar文件
* @param parent
* 父级ClassLoader
* @return
* @throws Exception
*/
public static ClassLoader createClassLoader ( File unpacked[],
File packed[], final ClassLoader parent ) throws Exception {
if ( LOG.isDebugEnabled () ) LOG.debug ( "Creating new class loader" );
/**
* 为该ClassLoader构建Classpath
*/
Set<URL> set = new LinkedHashSet<URL> ();
/**
* 加载目录
*/
if ( unpacked != null ) {
for ( int i = 0 ; i < unpacked.length ; i++ ) {
File file = unpacked [ i ];
if ( ! file.exists () || ! file.canRead () ) continue;
file = new File ( file.getCanonicalPath () + File.separator );
URL url = file.toURI ().toURL ();
if ( LOG.isDebugEnabled () ) LOG
.debug ( " Including directory " + url );
set.add ( url );
}
}
/**
* 加载目录下的JAR文件
*/
if ( packed != null ) {
for ( int i = 0 ; i < packed.length ; i++ ) {
File directory = packed [ i ];
if ( ! directory.isDirectory () || ! directory.exists ()
|| ! directory.canRead () ) continue;
String filenames[] = directory.list ();
for ( int j = 0 ; j < filenames.length ; j++ ) {
String filename = filenames [ j ]
.toLowerCase ( Locale.ENGLISH );
if ( ! filename.endsWith ( ".jar" ) ) continue;
File file = new File ( directory, filenames [ j ] );
if ( LOG.isDebugEnabled () ) LOG
.debug ( " Including jar file "
+ file.getAbsolutePath () );
URL url = file.toURI ().toURL ();
set.add ( url );
}
}
}
/**
* 构建一个新的ClassLoader返回。
*/
final URL[] array = set.toArray ( new URL[ set.size () ] );
return AccessController
.doPrivileged ( new PrivilegedAction<StandardClassLoader> () {
@Override
public StandardClassLoader run () {
if ( parent == null ) return new StandardClassLoader (
array );
else return new StandardClassLoader ( array, parent );
}
} );
}
/**
* 加载目录文件和jar文件到JVM中。
*
* @param repositories
* @param parent
* @return
* @throws Exception
*/
public static ClassLoader createClassLoader (
List<Repository> repositories, final ClassLoader parent )
throws Exception {
if ( LOG.isDebugEnabled () ) LOG.debug ( "Creating new class loader" );
/**
* 为该ClassLoader构建Classpath
*/
Set<URL> set = new LinkedHashSet<URL> ();
if ( repositories != null ) {
for ( Repository repository : repositories ) {
if ( repository.getType () == RepositoryType.URL ) {
URL url = new URL ( repository.getLocation () );
if ( LOG.isDebugEnabled () ) LOG.debug ( " Including URL "
+ url );
set.add ( url );
}
else if ( repository.getType () == RepositoryType.DIR ) {
File directory = new File ( repository.getLocation () );
directory = directory.getCanonicalFile ();
if ( ! validateFile ( directory, RepositoryType.DIR ) ) {
continue;
}
URL url = directory.toURI ().toURL ();
if ( LOG.isDebugEnabled () ) LOG
.debug ( " Including directory " + url );
set.add ( url );
}
else if ( repository.getType () == RepositoryType.JAR ) {
File file = new File ( repository.getLocation () );
file = file.getCanonicalFile ();
if ( ! validateFile ( file, RepositoryType.JAR ) ) {
continue;
}
URL url = file.toURI ().toURL ();
if ( LOG.isDebugEnabled () ) LOG
.debug ( " Including jar file " + url );
set.add ( url );
}
else if ( repository.getType () == RepositoryType.GLOB ) {
File directory = new File ( repository.getLocation () );
directory = directory.getCanonicalFile ();
if ( ! validateFile ( directory, RepositoryType.GLOB ) ) {
continue;
}
if ( LOG.isDebugEnabled () ) LOG
.debug ( " Including directory glob "
+ directory.getAbsolutePath () );
String filenames[] = directory.list ();
for ( int j = 0 ; j < filenames.length ; j++ ) {
String filename = filenames [ j ]
.toLowerCase ( Locale.ENGLISH );
if ( ! filename.endsWith ( ".jar" ) ) continue;
File file = new File ( directory, filenames [ j ] );
file = file.getCanonicalFile ();
if ( ! validateFile ( file, RepositoryType.JAR ) ) {
continue;
}
if ( LOG.isDebugEnabled () ) LOG
.debug ( " Including glob jar file "
+ file.getAbsolutePath () );
URL url = file.toURI ().toURL ();
set.add ( url );
}
}
}
}
/**
* 构建一个新的ClassLoader返回。
*/
final URL[] array = set.toArray ( new URL[ set.size () ] );
if ( LOG.isDebugEnabled () ) for ( int i = 0 ; i < array.length ; i++ ) {
LOG.debug ( " location " + i + " is " + array [ i ] );
}
return AccessController
.doPrivileged ( new PrivilegedAction<StandardClassLoader> () {
@Override
public StandardClassLoader run () {
if ( parent == null ) return new StandardClassLoader (
array );
else return new StandardClassLoader ( array, parent );
}
} );
}
private static boolean validateFile ( File file, RepositoryType type )
throws IOException {
if ( RepositoryType.DIR == type || RepositoryType.GLOB == type ) {
if ( ! file.exists () || ! file.isDirectory () || ! file.canRead () ) {
LOG.warn ( "Problem with JAR file [" + file + "], exists: ["
+ file.exists () + "], canRead: [" + file.canRead ()
+ "]" );
return false;
}
}
else if ( RepositoryType.JAR == type ) {
if ( ! file.exists () || ! file.canRead () ) {
LOG.warn ( "Problem with JAR file [" + file + "], exists: ["
+ file.exists () + "], canRead: [" + file.canRead ()
+ "]" );
return false;
}
}
return true;
}
public static enum RepositoryType {
DIR, GLOB, JAR, URL
}
public static class Repository {
private String location;
private RepositoryType type;
public Repository ( String location, RepositoryType type ) {
this.location = location;
this.type = type;
}
public String getLocation () {
return location;
}
public RepositoryType getType () {
return type;
}
}
}
package org.liufei.neta.lib;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.liufei.neta.util.ClassUtils;
import org.liufei.neta.util.FileCopyUtils;
import org.liufei.neta.util.ObjectCreator;
/**
* 动态加载jar文件, 指定目录下的jar文件和Class文件装入虚拟机供调用。
*
* @author 刘飞
*/
public class ClasspathLoader extends URLClassLoader {
private static final Logger LOG = Logger.getLogger ( ClasspathLoader.class );
/**
* @param urls
*/
public ClasspathLoader ( URL[] urls ) {
super ( urls );
this.debugUrls ( urls );
}
/**
* @param url
*/
public ClasspathLoader ( URL url ) {
this ( new URL[] {
url
} );
}
/**
* @param url
* @throws MalformedURLException
*/
public ClasspathLoader ( String url ) throws MalformedURLException {
this ( toUrl ( url ) );
}
/**
* @param urls
* @throws MalformedURLException
*/
public ClasspathLoader ( String[] urls ) throws MalformedURLException {
this ( toUrl ( urls ) );
}
/**
* 加载并实例化指定类名称的类.
*
* @param clazz
* 类名称
* @param constructorArgTypes
* 构造参数类型
* @param constructorArgs
* 构造参数
* @return
* @throws LinkageError
* @throws ClassNotFoundException
*/
public Object newInstance ( String clazz,
List<Class<?>> constructorArgTypes, List<Object> constructorArgs )
throws ClassNotFoundException, LinkageError {
return ObjectCreator.create ( this.load ( clazz ), constructorArgTypes,
constructorArgs );
}
/**
* 加载并实例化指定类名称的类, 该类必须有一个无参的构造方法。
*
* @param clazz
* 类名称
* @return
* @throws LinkageError
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public Object newInstance ( String clazz ) throws InstantiationException,
IllegalAccessException, ClassNotFoundException, LinkageError {
return this.load ( clazz ).newInstance ();
}
/**
* 加载类
*
* @param clazz
* 类名称
* @return
* @throws ClassNotFoundException
* @throws LinkageError
*/
public Class<?> load ( String clazz ) throws ClassNotFoundException,
LinkageError {
return ClassUtils.forName ( clazz, this );
}
/**
* 从比特流里加载java字节码并编译生成Class对象加载到JVM
*
* @param name
* 类名称
* @param b
* @param off
* @param len
* @return
* @throws ClassFormatError
*/
public Class<?> defineClassByBytes ( String name, byte[] b, int off, int len )
throws ClassFormatError {
return this.defineClass ( name, b, off, len );
}
/**
* 从文件中读取比特流加载java字节码并编译生成Class对象加载到JVM
*
* @param name
* 类名称
* @param file
* class字节码文件
* @return
* @throws IOException
*/
public Class<?> defineClassByBytes ( String name, File file )
throws IOException {
byte[] b = FileCopyUtils.copyToByteArray ( file );
return this.defineClass ( name, b, 0, b.length );
}
/**
* 从文件中读取比特流加载java字节码并编译生成Class对象加载到JVM
*
* @param name
* 类名称
* @param file
* class字节码文件
* @return
* @throws IOException
*/
public Class<?> defineClassByBytes ( String name, String file )
throws IOException {
return this.defineClassByBytes ( name, new File ( file ) );
}
@Override
protected Class<?> findClass ( String name ) throws ClassNotFoundException {
return super.findClass ( name );
}
@Override
protected synchronized Class<?> loadClass ( String name, boolean resolve )
throws ClassNotFoundException {
return super.loadClass ( name, resolve );
}
@Override
public Class<?> loadClass ( String name ) throws ClassNotFoundException {
return super.loadClass ( name );
}
private void debugUrls ( URL... urls ) {
for ( URL url : urls ) {
LOG.debug ( "loading java class source from classpath url : "
+ url.toString () );
}
}
/**
* 将路径数组转换为URL对象数组。
*
* @param urls
* @return
* @throws MalformedURLException
*/
private static URL[] toUrl ( String[] urls ) throws MalformedURLException {
List<URL> list = new ArrayList<URL> ();
for ( String u : urls ) {
list.add ( toUrl ( u ) );
}
return list.toArray ( new URL[ urls.length ] );
}
/**
* 将路径数组转换为URL对象数组。
*
* @param urls
* @return
* @throws MalformedURLException
*/
private static URL toUrl ( String url ) throws MalformedURLException {
return new URL ( url );
}
}
package org.liufei.neta.util;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
/**
* 系统包操作工具。
*
* @author 刘飞
*/
public class PackageUtil {
/**
* 找出指定文件下指定包名的所有类
*
* @param fileDir
* 文件
* @param pkgName
* 包名
* @return
*/
public static List<String> getClassInPackage ( String fileDir,
String pkgName ) {
Assert.notNull ( fileDir ) ;
Assert.notNull ( pkgName ) ;
return getClassInPackage ( new File ( fileDir ), pkgName );
}
/**
* 找出指定文件下指定包名的所有类
*
* @param fileDir
* 文件
* @param pkgName
* 包名
* @return
*/
public static List<String> getClassInPackage ( File fileDir, String pkgName ) {
Assert.notNull ( fileDir ) ;
Assert.notNull ( pkgName ) ;
List<File> dirs = new ArrayList<File> ();
FileSystemUtils.listAllFiles ( fileDir, dirs );
return getClassInPackage ( dirs, pkgName );
}
/**
* 找出指定目录下的所有类
*
* @param dirs
* 目录
* @param pkgName
* 包名
* @return
*/
public static List<String> getClassInPackage ( List<File> dirs,
String pkgName ) {
Assert.notNull ( dirs ) ;
Assert.notNull ( pkgName ) ;
List<String> ret = new ArrayList<String> ();
String pkg = pkgName.replace ( ".", File.separator );
String rPath = pkgName.replace ( '.', '/' ) + "/";
try {
for ( File classPath : dirs ) {
if ( ! classPath.exists () ) continue;
if ( classPath.isDirectory () ) {
File dir = new File ( classPath, rPath );
if ( ! dir.exists () ) continue;
for ( File file : dir.listFiles () ) {
if ( file.isFile () ) {
String clsName = file.getName ();
clsName = pkgName
+ "."
+ clsName.substring ( 0,
clsName.length () - 6 );
ret.add ( clsName );
}
}
}
else if ( classPath.isFile ()
&& ( classPath.getName ().endsWith ( ".java" ) || classPath
.getName ().endsWith ( ".class" ) )
&& classPath.getName ().indexOf ( "$" ) == - 1
&& classPath.getAbsolutePath ().indexOf ( pkg ) != - 1 ) {
if ( classPath.getName ().endsWith ( ".java" ) ) {
String clsName = classPath.getAbsolutePath ()
.substring (
classPath.getAbsolutePath ().indexOf (
pkg ) ).replace (
File.separator, "." );
clsName = clsName.substring ( 0, clsName.length () - 5 );
ret.add ( clsName );
}
else if ( classPath.getName ().endsWith ( ".class" ) ) {
String clsName = classPath.getAbsolutePath ()
.substring (
classPath.getAbsolutePath ().indexOf (
pkg ) ).replace (
File.separator, "." );
clsName = clsName.substring ( 0, clsName.length () - 6 );
ret.add ( clsName );
}
}
else {
FileInputStream fis = new FileInputStream ( classPath );
JarInputStream jis = new JarInputStream ( fis, false );
JarEntry e = null;
while ( ( e = jis.getNextJarEntry () ) != null ) {
String eName = e.getName ();
if ( eName.startsWith ( rPath )
&& ! eName.endsWith ( "/" ) ) {
ret.add ( eName.replace ( '/', '.' ).substring ( 0,
eName.length () - 6 ) );
}
jis.closeEntry ();
}
jis.close ();
}
}
for ( String cls : getClassInPackage ( pkgName ) ) {
ret.add ( cls );
}
}
catch ( Exception e ) {
throw new RuntimeException ( e );
}
return ret;
}
/**
* 找出系统目录下的所有类
*
* @param pkgName
* 包名
* @return
*/
public static List<String> getClassInPackage ( String pkgName ) {
Assert.notNull ( pkgName ) ;
List<String> ret = new ArrayList<String> ();
String pkg = pkgName.replace ( ".", File.separator );
String rPath = pkgName.replace ( '.', '/' ) + "/";
try {
for ( File classPath : CLASS_PATH_ARRAY ) {
if ( ! classPath.exists () ) continue;
if ( classPath.isDirectory () ) {
File dir = new File ( classPath, rPath );
if ( ! dir.exists () ) continue;
for ( File file : dir.listFiles () ) {
if ( file.isFile () ) {
String clsName = file.getName ();
clsName = pkgName
+ "."
+ clsName.substring ( 0,
clsName.length () - 6 );
ret.add ( clsName );
}
}
}
else if ( classPath.isFile ()
&& ( classPath.getName ().endsWith ( ".java" ) || classPath
.getName ().endsWith ( ".class" ) )
&& classPath.getName ().indexOf ( "$" ) == - 1
&& classPath.getAbsolutePath ().indexOf ( pkg ) != - 1 ) {
if ( classPath.getName ().endsWith ( ".java" ) ) {
String clsName = classPath.getAbsolutePath ()
.substring (
classPath.getAbsolutePath ().indexOf (
pkg ) ).replace (
File.separator, "." );
clsName = clsName.substring ( 0, clsName.length () - 5 );
ret.add ( clsName );
}
else if ( classPath.getName ().endsWith ( ".class" ) ) {
String clsName = classPath.getAbsolutePath ()
.substring (
classPath.getAbsolutePath ().indexOf (
pkg ) ).replace (
File.separator, "." );
clsName = clsName.substring ( 0, clsName.length () - 6 );
ret.add ( clsName );
}
}
else {
FileInputStream fis = new FileInputStream ( classPath );
JarInputStream jis = new JarInputStream ( fis, false );
JarEntry e = null;
while ( ( e = jis.getNextJarEntry () ) != null ) {
String eName = e.getName ();
if ( eName.startsWith ( rPath )
&& ! eName.endsWith ( "/" )
&& eName.indexOf ( "$" ) == - 1 ) {
ret.add ( eName.replace ( '/', '.' ).substring ( 0,
eName.length () - 6 ) );
}
jis.closeEntry ();
}
jis.close ();
}
}
}
catch ( Exception e ) {
throw new RuntimeException ( e );
}
return ret;
}
private static String[] CLASS_PATH_PROP = {
"java.class.path", "java.ext.dirs", "sun.boot.class.path",
"user.dir", "java.library.path", "java.home", "user.home"
};
private static List<File> CLASS_PATH_ARRAY = getClassPath ();
private static List<File> getClassPath () {
List<File> ret = new ArrayList<File> ();
String delim = ":";
if ( System.getProperty ( "os.name" ).indexOf ( "Windows" ) != - 1 ) delim = ";";
for ( String pro : CLASS_PATH_PROP ) {
String[] pathes = System.getProperty ( pro ).split ( delim );
for ( String path : pathes )
ret.add ( new File ( path ) );
}
return ret;
}
public static void main ( String[] args ) {
List<String> classes = PackageUtil.getClassInPackage ( "D:/lib",
"org.liufei" );
for ( String string : classes ) {
System.out.println ( "class : " + string );
}
System.out.println (classes.size ());
}
}
分享到:
相关推荐
在Java虚拟机(JVM)中,类加载器(ClassLoader)是至关重要的组成部分,它负责查找和加载类的字节码文件。理解ClassLoader的工作机制对于深入掌握Java应用程序的运行至关重要。这里我们将详细讨论ClassLoader的运行...
《深入理解ClassLoader工作机制》 Java虚拟机(JVM)中的ClassLoader是负责加载类到内存中的核心组件。它不仅承担着将字节码转换为可执行对象的重任,还参与了类生命周期的各个阶段,包括加载、验证、准备、解析、...
在Java中,Classloader是加载类的关键组件,它负责查找、加载和初始化字节码文件。自定义Classloader允许开发者根据特定需求定制类的加载逻辑,例如加密类文件、隔离不同版本的库或者动态加载代码。本文将深入探讨...
在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中,使得程序能够执行。本示例"ClassLoader小例子"将深入探讨这个概念,并通过一个具体的程序来演示其工作原理。下面我们...
Java ClassLoader是Java运行时系统的关键但经常被忽视的组件,负责在运行时查找和加载类文件。通过创建自定义ClassLoader,你可以定制JVM,使类文件的引入方式完全重新定义,这提供了很多实用和有趣的可能。这篇教程...
Java ClassLoader机制是Java虚拟机(JVM)中一个至关重要的组成部分,它的主要任务是将类的.class文件加载到JVM中,使得程序能够运行。ClassLoader不仅负责类的加载,还涉及类的验证、初始化等一系列过程。理解...
在Java编程语言中,`ClassLoader`是一个至关重要的组件,它负责加载类到JVM(Java虚拟机)中。本文将深入探讨`ClassLoader`的工作原理、加密解密应用程序以及如何防止类被反编译。 首先,让我们理解`ClassLoader`的...
在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中。理解ClassLoader的工作原理以及如何定制它,对于深入学习Java的运行机制和进行高级应用开发具有重要意义。本篇文章将...
在Java世界中,类加载器(ClassLoader)是关键的组件之一,它负责将类的字节码文件(.class)从文件系统或网络中加载到Java虚拟机(JVM)中,使得程序能够运行。本篇文章将深入探讨ClassLoader的关系网络以及如何...
《ClassLoader详解》 Java应用程序的运行离不开类的加载,而ClassLoader正是这个过程的关键角色。它负责将类的字节码加载到Java虚拟机(JVM)中并转换为可执行的Java对象。深入理解ClassLoader的工作原理对于优化...
Java ClassLoader机制是Java运行时环境中的核心组件之一,它负责加载类到JVM(Java虚拟机)中,使得程序能够执行。理解ClassLoader的工作原理对于优化应用性能、处理类加载问题以及实现自定义加载器至关重要。 首先...
在Java编程语言中,ClassLoader是核心组件之一,它负责加载类到JVM(Java虚拟机)中执行。本文将深入探讨ClassLoader的工作原理和类加载机制,帮助开发者理解这个至关重要的概念。 1. 类加载机制概述 Java的类加载...
在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中执行。这篇测试主要探讨了ClassLoader的工作原理及其在实际应用中的使用。通过阅读给出的博文链接,我们可以深入理解...
### Java ClassLoader与ClassPath详解 #### 一、概述 在Java编程中,类加载机制是十分关键的一个环节。类加载器(`ClassLoader`)负责将编译后的`.class`文件加载到Java虚拟机(JVM)中执行,而类路径(`ClassPath...
Java的类加载器(ClassLoader)体系结构是JVM(Java虚拟机)中至关重要的一部分,它负责将类的字节码转换为运行时的类实例。本文将深入探讨启动类加载器、扩展类加载器、系统类加载器以及用户自定义类加载器,同时还...
破解java加密的ClassLoader.java,在classloader植入破解代码