From 626a67d8cfb96dcb2e22b3e6313bcb9ca9e8e69c Mon Sep 17 00:00:00 2001 From: wenshao Date: Mon, 30 Dec 2013 21:08:05 +0800 Subject: [PATCH] support custom classLoader --- pom.xml | 4 ++-- .../alibaba/fastjson/parser/ParserConfig.java | 20 ++++++++++++---- .../deserializer/ASMDeserializerFactory.java | 23 +++++++++++-------- .../alibaba/fastjson/util/ASMClassLoader.java | 4 ++++ 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/pom.xml b/pom.xml index 6e45fb3e2..15aa93b67 100755 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ --> com.alibaba fastjson - 1.1.37 + 1.1.38-SNAPSHOT jar fastjson @@ -23,7 +23,7 @@ 4.11 - false + true false UTF-8 1.5 diff --git a/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java b/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java index 93c4c188a..b625159db 100755 --- a/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java +++ b/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java @@ -148,7 +148,17 @@ public class ParserConfig { protected final SymbolTable symbolTable = new SymbolTable(); - public ParserConfig(){ + protected ASMDeserializerFactory asmFactory = ASMDeserializerFactory.getInstance(); + + public ParserConfig() { + this(ASMDeserializerFactory.getInstance()); + } + + public ParserConfig(ClassLoader parentClassLoader){ + this(new ASMDeserializerFactory(parentClassLoader)); + } + + public ParserConfig(ASMDeserializerFactory asmFactory){ primitiveClasses.add(boolean.class); primitiveClasses.add(Boolean.class); @@ -399,7 +409,7 @@ public class ParserConfig { asmEnable = false; } - if (ASMDeserializerFactory.getInstance().isExternalClass(clazz)) { + if (asmFactory.isExternalClass(clazz)) { asmEnable = false; } @@ -446,7 +456,7 @@ public class ParserConfig { } try { - return ASMDeserializerFactory.getInstance().createJavaBeanDeserializer(this, clazz, type); + return asmFactory.createJavaBeanDeserializer(this, clazz, type); // } catch (VerifyError e) { // e.printStackTrace(); // return new JavaBeanDeserializer(this, clazz, type); @@ -482,7 +492,7 @@ public class ParserConfig { asmEnable = false; } - if (ASMDeserializerFactory.getInstance().isExternalClass(clazz)) { + if (asmFactory.isExternalClass(clazz)) { asmEnable = false; } @@ -491,7 +501,7 @@ public class ParserConfig { } try { - return ASMDeserializerFactory.getInstance().createFieldDeserializer(mapping, clazz, fieldInfo); + return asmFactory.createFieldDeserializer(mapping, clazz, fieldInfo); } catch (Throwable e) { // skip } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java index c3db0264c..a7611c8c0 100755 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java @@ -42,11 +42,11 @@ import com.alibaba.fastjson.util.FieldInfo; public class ASMDeserializerFactory implements Opcodes { - private static final ASMDeserializerFactory instance = new ASMDeserializerFactory(); + private static final ASMDeserializerFactory instance = new ASMDeserializerFactory(); - private ASMClassLoader classLoader = new ASMClassLoader(); + private final ASMClassLoader classLoader; - private final AtomicLong seed = new AtomicLong(); + private final AtomicLong seed = new AtomicLong(); public String getGenClassName(Class clazz) { return "Fastjson_ASM_" + clazz.getSimpleName() + "_" + seed.incrementAndGet(); @@ -60,7 +60,11 @@ public class ASMDeserializerFactory implements Opcodes { } public ASMDeserializerFactory(){ + classLoader = new ASMClassLoader(); + } + public ASMDeserializerFactory(ClassLoader parentClassLoader){ + classLoader = new ASMClassLoader(parentClassLoader); } public final static ASMDeserializerFactory getInstance() { @@ -183,9 +187,8 @@ public class ASMDeserializerFactory implements Opcodes { mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getSymbolTable", "()" + getDesc(SymbolTable.class)); mw.visitVarInsn(BIPUSH, seperator); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONLexerBase.class), "scanEnum", "(Ljava/lang/Class;" - + getDesc(SymbolTable.class) - + "C)Ljava/lang/Enum;"); + mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONLexerBase.class), "scanEnum", + "(Ljava/lang/Class;" + getDesc(SymbolTable.class) + "C)Ljava/lang/Enum;"); mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); } else if (Collection.class.isAssignableFrom(fieldClass)) { @@ -485,7 +488,8 @@ public class ASMDeserializerFactory implements Opcodes { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ALOAD, 0); mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONLexerBase.class), "scanFieldString", "([C)Ljava/lang/String;"); + mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONLexerBase.class), "scanFieldString", + "([C)Ljava/lang/String;"); mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); } else if (fieldClass.isEnum()) { @@ -656,7 +660,7 @@ public class ASMDeserializerFactory implements Opcodes { mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitFieldInsn(GETSTATIC, getType(Feature.class), feature.name(), "L" + getType(Feature.class) + ";"); mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONLexerBase.class), "isEnabled", "(" + "L" + getType(Feature.class) - + ";" + ")Z"); + + ";" + ")Z"); } private void defineVarLexer(Context context, MethodVisitor mw) { @@ -724,7 +728,8 @@ public class ASMDeserializerFactory implements Opcodes { mw.visitVarInsn(ALOAD, context.var("instance")); mw.visitVarInsn(LLOAD, context.var(fieldInfo.getName() + "_asm", 2)); if (fieldInfo.getMethod() != null) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(context.getClazz()), fieldInfo.getMethod().getName(), getDesc(fieldInfo.getMethod())); + mw.visitMethodInsn(INVOKEVIRTUAL, getType(context.getClazz()), fieldInfo.getMethod().getName(), + getDesc(fieldInfo.getMethod())); if (!fieldInfo.getMethod().getReturnType().equals(Void.TYPE)) { mw.visitInsn(POP); } diff --git a/src/main/java/com/alibaba/fastjson/util/ASMClassLoader.java b/src/main/java/com/alibaba/fastjson/util/ASMClassLoader.java index e4cbfb8f6..6f5f30b12 100755 --- a/src/main/java/com/alibaba/fastjson/util/ASMClassLoader.java +++ b/src/main/java/com/alibaba/fastjson/util/ASMClassLoader.java @@ -20,6 +20,10 @@ public class ASMClassLoader extends ClassLoader { public ASMClassLoader(){ super(getParentClassLoader()); } + + public ASMClassLoader(ClassLoader parent){ + super (parent); + } static ClassLoader getParentClassLoader() { ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();