Java-自定义类加载器-尝试使用类文件完整路径加载类
作为用于学术目的的HTTP Web服务器项目的一部分, 我正在尝试为web应用程序类编写自己的自定义类加载器,但似乎做得不对 一般来说,web应用程序位于它们自己的文件夹中,web应用程序的.class文件与其直接父文件夹名称相同。e、 g.Web1/Web1.class。 下面的代码在我达到defineClass方法之前工作正常,然后它抛出我,出现以下异常: java.io.FileNotFoundException:C:\inetpub\javawwwroot\WebApps\java\lang\Object\.Object.class系统找不到指定的路径 值得一提的是,在下面的代码中,C:\inetpub\javawwwroot\WebApps\part等于m_WebAppsFullPath变量 另外,当尝试使用 InputStream in=getResourceAsStreamclsFile 而不是InputStream in=新文件inputstreamclsfile 我得到一个空的返回值 更新:简而言之,如何加载一个既不在类路径中也不在项目包中的特定类Java-自定义类加载器-尝试使用类文件完整路径加载类,java,web-applications,classloader,Java,Web Applications,Classloader,作为用于学术目的的HTTP Web服务器项目的一部分, 我正在尝试为web应用程序类编写自己的自定义类加载器,但似乎做得不对 一般来说,web应用程序位于它们自己的文件夹中,web应用程序的.class文件与其直接父文件夹名称相同。e、 g.Web1/Web1.class。 下面的代码在我达到defineClass方法之前工作正常,然后它抛出我,出现以下异常: java.io.FileNotFoundException:C:\inetpub\javawwwroot\WebApps\java\la
protected synchronized Class loadClass(String className, boolean resolve)
throws ClassNotFoundException
{
log("Loading class: " + className + ", resolve: " + resolve);
// 1. is this class already loaded?
Class cls = findLoadedClass(className);
if (cls != null)
{
return cls;
}
// 2. get class file name from class name
String classRelativePath = className.replace('.', '/');
String classFileName =
((className.lastIndexOf('.') != -1) ? className.substring(className.lastIndexOf('.')) : className) + ".class";
String clsFile = m_WebAppsFullPath + "\\" + classRelativePath + "\\" + classFileName;
// 3. get bytes for class
byte[] classBytes = null;
try
{
//InputStream in = getResourceAsStream(clsFile);
InputStream in = new FileInputStream(clsFile);
byte[] buffer = new byte[BUFFER_SIZE];
ByteArrayOutputStream out = new ByteArrayOutputStream();
int n = -1;
while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
out.write(buffer, 0, n);
}
classBytes = out.toByteArray();
}
catch (IOException e) {
log("ERROR loading class file: " + e);
}
if (classBytes == null) {
throw new ClassNotFoundException("Cannot load class: " + className);
}
// 4. turn the byte array into a Class
try {
cls = defineClass(className, classBytes, 0, classBytes.length);
if (resolve) {
resolveClass(cls);
}
}
catch (SecurityException e) {
// loading core java classes such as java.lang.String
// is prohibited, throws java.lang.SecurityException.
// delegate to parent if not allowed to load class
cls = super.loadClass(className, resolve);
}
return cls;
}
知道我怎样才能让它工作吗
谢谢 目前,您不仅试图通过自己的类加载器加载自定义类,还尝试加载它们所依赖的所有系统类。比如java.lang.Object,这是您的问题所在 通常,Java中的类加载器是链接的,这意味着您的类加载器已经由另一个类加载器定义,很可能是系统类加载器。因此,建议不要自己覆盖loadClass方法,而是覆盖这两个方法的findClassString:Class和loadClassDataString:Class 下面是Classloader类的Javadoc的一个例外: ClassLoader类使用委托模型来搜索 课程和资源。ClassLoader的每个实例都有一个 关联的父类加载器。当被要求查找类或 资源,类加载器实例将委托对 在尝试查找前,将类或资源加载到其父类加载器 类或资源本身。虚拟机的内置类加载器, 称为引导类装入器,它本身没有父类,但可能 充当ClassLoader实例的父级 同一个Javadoc甚至列出了一个示例,如何正确定义自定义类加载器:
class NetworkClassLoader extends ClassLoader {
String host;
int port;
public Class findClass(String name) {
byte[] b = loadClassData(name);
return defineClass(name, b, 0, b.length);
}
private byte[] loadClassData(String name) {
// load the class data from the connection
. . .
}
}
我想您可能想读一下:目前,您不仅试图通过自己的类加载器加载自定义类,还试图加载它们所依赖的所有系统类。比如java.lang.Object,这是您的问题所在 通常,Java中的类加载器是链接的,这意味着您的类加载器已经由另一个类加载器定义,很可能是系统类加载器。因此,建议不要自己覆盖loadClass方法,而是覆盖这两个方法的findClassString:Class和loadClassDataString:Class 下面是Classloader类的Javadoc的一个例外: ClassLoader类使用委托模型来搜索 课程和资源。ClassLoader的每个实例都有一个 关联的父类加载器。当被要求查找类或 资源,类加载器实例将委托对 在尝试查找前,将类或资源加载到其父类加载器 类或资源本身。虚拟机的内置类加载器, 称为引导类装入器,它本身没有父类,但可能 充当ClassLoader实例的父级 同一个Javadoc甚至列出了一个示例,如何正确定义自定义类加载器:
class NetworkClassLoader extends ClassLoader {
String host;
int port;
public Class findClass(String name) {
byte[] b = loadClassData(name);
return defineClass(name, b, 0, b.length);
}
private byte[] loadClassData(String name) {
// load the class data from the connection
. . .
}
}
我想您可能想读一下:如果您能显示完整的异常堆栈跟踪,那会有所帮助….\Object\.Object.class确定您不需要…\Object.class否,我正在尝试加载我自己的名为Web1的类,它位于C:\inetpub\javawwwroot\WebApps\Web1\Web1.class没有如下目录:C:\inetpub\javawwwroot\WebApps\java\lang\n如果您可以显示完整的异常堆栈跟踪…\Object\.Object.class确定您不需要…\Object.class否,我正在尝试加载自己的名为Web1的类,它位于C:\inetpub\javawwwroot\WebApps\Web1\Web1.class。没有像C:\inetpub\javawwwroot\WebApps\java\lang\raven这样的目录是正确的。对于那些定制的find逻辑,应该将其放入findClass方法中。但是基于整个Java类装入器层次结构,它不应该首先尝试从顶级类装入器装入对象类吗?如果失败了,试着用我自己的自定义类加载器加载它?是的。但是,如果您将代码放在findClass和loadClassData中,而不是loadClass中,那么这种行为已经为您解决了;如果您希望父类loadingraven正确,则有必要进行覆盖。对于那些自定义查找逻辑,应该是
但是基于整个Java类加载器层次结构,它不应该首先从顶级类加载器加载对象类吗?如果失败了,试着用我自己的自定义类加载器加载它?是的。但是,如果您将代码放在findClass和loadClassData中,而不是loadClass中,那么这种行为已经为您解决了;如果希望加载父类的最后一个类,则有必要进行覆盖