fix[storage]: Fix storage functional method reference bug

This commit is contained in:
凌星
2023-09-18 10:14:42 +08:00
parent beb0f17cfc
commit 05ae9073fb
13 changed files with 231 additions and 75 deletions
@@ -0,0 +1,17 @@
package com.zfoo.storage.anno;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author veione
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface GraalvmNative {
}
@@ -29,6 +29,9 @@ public class StorageConfig {
// 未被使用的Storage是否回收,默认开启节省资源
private boolean recycle;
// 函数式capture扫描包
private String lambdaCapturePackage;
public String getId() {
return id;
}
@@ -68,4 +71,12 @@ public class StorageConfig {
public void setRecycle(boolean recycle) {
this.recycle = recycle;
}
public String getLambdaCapturePackage() {
return lambdaCapturePackage;
}
public void setLambdaCapturePackage(String lambdaCapturePackage) {
this.lambdaCapturePackage = lambdaCapturePackage;
}
}
@@ -0,0 +1,33 @@
package com.zfoo.storage.graalvm.feature;
import com.zfoo.protocol.util.ClassUtils;
import com.zfoo.storage.anno.GraalvmNative;
import org.graalvm.nativeimage.hosted.Feature;
import org.graalvm.nativeimage.hosted.RuntimeSerialization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 用于注册graalvm lambda capture的类
*
* @author veione
*/
public class RuntimeRegistrationFeature implements Feature {
private static final Logger log = LoggerFactory.getLogger(RuntimeRegistrationFeature.class);
private static String lambdaCapturePackage;
@Override
public void duringSetup(DuringSetupAccess access) {
log.info("Runtime registration feature on duringSetup");
var filterClasses = ClassUtils.getClasses(lambdaCapturePackage, c -> c.isAnnotationPresent(GraalvmNative.class));
filterClasses.forEach(cls -> {
log.info("Starting register lambda capture class: {}", cls);
RuntimeSerialization.registerLambdaCapturingClass(cls);
});
}
public static void setLambdaCapturePackage(String lambdaCapturePackage) {
RuntimeRegistrationFeature.lambdaCapturePackage = lambdaCapturePackage;
}
}
@@ -37,7 +37,7 @@ public final class LambdaUtils {
Class<? extends Serializable> clazz = func.getClass();
Method method = clazz.getDeclaredMethod("writeReplace");
ReflectionUtils.makeAccessible(method);
return new ReflectLambdaMeta((java.lang.invoke.SerializedLambda) method.invoke(func), clazz.getClassLoader());
return new ReflectLambdaMeta((java.lang.invoke.SerializedLambda) method.invoke(func));
} catch (Throwable e) {
// 3. 反射失败使用序列化的方式读取
return new ShadowLambdaMeta(SerializedLambda.extract(func));
@@ -27,11 +27,6 @@ public class IdeaProxyLambdaMeta implements LambdaMeta {
return name;
}
@Override
public Class<?> getInstantiatedClass() {
return clazz;
}
@Override
public String toString() {
return clazz.getSimpleName() + "::" + name;
@@ -14,11 +14,4 @@ public interface LambdaMeta {
*/
String getImplMethodName();
/**
* 实例化该方法的类
*
* @return 返回对应的类名称
*/
Class<?> getInstantiatedClass();
}
@@ -1,30 +1,17 @@
package com.zfoo.storage.util.support;
import com.zfoo.protocol.util.ClassUtils;
import com.zfoo.protocol.util.StringUtils;
/**
* Created by hcl at 2021/5/14
*/
public class ReflectLambdaMeta implements LambdaMeta {
private final java.lang.invoke.SerializedLambda lambda;
private final ClassLoader classLoader;
public ReflectLambdaMeta(java.lang.invoke.SerializedLambda lambda, ClassLoader classLoader) {
public ReflectLambdaMeta(java.lang.invoke.SerializedLambda lambda) {
this.lambda = lambda;
this.classLoader = classLoader;
}
@Override
public String getImplMethodName() {
return lambda.getImplMethodName();
}
@Override
public Class<?> getInstantiatedClass() {
String instantiatedMethodType = lambda.getInstantiatedMethodType();
String instantiatedType = instantiatedMethodType.substring(2, instantiatedMethodType.indexOf(StringUtils.SEMICOLON)).replace(StringUtils.SLASH, StringUtils.PERIOD);
return ClassUtils.toClassConfident(instantiatedType, this.classLoader);
}
}
@@ -1,8 +1,5 @@
package com.zfoo.storage.util.support;
import com.zfoo.protocol.util.StringUtils;
import com.zfoo.protocol.util.ClassUtils;
/**
* 基于 {@link SerializedLambda} 创建的元信息
* <p>
@@ -20,11 +17,4 @@ public class ShadowLambdaMeta implements LambdaMeta {
return lambda.getImplMethodName();
}
@Override
public Class<?> getInstantiatedClass() {
String instantiatedMethodType = lambda.getInstantiatedMethodType();
String instantiatedType = instantiatedMethodType.substring(2, instantiatedMethodType.indexOf(StringUtils.SEMICOLON)).replace(StringUtils.SLASH, StringUtils.PERIOD);
return ClassUtils.toClassConfident(instantiatedType, lambda.getCapturingClass().getClassLoader());
}
}
@@ -91,6 +91,7 @@ public class ExportBinaryTesting {
config.setResourceLocation("classpath:/excel");
config.setWriteable(true);
config.setRecycle(false);
config.setLambdaCapturePackage("com.zfoo.storage");
var storageManager = new StorageManager();
storageManager.setStorageConfig(config);
storageManager.initBefore();