[jboss-user] [Javassist user questions] - serialVersionUID issue
spampete
do-not-reply at jboss.com
Thu Dec 4 04:23:42 EST 2008
Hi all,
I have released a small memory leak detector on http://www.qarks.com web site, which is using javassist. Despite using the serialVersionUID helper, recent tests showed a remaining issue with some serializable classes during unmarshalling, with InvalidClassException due to inconsistent serialVersionUID.
I've had a look to Sun's ObjectStreamClass implementation (JDK 1.6) and found indeed some differences explaining the situation. Actually, I do not know if the issue is on Sun's side, not respecting its own spec, or not, but the fix I brough does work on my test bench.
I'd be interested in having your feedback, all of you guys !!
Meanwhile, here is the method I changed within javassist serialVersionUID helper, which I will also send to Shigeru Chiba by email:
|
| static long calculateDefault(CtClass clazz) throws CannotCompileException {
| ByteArrayOutputStream bout;
| try {
| bout = new ByteArrayOutputStream();
| DataOutputStream out = new DataOutputStream(bout);
| ClassFile classFile = clazz.getClassFile();
|
| String javaName = javaName(clazz);
| out.writeUTF(javaName);
|
| CtMethod[] methods = clazz.getDeclaredMethods();
|
| int classMods = clazz.getModifiers();
| if ((classMods & Modifier.INTERFACE) != 0) {
| classMods = (methods.length > 0) ?
| (classMods | Modifier.ABSTRACT) :
| (classMods & ~Modifier.ABSTRACT);
| }
| out.writeInt(classMods);
|
| if (!clazz.isArray()){
| String[] interfaces = classFile.getInterfaces();
| for (int i = 0; i < interfaces.length; ++i)
| interfaces = javaName(interfaces);
|
| Arrays.sort(interfaces);
| for (int i = 0; i < interfaces.length; ++i) {
| out.writeUTF(interfaces);
| }
| }
|
| CtField[] fields = clazz.getDeclaredFields();
| Arrays.sort(fields, new Comparator() {
| public int compare(Object o1, Object o2) {
| CtField field1 = (CtField) o1;
| CtField field2 = (CtField) o2;
| return field1.getName().compareTo(field2.getName());
| }
|
| });
| for (int i = 0; i < fields.length; ++i) {
| CtField field = fields;
| int mods = field.getModifiers();
| if (((mods & 0x2) == 0) || ((mods & 0x88) == 0)) {
| out.writeUTF(field.getName());
| out.writeInt(mods);
| out.writeUTF(field.getFieldInfo2().getDescriptor());
| }
|
| }
|
| if (classFile.getStaticInitializer() != null) {
| out.writeUTF("<clinit>");
| out.writeInt(8);
| out.writeUTF("()V");
| }
|
| CtConstructor[] constructors = clazz.getDeclaredConstructors();
| Arrays.sort(constructors, new Comparator() {
| public int compare(Object o1, Object o2) {
| CtConstructor c1 = (CtConstructor) o1;
| CtConstructor c2 = (CtConstructor) o2;
| return c1.getMethodInfo2().getDescriptor().compareTo(
| c2.getMethodInfo2().getDescriptor());
| }
|
| });
| for (int i = 0; i < constructors.length; ++i) {
| CtConstructor constructor = constructors;
| int mods = constructor.getModifiers();
| if ((mods & 0x2) == 0) {
| out.writeUTF("<init>");
| out.writeInt(mods);
| out.writeUTF(constructor.getMethodInfo2().getDescriptor()
| .replace('/', '.'));
| }
|
| }
|
| //CtMethod[] methods = clazz.getDeclaredMethods();
| Arrays.sort(methods, new Comparator() {
| public int compare(Object o1, Object o2) {
| CtMethod m1 = (CtMethod) o1;
| CtMethod m2 = (CtMethod) o2;
| int value = m1.getName().compareTo(m2.getName());
| if (value == 0) {
| value = m1.getMethodInfo2().getDescriptor().compareTo(
| m2.getMethodInfo2().getDescriptor());
| }
|
| return value;
| }
|
| });
| for (int i = 0; i < methods.length; ++i) {
| CtMethod method = methods;
| int mods = method.getModifiers() &
| (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
| Modifier.STATIC | Modifier.FINAL |
| Modifier.SYNCHRONIZED | Modifier.NATIVE |
| Modifier.ABSTRACT | Modifier.STRICT);
|
| if ((mods & Modifier.PRIVATE) == 0) {
| out.writeUTF(method.getName());
| out.writeInt(mods);
| out.writeUTF(method.getMethodInfo2().getDescriptor()
| .replace('/', '.'));
| }
|
| }
|
| out.flush();
|
| MessageDigest digest = MessageDigest.getInstance("SHA");
| byte[] digested = digest.digest(bout.toByteArray());
| long hash = 0L;
| for (int i = Math.min(digested.length, 8) - 1; i >= 0; --i)
| hash = hash << 8 | digested & 0xFF;
|
| return hash;
| } catch (IOException e) {
| throw new CannotCompileException(e);
| } catch (NoSuchAlgorithmException e) {
| throw new CannotCompileException(e);
| }
| }
|
|
kind regards,
Pierre
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4194254#4194254
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4194254
More information about the jboss-user
mailing list