java中的九陽神功——反射原理(Class獲取方式)
1、什麼是反射技術?動態獲取指定類以及類中的內容(成員),並運行其內容。應用程序已經運行,無法在其中進行new對象的建立,就無法使用對象。這時可以根據配置...
tomcat反序列化的過程中一直報ClassNotFoundException,這個是什麼原因呢
很明顯是classloader找不到這個class,為什麼呢,我的應用代碼中明明就有啊。
實際上java反序列化的時候,我們一般用的是ObjectInputStream,他默認會去找sun.misc.VM.latestUserDefinedLoader,這個就是系統默認的appClassloader。
重點來了,我們的tomcat中應用代碼的類不是appClassloader,而是webAppClassloader,是tomcat自己搞的一個classLoader。
解決方法:寫個類繼續ObjectInputStream,覆蓋他的resolveClass方法。使用當前線程的classloader,也就是webAppClassloader
具體代碼:
package com.vip.marmot.mirror.agent.dataHandler; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectStreamClass; import java.util.HashMap; /** * Created by cloud.huang on 17/5/18. */ public class YunbinObjectInputStream extends ObjectInputStream { public YunbinObjectInputStream(InputStream in) throws IOException { super(in); } protected YunbinObjectInputStream throws IOException, SecurityException { } /** * table mapping primitive type names to corresponding class objects */ private static final HashMap<String, Class<?>> primClasses = new HashMap<>(8, 1.0F); static { primClasses.put("boolean", boolean.class); primClasses.put("byte", byte.class); primClasses.put("char", char.class); primClasses.put("short", short.class); primClasses.put("int", int.class); primClasses.put("long", long.class); primClasses.put("float", float.class); primClasses.put("double", double.class); primClasses.put("void", void.class); } @Override protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { String name = desc.getName; try { ClassLoader loader = Thread.currentThread.getContextClassLoader; return Class.forName(name, false, loader); } catch (ClassNotFoundException ex) { Class cl = (Class) primClasses.get(name); if (cl != null) { return cl; } else { throw ex; } } } }