summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
authorMuga Nishizawa <muga@f11vm.(none)>2010-09-27 17:55:48 +0900
committerMuga Nishizawa <muga@f11vm.(none)>2010-09-27 17:55:48 +0900
commit2736b88dd569cc0e11c9ea18a917ba4dfc1a095e (patch)
tree2090bb3f82153267ec13f419c2a7be0c07dda915 /java/src
parentee1ba5c0f22968b580200b001fc2b94a705b5521 (diff)
downloadmsgpack-python-2736b88dd569cc0e11c9ea18a917ba4dfc1a095e.tar.gz
edit Packer and Unpacker classes, and move org.msgpack.util.annotation.*.java to org.msgpack.util.codegen.*.java
Diffstat (limited to 'java/src')
-rw-r--r--java/src/main/java/org/msgpack/CustomConverter.java15
-rw-r--r--java/src/main/java/org/msgpack/CustomMessage.java11
-rw-r--r--java/src/main/java/org/msgpack/CustomUnpacker.java16
-rw-r--r--java/src/main/java/org/msgpack/MessageConverter.java4
-rw-r--r--java/src/main/java/org/msgpack/Packer.java19
-rw-r--r--java/src/main/java/org/msgpack/Unpacker.java26
-rw-r--r--java/src/main/java/org/msgpack/util/annotation/PackUnpackUtilException.java12
-rw-r--r--java/src/main/java/org/msgpack/util/codegen/BasicConstants.java160
-rw-r--r--java/src/main/java/org/msgpack/util/codegen/Constants.java7
-rw-r--r--java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java232
-rw-r--r--java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java189
-rw-r--r--java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenException.java12
-rw-r--r--java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenPacker.java18
-rw-r--r--java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenTemplate.java17
-rw-r--r--java/src/main/java/org/msgpack/util/codegen/MessagePackOptional.java (renamed from java/src/main/java/org/msgpack/util/annotation/MessagePackOptional.java)2
-rw-r--r--java/src/main/java/org/msgpack/util/codegen/MessagePackRequired.java (renamed from java/src/main/java/org/msgpack/util/annotation/MessagePackRequired.java)2
-rw-r--r--java/src/main/java/org/msgpack/util/codegen/MessagePackUnpackable.java (renamed from java/src/main/java/org/msgpack/util/annotation/MessagePackUnpackable.java)2
-rw-r--r--java/src/main/java/org/msgpack/util/codegen/PackUnpackUtil.java (renamed from java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java)18
-rw-r--r--java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java51
-rw-r--r--java/src/test/java/org/msgpack/util/codegen/TestMessagePackUnpackable.java (renamed from java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java)27
20 files changed, 766 insertions, 74 deletions
diff --git a/java/src/main/java/org/msgpack/CustomConverter.java b/java/src/main/java/org/msgpack/CustomConverter.java
index 4351464..abbc88a 100644
--- a/java/src/main/java/org/msgpack/CustomConverter.java
+++ b/java/src/main/java/org/msgpack/CustomConverter.java
@@ -17,23 +17,22 @@
//
package org.msgpack;
-import java.util.Map;
-import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
// FIXME package private?
public class CustomConverter {
- public static void register(Class target, MessageConverter converter) {
- map.put(target, converter);
+ private static ConcurrentHashMap<Class<?>, MessageConverter> map = new ConcurrentHashMap<Class<?>, MessageConverter>();
+
+ public static void register(Class<?> target, MessageConverter converter) {
+ map.putIfAbsent(target, converter);
}
- public static MessageConverter get(Class target) {
+ public static MessageConverter get(Class<?> target) {
return map.get(target);
}
- public static boolean isRegistered(Class target) {
+ public static boolean isRegistered(Class<?> target) {
return map.containsKey(target);
}
-
- private static Map<Class, MessageConverter> map = new HashMap<Class, MessageConverter>();
}
diff --git a/java/src/main/java/org/msgpack/CustomMessage.java b/java/src/main/java/org/msgpack/CustomMessage.java
index f87898c..53f8323 100644
--- a/java/src/main/java/org/msgpack/CustomMessage.java
+++ b/java/src/main/java/org/msgpack/CustomMessage.java
@@ -17,14 +17,19 @@
//
package org.msgpack;
+import java.lang.annotation.Annotation;
+
public class CustomMessage {
- public static void registerPacker(Class target, MessagePacker packer) {
+ public static void registerPacker(Class<?> target, MessagePacker packer) {
CustomPacker.register(target, packer);
}
- public static void registerTemplate(Class target, Template tmpl) {
+ public static void registerTemplate(Class<?> target, Template tmpl) {
CustomUnpacker.register(target, tmpl);
CustomConverter.register(target, tmpl);
}
-}
+ static boolean isAnnotated(Class<?> target, Class<? extends Annotation> with) {
+ return target.getAnnotation(with) != null;
+ }
+}
diff --git a/java/src/main/java/org/msgpack/CustomUnpacker.java b/java/src/main/java/org/msgpack/CustomUnpacker.java
index b6047b8..b45292b 100644
--- a/java/src/main/java/org/msgpack/CustomUnpacker.java
+++ b/java/src/main/java/org/msgpack/CustomUnpacker.java
@@ -17,23 +17,21 @@
//
package org.msgpack;
-import java.util.Map;
-import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
// FIXME package private?
public class CustomUnpacker {
- public static void register(Class target, MessageUnpacker converter) {
- map.put(target, converter);
+ private static ConcurrentHashMap<Class<?>, MessageUnpacker> map = new ConcurrentHashMap<Class<?>, MessageUnpacker>();
+
+ public static void register(Class<?> target, MessageUnpacker converter) {
+ map.putIfAbsent(target, converter);
}
- public static MessageUnpacker get(Class target) {
+ public static MessageUnpacker get(Class<?> target) {
return map.get(target);
}
- public static boolean isRegistered(Class target) {
+ public static boolean isRegistered(Class<?> target) {
return map.containsKey(target);
}
-
- private static Map<Class, MessageUnpacker> map = new HashMap<Class, MessageUnpacker>();
}
-
diff --git a/java/src/main/java/org/msgpack/MessageConverter.java b/java/src/main/java/org/msgpack/MessageConverter.java
index 8ad60ae..5e5f437 100644
--- a/java/src/main/java/org/msgpack/MessageConverter.java
+++ b/java/src/main/java/org/msgpack/MessageConverter.java
@@ -17,9 +17,7 @@
//
package org.msgpack;
-import java.io.IOException;
-
public interface MessageConverter {
- public Object convert(MessagePackObject from) throws MessageTypeException;
+ Object convert(MessagePackObject from) throws MessageTypeException;
}
diff --git a/java/src/main/java/org/msgpack/Packer.java b/java/src/main/java/org/msgpack/Packer.java
index b4526cd..9ea4ea2 100644
--- a/java/src/main/java/org/msgpack/Packer.java
+++ b/java/src/main/java/org/msgpack/Packer.java
@@ -485,22 +485,21 @@ public class Packer {
if(packer != null) {
packer.pack(this, o);
return this;
- } else if (isAnnotated(klass, MessagePackMessage.class)) {
+ } else if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) {
packer = ReflectionPacker.create(klass);
packer.pack(this, o);
return this;
- } else if (isAnnotated(klass, MessagePackDelegate.class)) {
+ } else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) {
+ // FIXME DelegatePacker
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
- } else if (isAnnotated(klass, MessagePackOrdinalEnum.class)) {
+ } else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) {
+ // FIXME OrdinalEnumPacker
throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
}
- CustomPacker.register(klass, packer);
- // FIXME check annotations -> code generation -> CustomMessage.registerPacker
-
+ if (packer != null) {
+ CustomMessage.registerPacker(klass, packer);
+ }
throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")");
}
-
- static boolean isAnnotated(Class<?> target, Class<? extends Annotation> with) {
- return target.getAnnotation(with) != null;
- }
+
}
diff --git a/java/src/main/java/org/msgpack/Unpacker.java b/java/src/main/java/org/msgpack/Unpacker.java
index 4e39748..add3312 100644
--- a/java/src/main/java/org/msgpack/Unpacker.java
+++ b/java/src/main/java/org/msgpack/Unpacker.java
@@ -18,12 +18,17 @@
package org.msgpack;
import java.lang.Iterable;
+import java.lang.annotation.Annotation;
import java.io.InputStream;
import java.io.IOException;
import java.util.Iterator;
import java.nio.ByteBuffer;
import java.math.BigInteger;
+import org.msgpack.annotation.MessagePackDelegate;
+import org.msgpack.annotation.MessagePackMessage;
+import org.msgpack.annotation.MessagePackOrdinalEnum;
+
/**
* Unpacker enables you to deserialize objects from stream.
*
@@ -573,7 +578,7 @@ public class Unpacker implements Iterable<MessagePackObject> {
obj.messageUnpack(this);
}
- final public Object unpack(Class klass) throws IOException, MessageTypeException, InstantiationException, IllegalAccessException {
+ final public Object unpack(Class<?> klass) throws IOException, MessageTypeException, InstantiationException, IllegalAccessException {
if(MessageUnpackable.class.isAssignableFrom(klass)) {
Object obj = klass.newInstance();
((MessageUnpackable)obj).messageUnpack(this);
@@ -584,14 +589,25 @@ public class Unpacker implements Iterable<MessagePackObject> {
if(unpacker != null) {
return unpacker.unpack(this);
}
-
- // FIXME check annotations -> code generation -> CustomMessage.registerTemplate
-
+
+ Template tmpl = null;
+ if (CustomMessage.isAnnotated(klass, MessagePackMessage.class)) {
+ tmpl = ReflectionTemplate.create(klass);
+ return tmpl.unpack(this);
+ } else if (CustomMessage.isAnnotated(klass, MessagePackDelegate.class)) {
+ // FIXME DelegateTemplate
+ throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
+ } else if (CustomMessage.isAnnotated(klass, MessagePackOrdinalEnum.class)) {
+ // FIXME OrdinalEnumTemplate
+ throw new UnsupportedOperationException("not supported yet. : " + klass.getName());
+ }
+ if (tmpl != null) {
+ CustomMessage.registerTemplate(klass, tmpl);
+ }
MessageConverter converter = CustomConverter.get(klass);
if(converter != null) {
return converter.convert(unpackObject());
}
-
throw new MessageTypeException();
}
}
diff --git a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtilException.java b/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtilException.java
deleted file mode 100644
index df3af05..0000000
--- a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtilException.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.msgpack.util.annotation;
-
-public class PackUnpackUtilException extends RuntimeException {
-
- public PackUnpackUtilException(String reason) {
- super(reason);
- }
-
- public PackUnpackUtilException(String reason, Throwable t) {
- super(reason, t);
- }
-}
diff --git a/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java b/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java
new file mode 100644
index 0000000..53a8a4c
--- /dev/null
+++ b/java/src/main/java/org/msgpack/util/codegen/BasicConstants.java
@@ -0,0 +1,160 @@
+package org.msgpack.util.codegen;
+
+public interface BasicConstants {
+
+ String KEYWORD_MODIFIER_PUBLIC = "public";
+
+ String KEYWORD_CATCH = "catch";
+
+ String KEYWORD_ELSE = "else";
+
+ String KEYWORD_ELSEIF = "else if";
+
+ String KEYWORD_FOR = "for";
+
+ String KEYWORD_IF = "if";
+
+ String KEYWORD_INSTANCEOF = "instanceof";
+
+ String KEYWORD_NEW = "new";
+
+ String KEYWORD_NULL = "null";
+
+ String KEYWORD_THROW = "throw";
+
+ String KEYWORD_THROWS = "throws";
+
+ String KEYWORD_TRY = "try";
+
+ String CHAR_NAME_SPACE = " ";
+
+ String CHAR_NAME_COMMA = ",";
+
+ String CHAR_NAME_EQUAL = "=";
+
+ String CHAR_NAME_PLUS = "+";
+
+ String CHAR_NAME_LESSTHAN = "<";
+
+ String CHAR_NAME_RIGHT_PARENTHESIS = ")";
+
+ String CHAR_NAME_LEFT_PARENTHESIS = "(";
+
+ String CHAR_NAME_RIGHT_CURLY_BRACKET = "}";
+
+ String CHAR_NAME_LEFT_CURLY_BRACKET = "{";
+
+ String CHAR_NAME_RIGHT_SQUARE_BRACKET = "]";
+
+ String CHAR_NAME_LEFT_SQUARE_BRACKET = "[";
+
+ String CHAR_NAME_DOT = ".";
+
+ String CHAR_NAME_SEMICOLON = ";";
+
+ String VARIABLE_NAME_PK = "_$$_pk";
+
+ String VARIABLE_NAME_OBJ = "_$$_obj";
+
+ String VARIABLE_NAME_TARGET = "_$$_target";
+
+ String VARIABLE_NAME_SIZE = "_$$_len";
+
+ String VARIABLE_NAME_ARRAY = "_$$_ary";
+
+ String VARIABLE_NAME_LIST = "_$$_list";
+
+ String VARIABLE_NAME_MAP = "_$$_map";
+
+ String VARIABLE_NAME_KEY = "_$$_key";
+
+ String VARIABLE_NAME_VAL = "_$$_val";
+
+ String VARIABLE_NAME_ITER = "_$$_iter";
+
+ String VARIABLE_NAME_MPO = "_$$_mpo";
+
+ String VARIABLE_NAME_I = "i";
+
+ String METHOD_NAME_VALUEOF = "valueOf";
+
+ String METHOD_NAME_ADD = "add";
+
+ String METHOD_NAME_PUT = "put";
+
+ String METHOD_NAME_GET = "get";
+
+ String METHOD_NAME_SIZE = "size";
+
+ String METHOD_NAME_KEYSET = "keySet";
+
+ String METHOD_NAME_ITERATOR = "iterator";
+
+ String METHOD_NAME_HASNEXT = "hasNext";
+
+ String METHOD_NAME_NEXT = "next";
+
+ String METHOD_NAME_MSGPACK = "messagePack";
+
+ String METHOD_NAME_MSGUNPACK = "messageUnpack";
+
+ String METHOD_NAME_MSGCONVERT = "messageConvert";
+
+ String METHOD_NAME_PACK = "pack";
+
+ String METHOD_NAME_PACKARRAY = "packArray";
+
+ String METHOD_NAME_UNPACK = "unpack";
+
+ String METHOD_NAME_UNPACKBOOLEAN = "unpackBoolean";
+
+ String METHOD_NAME_UNPACKBYTE = "unpackByte";
+
+ String METHOD_NAME_UNPACKDOUBLE = "unpackDouble";
+
+ String METHOD_NAME_UNPACKFLOAT = "unpackFloat";
+
+ String METHOD_NAME_UNPACKINT = "unpackInt";
+
+ String METHOD_NAME_UNPACKLONG = "unpackLong";
+
+ String METHOD_NAME_UNPACKSHORT = "unpackShort";
+
+ String METHOD_NAME_UNPACKSTRING = "unpackString";
+
+ String METHOD_NAME_UNPACKBIGINTEGER = "unpackBigInteger";
+
+ String METHOD_NAME_UNPACKOBJECT = "unpackObject";
+
+ String METHOD_NAME_UNPACKBYTEARRAY = "unpackByteArray";
+
+ String METHOD_NAME_UNPACKARRAY = "unpackArray";
+
+ String METHOD_NAME_UNPACKMAP = "unpackMap";
+
+ String METHOD_NAME_ASARRAY = "asArray";
+
+ String METHOD_NAME_ASBOOLEAN = "asBoolean";
+
+ String METHOD_NAME_ASBYTE = "asByte";
+
+ String METHOD_NAME_ASSHORT = "asShort";
+
+ String METHOD_NAME_ASINT = "asInt";
+
+ String METHOD_NAME_ASFLOAT = "asFloat";
+
+ String METHOD_NAME_ASLONG = "asLong";
+
+ String METHOD_NAME_ASDOUBLE = "asDouble";
+
+ String METHOD_NAME_ASSTRING = "asString";
+
+ String METHOD_NAME_ASBYTEARRAY = "asByteArray";
+
+ String METHOD_NAME_ASBIGINTEGER = "asBigInteger";
+
+ String METHOD_NAME_ASLIST = "asList";
+
+ String METHOD_NAME_ASMAP = "asMap";
+}
diff --git a/java/src/main/java/org/msgpack/util/codegen/Constants.java b/java/src/main/java/org/msgpack/util/codegen/Constants.java
new file mode 100644
index 0000000..ddeef31
--- /dev/null
+++ b/java/src/main/java/org/msgpack/util/codegen/Constants.java
@@ -0,0 +1,7 @@
+package org.msgpack.util.codegen;
+
+public interface Constants extends BasicConstants {
+ String POSTFIX_TYPE_NAME_PACKER = "_$$_Packer";
+
+ String POSTFIX_TYPE_NAME_ENHANCER = "_$$_Enhanced";
+}
diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java
new file mode 100644
index 0000000..9f63242
--- /dev/null
+++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGen.java
@@ -0,0 +1,232 @@
+package org.msgpack.util.codegen;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javassist.CannotCompileException;
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.CtMethod;
+import javassist.CtNewConstructor;
+import javassist.CtNewMethod;
+import javassist.NotFoundException;
+
+import org.msgpack.MessagePacker;
+import org.msgpack.Packer;
+import org.msgpack.Template;
+
+public class DynamicCodeGen extends DynamicCodeGenBase implements Constants {
+
+ private static DynamicCodeGen INSTANCE;
+
+ private static AtomicInteger COUNTER;
+
+ public static DynamicCodeGen getInstance() {
+ if (INSTANCE == null) {
+ INSTANCE = new DynamicCodeGen();
+ }
+ return INSTANCE;
+ }
+
+ private ClassPool pool;
+
+ private DynamicCodeGen() {
+ this.pool = ClassPool.getDefault();
+ }
+
+ public Class<?> generateMessagePackerClass(Class<?> origClass) {
+ try {
+ String origName = origClass.getName();
+ String packerName = origName + POSTFIX_TYPE_NAME_PACKER;
+ checkClassValidation(origClass);
+ checkDefaultConstructorValidation(origClass);
+ CtClass packerCtClass = pool.makeClass(packerName);
+ setInterface(packerCtClass, MessagePacker.class);
+ addDefaultConstructor(packerCtClass);
+ Field[] fields = getDeclaredFields(origClass);
+ addPackMethod(packerCtClass, origClass, fields);
+ return createClass(packerCtClass);
+ } catch (NotFoundException e) {
+ throw new DynamicCodeGenException(e.getMessage(), e);
+ } catch (CannotCompileException e) {
+ throw new DynamicCodeGenException(e.getMessage(), e);
+ }
+ }
+
+ public Class<?> generateTemplateClass(Class<?> origClass) {
+ try {
+ String origName = origClass.getName();
+ String packerName = origName + POSTFIX_TYPE_NAME_PACKER;
+ checkClassValidation(origClass);
+ checkDefaultConstructorValidation(origClass);
+ CtClass packerCtClass = pool.makeClass(packerName);
+ setInterface(packerCtClass, Template.class);
+ addDefaultConstructor(packerCtClass);
+ Field[] fields = getDeclaredFields(origClass);
+ addPackMethod(packerCtClass, origClass, fields);
+ return createClass(packerCtClass);
+ } catch (NotFoundException e) {
+ throw new DynamicCodeGenException(e.getMessage(), e);
+ } catch (CannotCompileException e) {
+ throw new DynamicCodeGenException(e.getMessage(), e);
+ }
+ }
+
+ private void checkClassValidation(Class<?> origClass) {
+ // not public, abstract, final
+ int mod = origClass.getModifiers();
+ if ((!(Modifier.isPublic(mod) || Modifier.isProtected(mod)))
+ || Modifier.isAbstract(mod) || Modifier.isFinal(mod)) {
+ throwClassValidationException(origClass,
+ "it must be a public class");
+ }
+ // interface, enum
+ if (origClass.isInterface() || origClass.isEnum()) {
+ throwClassValidationException(origClass,
+ "it must not be an interface or enum");
+ }
+ }
+
+ private static void throwClassValidationException(Class<?> origClass,
+ String msg) {
+ throw new DynamicCodeGenException(msg + ": " + origClass.getName());
+ }
+
+ private void checkDefaultConstructorValidation(Class<?> origClass) {
+ Constructor<?> cons = null;
+ try {
+ cons = origClass.getDeclaredConstructor(new Class[0]);
+ } catch (Exception e1) {
+ throwConstructoValidationException(origClass);
+ }
+
+ int mod = cons.getModifiers();
+ if (!(Modifier.isPublic(mod) || Modifier.isProtected(mod))) {
+ throwConstructoValidationException(origClass);
+ }
+ }
+
+ private static void throwConstructoValidationException(Class<?> origClass) {
+ throw new DynamicCodeGenException(
+ "it must have a public zero-argument constructor: "
+ + origClass.getName());
+ }
+
+ private void setInterface(CtClass packerCtClass, Class<?> infClass)
+ throws NotFoundException {
+ CtClass infCtClass = pool.get(infClass.getName());
+ packerCtClass.addInterface(infCtClass);
+ }
+
+ private void addDefaultConstructor(CtClass enhCtClass)
+ throws CannotCompileException {
+ CtConstructor newCtCons = CtNewConstructor
+ .defaultConstructor(enhCtClass);
+ enhCtClass.addConstructor(newCtCons);
+ }
+
+ private Field[] getDeclaredFields(Class<?> origClass) {
+ ArrayList<Field> allFields = new ArrayList<Field>();
+ Class<?> nextClass = origClass;
+ while (nextClass != Object.class) {
+ Field[] fields = nextClass.getDeclaredFields();
+ for (Field field : fields) {
+ try {
+ checkFieldValidation(field, allFields);
+ allFields.add(field);
+ } catch (DynamicCodeGenException e) { // ignore
+ }
+ }
+ nextClass = nextClass.getSuperclass();
+ }
+ return allFields.toArray(new Field[0]);
+ }
+
+ private void checkFieldValidation(Field field, List<Field> fields) {
+ // check modifiers (public or protected)
+ int mod = field.getModifiers();
+ if ((!(Modifier.isPublic(mod) || Modifier.isProtected(mod)))
+ || Modifier.isStatic(mod) || Modifier.isFinal(mod)
+ || Modifier.isTransient(mod) || field.isSynthetic()) {
+ throwFieldValidationException(field);
+ }
+ // check same name
+ for (Field f : fields) {
+ if (f.getName().equals(field.getName())) {
+ throwFieldValidationException(field);
+ }
+ }
+ }
+
+ private static void throwFieldValidationException(Field field) {
+ throw new DynamicCodeGenException("it must be a public field: "
+ + field.getName());
+ }
+
+ private void addPackMethod(CtClass packerCtClass, Class<?> c, Field[] fs)
+ throws CannotCompileException, NotFoundException {
+ StringBuilder sb = new StringBuilder();
+ sb.append(KEYWORD_MODIFIER_PUBLIC);
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(void.class.getName());
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(METHOD_NAME_PACK);
+ sb.append(CHAR_NAME_LEFT_PARENTHESIS);
+ sb.append(Packer.class.getName());
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(VARIABLE_NAME_PK);
+ sb.append(CHAR_NAME_COMMA);
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(Object.class.getName());
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(VARIABLE_NAME_OBJ);
+ sb.append(CHAR_NAME_RIGHT_PARENTHESIS);
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(KEYWORD_THROWS);
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(IOException.class.getName());
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(CHAR_NAME_LEFT_CURLY_BRACKET);
+ sb.append(CHAR_NAME_SPACE);
+ insertPackMethodBody(sb, c, fs);
+ sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET);
+ // System.out.println("pack method: " + sb.toString());
+ CtMethod newCtMethod = CtNewMethod.make(sb.toString(), packerCtClass);
+ packerCtClass.addMethod(newCtMethod);
+ }
+
+ private void insertPackMethodBody(StringBuilder sb, Class<?> c, Field[] fs) {
+ insertLocalVariableDecl(sb, c, VARIABLE_NAME_TARGET);
+ StringBuilder mc = new StringBuilder();
+ insertTypeCast(mc, c, VARIABLE_NAME_OBJ);
+ insertValueInsertion(sb, mc.toString());
+ insertSemicolon(sb);
+ insertMethodCall(sb, VARIABLE_NAME_PK, METHOD_NAME_PACKARRAY,
+ new String[] { new Integer(fs.length).toString() });
+ insertSemicolon(sb);
+ for (Field f : fs) {
+ insertCodeOfPackCall(sb, f);
+ }
+ }
+
+ private void insertCodeOfPackCall(StringBuilder sb, Field field) {
+ StringBuilder aname = new StringBuilder();
+ aname.append(VARIABLE_NAME_TARGET);
+ aname.append(CHAR_NAME_DOT);
+ aname.append(field.getName());
+ insertMethodCall(sb, VARIABLE_NAME_PK, METHOD_NAME_PACK,
+ new String[] { aname.toString() });
+ insertSemicolon(sb);
+ }
+
+ private Class<?> createClass(CtClass packerCtClass)
+ throws CannotCompileException {
+ return packerCtClass.toClass(null, null);
+ }
+}
diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java
new file mode 100644
index 0000000..24ae579
--- /dev/null
+++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenBase.java
@@ -0,0 +1,189 @@
+package org.msgpack.util.codegen;
+
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Map;
+
+public class DynamicCodeGenBase implements BasicConstants {
+ public DynamicCodeGenBase() {
+ }
+
+ public void insertSemicolon(StringBuilder sb) {
+ sb.append(CHAR_NAME_SEMICOLON);
+ sb.append(CHAR_NAME_SPACE);
+ }
+
+ public void insertPublicFieldDecl(StringBuilder sb, Class<?> type,
+ String name) {
+ sb.append(KEYWORD_MODIFIER_PUBLIC);
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(type.getName());
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(name);
+ }
+
+ public void insertLocalVariableDecl(StringBuilder sb, Class<?> type,
+ String name) {
+ sb.append(type.getName());
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(name);
+ }
+
+ public void insertValueInsertion(StringBuilder sb, String expr) {
+ // = expr
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(CHAR_NAME_EQUAL);
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(expr);
+ }
+
+ public void insertDefaultConsCall(StringBuilder sb, Class<?> type) {
+ // new tname()
+ insertConsCall(sb, type, null);
+ }
+
+ public void insertConsCall(StringBuilder sb, Class<?> type, String expr) {
+ // new tname(expr)
+ sb.append(KEYWORD_NEW);
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(type.getName());
+ sb.append(CHAR_NAME_LEFT_PARENTHESIS);
+ if (expr != null) {
+ sb.append(expr);
+ }
+ sb.append(CHAR_NAME_RIGHT_PARENTHESIS);
+ }
+
+ public void insertMethodCall(StringBuilder sb, String tname, String mname,
+ String[] anames) {
+ // tname.mname(anames[0], anames[1], ...)
+ int len = anames.length;
+ sb.append(tname);
+ sb.append(CHAR_NAME_DOT);
+ sb.append(mname);
+ sb.append(CHAR_NAME_LEFT_PARENTHESIS);
+ for (int i = 0; i < len; ++i) {
+ sb.append(anames[i]);
+ if (i + 1 != len) {
+ sb.append(CHAR_NAME_COMMA);
+ sb.append(CHAR_NAME_SPACE);
+ }
+ }
+ sb.append(CHAR_NAME_RIGHT_PARENTHESIS);
+ }
+
+ public void insertTypeCast(StringBuilder sb, Class<?> type) {
+ // (type)
+ sb.append(CHAR_NAME_LEFT_PARENTHESIS);
+ sb.append(type.getName());
+ sb.append(CHAR_NAME_RIGHT_PARENTHESIS);
+ }
+
+ public void insertTypeCast(StringBuilder sb, Class<?> type, String varName) {
+ // ((type)var)
+ sb.append(CHAR_NAME_LEFT_PARENTHESIS);
+ sb.append(CHAR_NAME_LEFT_PARENTHESIS);
+ sb.append(type.getName());
+ sb.append(CHAR_NAME_RIGHT_PARENTHESIS);
+ sb.append(varName);
+ sb.append(CHAR_NAME_RIGHT_PARENTHESIS);
+ }
+
+ public void insertTypeConvToObjectType(StringBuilder sb, Class<?> type,
+ String expr) throws DynamicCodeGenException {
+ if (type.isPrimitive()) { // primitive type
+ if (type.equals(boolean.class)) {
+ // new Boolean(expr)
+ insertConsCall(sb, Boolean.class, expr);
+ } else if (type.equals(byte.class)) {
+ insertConsCall(sb, Byte.class, expr);
+ } else if (type.equals(short.class)) {
+ insertConsCall(sb, Short.class, expr);
+ } else if (type.equals(int.class)) {
+ insertConsCall(sb, Integer.class, expr);
+ } else if (type.equals(long.class)) {
+ insertConsCall(sb, Long.class, expr);
+ } else if (type.equals(float.class)) {
+ insertConsCall(sb, Float.class, expr);
+ } else if (type.equals(double.class)) {
+ insertConsCall(sb, Double.class, expr);
+ } else {
+ throw new DynamicCodeGenException("Type error: "
+ + type.getName());
+ }
+ } else { // reference type
+ sb.append(expr);
+ }
+ }
+
+ public void insertTryCatchBlocks(StringBuilder sb, String tryBody,
+ List<Class<?>> types, List<String> names, List<String> catchBodies) {
+ int len = types.size();
+ sb.append(KEYWORD_TRY);
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(CHAR_NAME_LEFT_CURLY_BRACKET);
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(tryBody);
+ sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET);
+ sb.append(CHAR_NAME_SPACE);
+ for (int i = 0; i < len; ++i) {
+ sb.append(KEYWORD_CATCH);
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(CHAR_NAME_LEFT_PARENTHESIS);
+ sb.append(types.get(i).getName());
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(names.get(i));
+ sb.append(CHAR_NAME_RIGHT_PARENTHESIS);
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(CHAR_NAME_LEFT_CURLY_BRACKET);
+ sb.append(CHAR_NAME_SPACE);
+ sb.append(catchBodies.get(i));
+ sb.append(CHAR_NAME_RIGHT_CURLY_BRACKET);
+ sb.append(CHAR_NAME_SPACE);
+ }
+ }
+
+ public String getAsMethod(Class<?> c) throws DynamicCodeGenException {
+ if (c.equals(boolean.class)) {
+ return METHOD_NAME_ASBOOLEAN;
+ } else if (c.equals(byte.class)) {
+ return METHOD_NAME_ASBYTE;
+ } else if (c.equals(short.class)) {
+ return METHOD_NAME_ASSHORT;
+ } else if (c.equals(int.class)) {
+ return METHOD_NAME_ASINT;
+ } else if (c.equals(float.class)) {
+ return METHOD_NAME_ASFLOAT;
+ } else if (c.equals(long.class)) {
+ return METHOD_NAME_ASLONG;
+ } else if (c.equals(double.class)) {
+ return METHOD_NAME_ASDOUBLE;
+ } else if (c.equals(Boolean.class)) {
+ return METHOD_NAME_ASBOOLEAN;
+ } else if (c.equals(Byte.class)) {
+ return METHOD_NAME_ASBYTE;
+ } else if (c.equals(Short.class)) {
+ return METHOD_NAME_ASSHORT;
+ } else if (c.equals(Integer.class)) {
+ return METHOD_NAME_ASINT;
+ } else if (c.equals(Float.class)) {
+ return METHOD_NAME_ASFLOAT;
+ } else if (c.equals(Long.class)) {
+ return METHOD_NAME_ASLONG;
+ } else if (c.equals(Double.class)) {
+ return METHOD_NAME_ASDOUBLE;
+ } else if (c.equals(String.class)) {
+ return METHOD_NAME_ASSTRING;
+ } else if (c.equals(byte[].class)) {
+ return METHOD_NAME_ASBYTEARRAY;
+ } else if (c.equals(BigInteger.class)) {
+ return METHOD_NAME_ASBIGINTEGER;
+ } else if (List.class.isAssignableFrom(c)) {
+ return METHOD_NAME_ASLIST;
+ } else if (Map.class.isAssignableFrom(c)) {
+ return METHOD_NAME_ASMAP;
+ } else {
+ throw new DynamicCodeGenException("Type error: " + c.getName());
+ }
+ }
+}
diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenException.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenException.java
new file mode 100644
index 0000000..1877ed5
--- /dev/null
+++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenException.java
@@ -0,0 +1,12 @@
+package org.msgpack.util.codegen;
+
+public class DynamicCodeGenException extends RuntimeException {
+
+ public DynamicCodeGenException(String reason) {
+ super(reason);
+ }
+
+ public DynamicCodeGenException(String reason, Throwable t) {
+ super(reason, t);
+ }
+}
diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenPacker.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenPacker.java
new file mode 100644
index 0000000..2a014b8
--- /dev/null
+++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenPacker.java
@@ -0,0 +1,18 @@
+package org.msgpack.util.codegen;
+
+import org.msgpack.MessagePacker;
+
+public class DynamicCodeGenPacker {
+
+ public static MessagePacker create(Class<?> c) {
+ try {
+ DynamicCodeGen gen = DynamicCodeGen.getInstance();
+ Class<?> packerClass = gen.generateMessagePackerClass(c);
+ return (MessagePacker)packerClass.newInstance();
+ } catch (InstantiationException e) {
+ throw new DynamicCodeGenException(e.getMessage(), e);
+ } catch (IllegalAccessException e) {
+ throw new DynamicCodeGenException(e.getMessage(), e);
+ }
+ }
+}
diff --git a/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenTemplate.java b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenTemplate.java
new file mode 100644
index 0000000..1e12f2e
--- /dev/null
+++ b/java/src/main/java/org/msgpack/util/codegen/DynamicCodeGenTemplate.java
@@ -0,0 +1,17 @@
+package org.msgpack.util.codegen;
+
+import org.msgpack.Template;
+
+public class DynamicCodeGenTemplate {
+ public static Template create(Class<?> c) {
+ try {
+ DynamicCodeGen gen = DynamicCodeGen.getInstance();
+ Class<?> tmplClass = gen.generateTemplateClass(c);
+ return (Template) tmplClass.newInstance();
+ } catch (InstantiationException e) {
+ throw new DynamicCodeGenException(e.getMessage(), e);
+ } catch (IllegalAccessException e) {
+ throw new DynamicCodeGenException(e.getMessage(), e);
+ }
+ }
+}
diff --git a/java/src/main/java/org/msgpack/util/annotation/MessagePackOptional.java b/java/src/main/java/org/msgpack/util/codegen/MessagePackOptional.java
index a565292..736c2ed 100644
--- a/java/src/main/java/org/msgpack/util/annotation/MessagePackOptional.java
+++ b/java/src/main/java/org/msgpack/util/codegen/MessagePackOptional.java
@@ -1,4 +1,4 @@
-package org.msgpack.util.annotation;
+package org.msgpack.util.codegen;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/java/src/main/java/org/msgpack/util/annotation/MessagePackRequired.java b/java/src/main/java/org/msgpack/util/codegen/MessagePackRequired.java
index 03e50cf..a0c956f 100644
--- a/java/src/main/java/org/msgpack/util/annotation/MessagePackRequired.java
+++ b/java/src/main/java/org/msgpack/util/codegen/MessagePackRequired.java
@@ -1,4 +1,4 @@
-package org.msgpack.util.annotation;
+package org.msgpack.util.codegen;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/java/src/main/java/org/msgpack/util/annotation/MessagePackUnpackable.java b/java/src/main/java/org/msgpack/util/codegen/MessagePackUnpackable.java
index 77f6e6d..e5aff40 100644
--- a/java/src/main/java/org/msgpack/util/annotation/MessagePackUnpackable.java
+++ b/java/src/main/java/org/msgpack/util/codegen/MessagePackUnpackable.java
@@ -1,4 +1,4 @@
-package org.msgpack.util.annotation;
+package org.msgpack.util.codegen;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java b/java/src/main/java/org/msgpack/util/codegen/PackUnpackUtil.java
index 0aeb6d8..2062ee4 100644
--- a/java/src/main/java/org/msgpack/util/annotation/PackUnpackUtil.java
+++ b/java/src/main/java/org/msgpack/util/codegen/PackUnpackUtil.java
@@ -1,4 +1,4 @@
-package org.msgpack.util.annotation;
+package org.msgpack.util.codegen;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -230,7 +230,7 @@ public class PackUnpackUtil {
}
private static void throwClassValidationException(Class<?> origClass) {
- throw new PackUnpackUtilException(
+ throw new DynamicCodeGenException(
"it must be a public class and have @"
+ MessagePackUnpackable.class.getName() + ": "
+ origClass.getName());
@@ -260,7 +260,7 @@ public class PackUnpackUtil {
private static void throwConstructoValidationException(
Class<?> origClass) {
- throw new PackUnpackUtilException(
+ throw new DynamicCodeGenException(
"it must have a public zero-argument constructor: "
+ origClass.getName());
}
@@ -295,7 +295,7 @@ public class PackUnpackUtil {
try {
checkFieldValidation(field, allFields);
allFields.add(field);
- } catch (PackUnpackUtilException e) { // ignore
+ } catch (DynamicCodeGenException e) { // ignore
}
}
nextClass = nextClass.getSuperclass();
@@ -320,7 +320,7 @@ public class PackUnpackUtil {
}
private static void throwFieldValidationException(Field field) {
- throw new PackUnpackUtilException("it must be a public field: "
+ throw new DynamicCodeGenException("it must be a public field: "
+ field.getName());
}
@@ -1267,9 +1267,9 @@ public class PackUnpackUtil {
try {
enhClass = enhancer.generate(origClass, packUnpackable);
} catch (NotFoundException e) {
- throw new PackUnpackUtilException(e.getMessage(), e);
+ throw new DynamicCodeGenException(e.getMessage(), e);
} catch (CannotCompileException e) {
- throw new PackUnpackUtilException(e.getMessage(), e);
+ throw new DynamicCodeGenException(e.getMessage(), e);
}
// set the generated class to the cache
enhancer.setCache(origName, enhClass);
@@ -1306,9 +1306,9 @@ public class PackUnpackUtil {
// create a new object of the generated class
return enhClass.newInstance();
} catch (InstantiationException e) {
- throw new PackUnpackUtilException(e.getMessage(), e);
+ throw new DynamicCodeGenException(e.getMessage(), e);
} catch (IllegalAccessException e) {
- throw new PackUnpackUtilException(e.getMessage(), e);
+ throw new DynamicCodeGenException(e.getMessage(), e);
}
}
diff --git a/java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java b/java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java
new file mode 100644
index 0000000..d4e9c16
--- /dev/null
+++ b/java/src/test/java/org/msgpack/util/codegen/TestDynamicCodeGenPacker.java
@@ -0,0 +1,51 @@
+package org.msgpack.util.codegen;
+
+import static org.msgpack.Templates.tString;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.junit.Test;
+import org.msgpack.MessagePacker;
+import org.msgpack.Packer;
+import org.msgpack.ReflectionPacker;
+import org.msgpack.ReflectionTemplate;
+import org.msgpack.Template;
+import org.msgpack.Unpacker;
+
+import junit.framework.TestCase;
+
+
+public class TestDynamicCodeGenPacker extends TestCase {
+ public static class StringFieldClass {
+ public String s1;
+ public String s2;
+ public StringFieldClass() { }
+ }
+
+ @Test
+ public void testPackConvert() throws Exception {
+ tString(); // FIXME link StringTemplate
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ MessagePacker packer = DynamicCodeGenPacker.create(StringFieldClass.class);
+
+ StringFieldClass src = new StringFieldClass();
+
+ src.s1 = "kumofs";
+ src.s2 = "frsyuki";
+
+ packer.pack(new Packer(out), src);
+
+ Template tmpl = ReflectionTemplate.create(StringFieldClass.class);
+
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+
+ Object obj = tmpl.unpack(new Unpacker(in));
+ assertEquals(obj.getClass(), StringFieldClass.class);
+
+ StringFieldClass dst = (StringFieldClass)obj;
+ assertEquals(src.s1, dst.s1);
+ assertEquals(src.s2, dst.s2);
+ }
+}
diff --git a/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java b/java/src/test/java/org/msgpack/util/codegen/TestMessagePackUnpackable.java
index 08c4fa8..7e0bacc 100644
--- a/java/src/test/java/org/msgpack/util/annotation/TestMessagePackUnpackable.java
+++ b/java/src/test/java/org/msgpack/util/codegen/TestMessagePackUnpackable.java
@@ -1,4 +1,4 @@
-package org.msgpack.util.annotation;
+package org.msgpack.util.codegen;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -16,6 +16,9 @@ import org.msgpack.MessagePackObject;
import org.msgpack.MessageUnpackable;
import org.msgpack.Packer;
import org.msgpack.Unpacker;
+import org.msgpack.util.codegen.MessagePackUnpackable;
+import org.msgpack.util.codegen.PackUnpackUtil;
+import org.msgpack.util.codegen.DynamicCodeGenException;
public class TestMessagePackUnpackable extends TestCase {
@@ -350,7 +353,7 @@ public class TestMessagePackUnpackable extends TestCase {
try {
PackUnpackUtil.newEnhancedInstance(NoDefaultConstructorClass.class);
fail();
- } catch (PackUnpackUtilException e) {
+ } catch (DynamicCodeGenException e) {
assertTrue(true);
}
assertTrue(true);
@@ -358,7 +361,7 @@ public class TestMessagePackUnpackable extends TestCase {
PackUnpackUtil
.newEnhancedInstance(PrivateDefaultConstructorClass.class);
fail();
- } catch (PackUnpackUtilException e) {
+ } catch (DynamicCodeGenException e) {
assertTrue(true);
}
assertTrue(true);
@@ -366,7 +369,7 @@ public class TestMessagePackUnpackable extends TestCase {
PackUnpackUtil
.newEnhancedInstance(ProtectedDefaultConstructorClass.class);
assertTrue(true);
- } catch (PackUnpackUtilException e) {
+ } catch (DynamicCodeGenException e) {
fail();
}
assertTrue(true);
@@ -374,7 +377,7 @@ public class TestMessagePackUnpackable extends TestCase {
PackUnpackUtil
.newEnhancedInstance(PackageDefaultConstructorClass.class);
fail();
- } catch (PackUnpackUtilException e) {
+ } catch (DynamicCodeGenException e) {
assertTrue(true);
}
assertTrue(true);
@@ -409,21 +412,21 @@ public class TestMessagePackUnpackable extends TestCase {
try {
PackUnpackUtil.newEnhancedInstance(PrivateModifierClass.class);
fail();
- } catch (PackUnpackUtilException e) {
+ } catch (DynamicCodeGenException e) {
assertTrue(true);
}
assertTrue(true);
try {
PackUnpackUtil.newEnhancedInstance(ProtectedModifierClass.class);
assertTrue(true);
- } catch (PackUnpackUtilException e) {
+ } catch (DynamicCodeGenException e) {
fail();
}
assertTrue(true);
try {
PackUnpackUtil.newEnhancedInstance(PackageModifierClass.class);
fail();
- } catch (PackUnpackUtilException e) {
+ } catch (DynamicCodeGenException e) {
assertTrue(true);
}
assertTrue(true);
@@ -448,14 +451,14 @@ public class TestMessagePackUnpackable extends TestCase {
try {
PackUnpackUtil.newEnhancedInstance(FinalModifierClass.class);
fail();
- } catch (PackUnpackUtilException e) {
+ } catch (DynamicCodeGenException e) {
assertTrue(true);
}
assertTrue(true);
try {
PackUnpackUtil.newEnhancedInstance(AbstractModifierClass.class);
fail();
- } catch (PackUnpackUtilException e) {
+ } catch (DynamicCodeGenException e) {
assertTrue(true);
}
assertTrue(true);
@@ -474,14 +477,14 @@ public class TestMessagePackUnpackable extends TestCase {
try {
PackUnpackUtil.newEnhancedInstance(SampleInterface.class);
fail();
- } catch (PackUnpackUtilException e) {
+ } catch (DynamicCodeGenException e) {
assertTrue(true);
}
assertTrue(true);
try {
PackUnpackUtil.newEnhancedInstance(SampleEnum.class);
fail();
- } catch (PackUnpackUtilException e) {
+ } catch (DynamicCodeGenException e) {
assertTrue(true);
}
assertTrue(true);