Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sofaboot 4.0 support #93

Merged
merged 8 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>com.alipay.sofa</groupId>
<artifactId>hessian</artifactId>
<version>3.4.0</version>
<version>3.5.0</version>
<packaging>jar</packaging>

<name>${project.groupId}:${project.artifactId}</name>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Ant Group
* Copyright (c) 2004-2023 All Rights Reserved.
*/
package com.caucho.hessian.io;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

/**
*
* @author junyuan
* @version AbstractFieldAdaptorDeserializer.java, v 0.1 2023年05月06日 14:21 junyuan Exp $
*/
public abstract class AbstractFieldAdaptorDeserializer extends AbstractDeserializer {

protected Map<String, Field> _fields;

public AbstractFieldAdaptorDeserializer(Class<?> cl) {
_fields = getFieldMapForSerialize(cl);
}

protected Map<String, Field> getFieldMapForSerialize(Class cl) {
Map<String, Field> fields = new HashMap<String, Field>();
for (; cl != null; cl = cl.getSuperclass()) {
Field[] originFields = cl.getDeclaredFields();
for (int i = 0; i < originFields.length; i++) {
Field field = originFields[i];
if (Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) {
continue;
} else if (fields.containsKey(field.getName())) {
continue;
}
fields.put(field.getName(), field);
}
}
return fields;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Ant Group
* Copyright (c) 2004-2023 All Rights Reserved.
*/
package com.caucho.hessian.io;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

/**
*
* @author junyuan
* @version AbstractFieldAdaptorSerializer.java, v 0.1 2023年04月10日 19:34 junyuan Exp $
*/
public abstract class AbstractFieldAdaptorSerializer extends AbstractSerializer {

protected Field[] _fields;

public AbstractFieldAdaptorSerializer(Class<?> clazz) {
this._fields = getFieldsForSerialize(clazz);
}

public void writeObject(Object obj, AbstractHessianOutput out) throws IOException {
if (obj == null) {
out.writeNull();
return;
}

if (out.addRef(obj)) {
return;
}
Class cl = obj.getClass();
int ref = out.writeObjectBegin(cl.getName());

if (ref < -1) {
writeObject10(obj, out);
}
else {
if (ref == -1) {
writeDefinition20(out);
out.writeObjectBegin(cl.getName());
}

writeInstance(obj, out);
}
}

private void writeObject10(Object obj, AbstractHessianOutput out)
throws IOException
{
for (int i = 0; i < _fields.length; i++) {
Field field = _fields[i];

out.writeString(field.getName());

serializeField(out, obj, field);
}

out.writeMapEnd();
}

private void writeDefinition20(AbstractHessianOutput out)
throws IOException
{
out.writeClassFieldLength(_fields.length);

for (int i = 0; i < _fields.length; i++) {
Field field = _fields[i];

out.writeString(field.getName());
}
}

public void writeInstance(Object obj, AbstractHessianOutput out)
throws IOException
{
for (int i = 0; i < _fields.length; i++) {
Field field = _fields[i];
serializeField(out, obj, field);
}
}

protected abstract void serializeField(AbstractHessianOutput out, Object obj, Field field) throws IOException;

/**
* get all fields
* include super class
* exclude transient or static
* @param cl
* @return
*/
protected Field[] getFieldsForSerialize(Class cl) {
List<Field> fields = new ArrayList<Field>();
for (; cl != null; cl = cl.getSuperclass()) {
Field[] originFields = cl.getDeclaredFields();
for (int i = 0; i < originFields.length; i++) {
Field field = originFields[i];
if (Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) {
continue;
}
fields.add(field);
}
}
return fields.toArray(new Field[0]);
}
}
11 changes: 4 additions & 7 deletions src/main/java/com/caucho/hessian/io/JavaDeserializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

package com.caucho.hessian.io;

import com.caucho.hessian.util.ReflectionUtil;
import sun.misc.Unsafe;

import java.io.IOException;
Expand Down Expand Up @@ -99,7 +100,7 @@ public JavaDeserializer(Class cl)
_readResolve = getReadResolve(cl);

if (_readResolve != null) {
_readResolve.setAccessible(true);
ReflectionUtil.setAccessible(_readResolve);
}

Constructor[] constructors = cl.getDeclaredConstructors();
Expand Down Expand Up @@ -138,7 +139,7 @@ else if (param[j].isPrimitive())
}

if (_constructor != null) {
_constructor.setAccessible(true);
ReflectionUtil.setAccessible(_constructor);
Class[] params = _constructor.getParameterTypes();
_constructorArgs = new Object[params.length];
for (int i = 0; i < params.length; i++) {
Expand Down Expand Up @@ -325,11 +326,7 @@ else if (fieldMap.get(field.getName()) != null)
continue;

// XXX: could parameterize the handler to only deal with public
try {
field.setAccessible(true);
} catch (Throwable e) {
e.printStackTrace();
}
ReflectionUtil.setAccessible(field);

Class type = field.getType();
FieldDeserializer deser;
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/com/caucho/hessian/io/JavaSerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@

package com.caucho.hessian.io;

import com.caucho.hessian.util.ReflectionUtil;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
Expand All @@ -70,8 +72,9 @@ public class JavaSerializer extends AbstractSerializer
public JavaSerializer(Class cl)
{
_writeReplace = getWriteReplace(cl);
if (_writeReplace != null)
_writeReplace.setAccessible(true);
if (_writeReplace != null) {
ReflectionUtil.setAccessible(_writeReplace);
}

ArrayList primitiveFields = new ArrayList();
ArrayList compoundFields = new ArrayList();
Expand All @@ -86,7 +89,7 @@ public JavaSerializer(Class cl)
continue;

// XXX: could parameterize the handler to only deal with public
field.setAccessible(true);
ReflectionUtil.setAccessible(field);

if (field.getType().isPrimitive() ||
field.getType().getName().startsWith("java.lang.") &&
Expand Down
69 changes: 67 additions & 2 deletions src/main/java/com/caucho/hessian/io/SerializerFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@
import com.alipay.hessian.ClassNameResolver;
import com.alipay.hessian.ClassNameResolverBuilder;
import com.caucho.burlap.io.BurlapRemoteObject;
import com.caucho.hessian.io.atomic.AtomicDeserializer;
import com.caucho.hessian.io.atomic.AtomicSerializer;
import com.caucho.hessian.io.java17.base.JavaCurrencyDeserializer;
import com.caucho.hessian.io.java17.base.JavaCurrencySerializer;
import com.caucho.hessian.io.java8.DurationHandle;
import com.caucho.hessian.io.java8.InstantHandle;
import com.caucho.hessian.io.java8.Java8TimeSerializer;
Expand All @@ -66,12 +70,22 @@
import com.caucho.hessian.io.java8.ZoneIdSerializer;
import com.caucho.hessian.io.java8.ZoneOffsetHandle;
import com.caucho.hessian.io.java8.ZonedDateTimeHandle;
import com.caucho.hessian.io.throwable.StackTraceElementDeserializer;
import com.caucho.hessian.io.throwable.StackTraceElementSerializer;
import com.caucho.hessian.io.throwable.ThrowableHelper;

import java.io.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicLongArray;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -107,6 +121,7 @@ public class SerializerFactory extends AbstractSerializerFactory
protected ClassNameResolver classNameResolver = ClassNameResolverBuilder.buildDefault();

protected final static boolean isHigherThanJdk8 = isJava8();
protected final static boolean isHigherThanJdk17 = isJava17();

private Map<ClassLoader, Map<String, Object>> _typeNotFoundMap = new ConcurrentHashMap<ClassLoader, Map<String, Object>>(
8);
Expand Down Expand Up @@ -236,7 +251,7 @@ else if (cl.isArray())
serializer = new ArraySerializer();

else if (Throwable.class.isAssignableFrom(cl))
serializer = new ThrowableSerializer(cl);
serializer = ThrowableHelper.getSerializer(cl);

else if (InputStream.class.isAssignableFrom(cl))
serializer = new InputStreamSerializer();
Expand Down Expand Up @@ -343,6 +358,9 @@ else if (Enumeration.class.isAssignableFrom(cl))
else if (Enum.class.isAssignableFrom(cl))
deserializer = new EnumDeserializer(cl);

else if (Throwable.class.isAssignableFrom(cl))
deserializer = ThrowableHelper.getDeserializer(cl);

else
deserializer = getDefaultDeserializer(cl);

Expand Down Expand Up @@ -620,7 +638,7 @@ protected static void addBasic(Class cl, String typeName, int type)

try {
Class stackTrace = Class.forName("java.lang.StackTraceElement");

_staticSerializerMap.put(stackTrace, new StackTraceElementSerializer());
_staticDeserializerMap.put(stackTrace, new StackTraceElementDeserializer());
} catch (Throwable e) {
}
Expand Down Expand Up @@ -663,6 +681,32 @@ protected static void addBasic(Class cl, String typeName, int type)
log.warning(String.valueOf(t.getCause()));
}

try {
AtomicSerializer atomicSerializer = new AtomicSerializer();
_staticSerializerMap.put(AtomicInteger.class, atomicSerializer);
_staticSerializerMap.put(AtomicLong.class, atomicSerializer);
_staticSerializerMap.put(AtomicBoolean.class, atomicSerializer);
_staticSerializerMap.put(AtomicReference.class, atomicSerializer);
_staticSerializerMap.put(AtomicLongArray.class, atomicSerializer);
_staticSerializerMap.put(AtomicIntegerArray.class, atomicSerializer);
_staticSerializerMap.put(AtomicReferenceArray.class, atomicSerializer);

_staticDeserializerMap.put(AtomicInteger.class, new AtomicDeserializer(AtomicInteger.class));
_staticDeserializerMap.put(AtomicLong.class, new AtomicDeserializer(AtomicLong.class));
_staticDeserializerMap.put(AtomicBoolean.class, new AtomicDeserializer(AtomicBoolean.class));
_staticDeserializerMap.put(AtomicReference.class, new AtomicDeserializer(AtomicReference.class));
_staticDeserializerMap.put(AtomicLongArray.class, new AtomicDeserializer(AtomicLongArray.class));
_staticDeserializerMap.put(AtomicIntegerArray.class, new AtomicDeserializer(AtomicIntegerArray.class));
_staticDeserializerMap.put(AtomicReferenceArray.class, new AtomicDeserializer(AtomicReferenceArray.class));

} catch (Throwable t) {
log.warning(String.valueOf(t.getCause()));
}

if (isHigherThanJdk17) {
addCurrencySupport();
}

}

/**
Expand All @@ -675,6 +719,27 @@ private static boolean isJava8() {
return Double.valueOf(javaVersion) >= 1.8;
}

/**
* check if the environment is java 17 or beyond
*
* @return if on java 17
*/
private static boolean isJava17() {
String javaVersion = System.getProperty("java.specification.version");
return Double.valueOf(javaVersion) >= 17;
}

protected static void addCurrencySupport() {
try {
JavaCurrencySerializer currencySerializer = new JavaCurrencySerializer(Currency.class);
JavaCurrencyDeserializer currencyDeserializer = new JavaCurrencyDeserializer();
_staticSerializerMap.put(Currency.class, currencySerializer);
_staticDeserializerMap.put(Currency.class, currencyDeserializer);
} catch (Throwable t) {
log.warning(String.valueOf(t.getCause()));
}
}

private static boolean isZoneId(Class cl) {
try {
return isHigherThanJdk8 && Class.forName("java.time.ZoneId").isAssignableFrom(cl);
Expand Down
Loading
Loading