暗黑模式
关于反序列化的ClassLoader记录
发布时间:2020-10-16 11:15:07 阅读:302

关于反序列化的ClassLoader记录

反序列化会使用ObjectInputStream这个类,这个类会调用resolveClass的方法()

/**  
 * Load the local class equivalent of the specified stream class * description.  Subclasses may implement this method to allow classes to * be fetched from an alternate source. * * <p>The corresponding method in <code>ObjectOutputStream</code> is  
 * <code>annotateClass</code>.  This method will be invoked only once for  
 * each unique class in the stream.  This method can be implemented by * subclasses to use an alternate loading mechanism but must return a * <code>Class</code> object. Once returned, if the class is not an array  
 * class, its serialVersionUID is compared to the serialVersionUID of the * serialized class, and if there is a mismatch, the deserialization fails * and an {@link InvalidClassException} is thrown.  
 * * <p>The default implementation of this method in  
 * <code>ObjectInputStream</code> returns the result of calling  
 * <pre>  
 *     Class.forName(desc.getName(), false, loader)  
 * </pre>  
 * where <code>loader</code> is the first class loader on the current  
 * thread's stack (starting from the currently executing method) that is * neither the {@linkplain ClassLoader#getPlatformClassLoader() platform  
 * class loader} nor its ancestor; otherwise, <code>loader</code> is the  
 * <em>platform class loader</em>. If this call results in a  
 * <code>ClassNotFoundException</code> and the name of the passed  
 * <code>ObjectStreamClass</code> instance is the Java language keyword  
 * for a primitive type or void, then the <code>Class</code> object  
 * representing that primitive type or void will be returned * (e.g., an <code>ObjectStreamClass</code> with the name  
 * <code>"int"</code> will be resolved to <code>Integer.TYPE</code>).  
 * Otherwise, the <code>ClassNotFoundException</code> will be thrown to  
 * the caller of this method. * * @param desc an instance of class <code>ObjectStreamClass</code>  
 * @return a <code>Class</code> object corresponding to <code>desc</code>  
 * @throws IOException any of the usual Input/Output exceptions.  
 * @throws ClassNotFoundException if class of a serialized object cannot  
 *          be found. */protected Class<?> resolveClass(ObjectStreamClass desc)  
    throws IOException, ClassNotFoundException  
{  
    String name = desc.getName();  
 try {  
        return Class.forName(name, false, latestUserDefinedLoader());  
 } catch (ClassNotFoundException ex) {  
        Class<?> cl = primClasses.get(name);  
 if (cl != null) {  
            return cl;  
 } else {  
            throw ex;  
 }  
    }  
}

其中第一行代码使用了public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
然后用latestUserDefinedLoader()获取最后用户定义的ClassLoader
继续查看latestUserDefinedLoader()的源码

/*  
 * Returns the first user-defined class loader up the execution stack, * or the platform class loader if only code from the platform or * bootstrap class loader is on the stack. */public static ClassLoader latestUserDefinedLoader() {  
    ClassLoader loader = latestUserDefinedLoader0();  
 return loader != null ? loader : ClassLoader.getPlatformClassLoader();  
} 

大概意思是先去调用native的latestUserDefinedLoader0()方法,如果找不到就返回PlatformClassLoader()【我使用的JDK11】;

我这里测试一般latestUserDefinedLoader0()会返回AppClassLoader

这里测试,latestUserDefinedLoader0()不会返回自定义的上下文类加载器

使用 Nuxt 3 构建 | 部署于 Kubernetes | 托管于 狗云
Copyright © 2023 | 网站已续航 1807 天