Fix AotUtils StackOverflowError (#13710)
* Fix AotUtils StackOverflowError Signed-off-by: crazyhzm <crazyhzm@gmail.com> * Fix ut Signed-off-by: crazyhzm <crazyhzm@gmail.com> --------- Signed-off-by: crazyhzm <crazyhzm@gmail.com>
This commit is contained in:
parent
0fa88a1180
commit
1dd289d405
|
|
@ -21,6 +21,8 @@ import org.apache.dubbo.common.compiler.support.ClassUtils;
|
|||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.TypeReference;
|
||||
|
|
@ -30,25 +32,34 @@ public class AotUtils {
|
|||
private AotUtils() {}
|
||||
|
||||
public static void registerSerializationForService(Class<?> serviceType, RuntimeHints hints) {
|
||||
Set<Class<?>> serializationTypeCache = new LinkedHashSet<>();
|
||||
Arrays.stream(serviceType.getMethods()).forEach((method) -> {
|
||||
Arrays.stream(method.getParameterTypes())
|
||||
.forEach((parameterType) -> registerSerializationType(parameterType, hints));
|
||||
.forEach(
|
||||
(parameterType) -> registerSerializationType(parameterType, hints, serializationTypeCache));
|
||||
|
||||
registerSerializationType(method.getReturnType(), hints);
|
||||
registerSerializationType(method.getReturnType(), hints, serializationTypeCache);
|
||||
});
|
||||
}
|
||||
|
||||
private static void registerSerializationType(Class<?> registerType, RuntimeHints hints) {
|
||||
private static void registerSerializationType(
|
||||
Class<?> registerType, RuntimeHints hints, Set<Class<?>> serializationTypeCache) {
|
||||
if (isPrimitive(registerType)) {
|
||||
hints.serialization().registerType(TypeReference.of(ClassUtils.getBoxedClass(registerType)));
|
||||
serializationTypeCache.add(registerType);
|
||||
} else {
|
||||
if (Serializable.class.isAssignableFrom(registerType)) {
|
||||
hints.serialization().registerType(TypeReference.of(registerType));
|
||||
serializationTypeCache.add(registerType);
|
||||
|
||||
Arrays.stream(registerType.getDeclaredFields())
|
||||
.forEach((field -> registerSerializationType(field.getType(), hints)));
|
||||
Arrays.stream(registerType.getDeclaredFields()).forEach((field -> {
|
||||
if (!serializationTypeCache.contains(field.getType())) {
|
||||
registerSerializationType(field.getType(), hints, serializationTypeCache);
|
||||
serializationTypeCache.add(field.getType());
|
||||
}
|
||||
}));
|
||||
|
||||
registerSerializationType(registerType.getSuperclass(), hints);
|
||||
registerSerializationType(registerType.getSuperclass(), hints, serializationTypeCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,4 +71,34 @@ public class AotUtilsTest {
|
|||
Assertions.assertTrue(containHelloRequestSuper.get());
|
||||
Assertions.assertTrue(containHelloResponse.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerSerializationForCircularDependencyFieldTest() {
|
||||
RuntimeHints runtimeHints = new RuntimeHints();
|
||||
AotUtils.registerSerializationForService(CircularDependencyDemoService.class, runtimeHints);
|
||||
AtomicBoolean containDemoA = new AtomicBoolean(false);
|
||||
runtimeHints.serialization().javaSerializationHints().forEach(s -> {
|
||||
if (s.getType().getName().equals(DemoA.class.getName())) {
|
||||
containDemoA.set(true);
|
||||
}
|
||||
});
|
||||
AtomicBoolean containDemoB = new AtomicBoolean(false);
|
||||
runtimeHints.serialization().javaSerializationHints().forEach(s -> {
|
||||
if (s.getType().getName().equals(DemoB.class.getName())) {
|
||||
containDemoB.set(true);
|
||||
}
|
||||
});
|
||||
|
||||
Assertions.assertTrue(containDemoA.get());
|
||||
Assertions.assertTrue(containDemoB.get());
|
||||
|
||||
AotUtils.registerSerializationForService(DemoService.class, runtimeHints);
|
||||
AtomicBoolean containSexEnum = new AtomicBoolean(false);
|
||||
runtimeHints.serialization().javaSerializationHints().forEach(s -> {
|
||||
if (s.getType().getName().equals(SexEnum.class.getName())) {
|
||||
containSexEnum.set(true);
|
||||
}
|
||||
});
|
||||
Assertions.assertTrue(containSexEnum.get());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring6.utils;
|
||||
|
||||
public interface CircularDependencyDemoService {
|
||||
String sayHello(DemoA a);
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring6.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class DemoA implements Serializable {
|
||||
private DemoB b;
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring6.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class DemoB implements Serializable {
|
||||
private DemoA a;
|
||||
}
|
||||
|
|
@ -22,8 +22,11 @@ public class Person implements Serializable {
|
|||
|
||||
private String name;
|
||||
|
||||
public Person(String name) {
|
||||
private SexEnum sex;
|
||||
|
||||
public Person(String name, SexEnum sex) {
|
||||
this.name = name;
|
||||
this.sex = sex;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
|
@ -33,4 +36,12 @@ public class Person implements Serializable {
|
|||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public SexEnum getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
public void setSex(SexEnum sex) {
|
||||
this.sex = sex;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring6.utils;
|
||||
|
||||
public enum SexEnum {
|
||||
BOY("boy"),
|
||||
GIRL("girl");
|
||||
|
||||
private final String desc;
|
||||
|
||||
SexEnum(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue