
com.github.binarywang.wx.graal.GraalProcessor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of weixin-graal Show documentation
Show all versions of weixin-graal Show documentation
微信开发Java内部配合graal以产生native-image配置的辅助工具, 可以通过项目的 native-image Profile 来启用: mvn -P native-image ...
package com.github.binarywang.wx.graal;
import lombok.Data;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import java.io.IOException;
import java.io.Writer;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* 目前仅仅处理@Data,且必须在lombok自己的processor之前执行,千万注意!!!!!
*
* @author outersky
*/
@SupportedAnnotationTypes("lombok.Data")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class GraalProcessor extends AbstractProcessor {
private static final String REFLECTION_CONFIG_JSON = "reflection-config.json";
private static final String NATIVE_IMAGE_PROPERTIES = "native-image.properties";
private final SortedSet classSet = new TreeSet<>();
private String shortestPackageName = null;
@Override
public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (TypeElement annotatedClass : ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Data.class))) {
registerClass(annotatedClass.getQualifiedName().toString());
handleSuperClass(annotatedClass);
}
//只有最后一轮才可以写文件,否则文件会被重复打开,报错!
if (!roundEnv.processingOver()) {
return false;
}
// 如果没有文件要写,跳过
if (classSet.isEmpty()) {
return false;
}
writeFiles();
//必须返回false,以便让lombok能继续处理。
return false;
}
/**
* 设置当前最短的package名称
*
* @param packageName 包名
*/
private void setShortestPackageName(String packageName) {
if (shortestPackageName == null) {
shortestPackageName = packageName;
} else if (packageName.length() < shortestPackageName.length()) {
shortestPackageName = packageName;
}
}
/**
* 更加完整的类名来获取package名称
*
* @param fullClassName 完整的类名
* @return package name
*/
private String getPackageName(String fullClassName) {
int last = fullClassName.lastIndexOf('.');
if (last == -1) {
return fullClassName;
}
return fullClassName.substring(0, last);
}
/**
* 保存文件
* META-INF/native-image/.../reflection-config.json
* META-INF/native-image/.../native-image.properties
*/
private void writeFiles() {
String basePackage = shortestPackageName;
String module;
if (basePackage.contains(".")) {
final int i = basePackage.lastIndexOf('.');
module = basePackage.substring(i + 1);
basePackage = basePackage.substring(0, i);
} else {
module = basePackage;
}
String path = "META-INF/native-image/" + basePackage + "/" + module + "/";
String reflectFile = path + REFLECTION_CONFIG_JSON;
String propsFile = path + NATIVE_IMAGE_PROPERTIES;
try {
FileObject fileObject = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", propsFile);
try (Writer writer = fileObject.openWriter();) {
writer.append("Args = -H:ReflectionConfigurationResources=${.}/" + REFLECTION_CONFIG_JSON);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
FileObject fileObject = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", reflectFile);
try (Writer writer = fileObject.openWriter();) {
writer.write("[\n");
boolean first = true;
for (String name : classSet) {
if (first) {
first = false;
} else {
writer.write(",");
}
writer.write(assetGraalJsonElement(name));
writer.append('\n');
}
writer.write("]");
}
} catch (IOException e) {
e.printStackTrace();
}
}
private String assetGraalJsonElement(String className) {
return "{\n" +
" \"name\" : \"" + className + "\",\n" +
" \"allDeclaredFields\":true,\n" +
" \"allDeclaredMethods\":true,\n" +
" \"allDeclaredConstructors\":true,\n" +
" \"allPublicMethods\" : true\n" +
"}";
}
/**
* 登记一个class
*
* @param className 完整的类名
*/
private void registerClass(String className) {
classSet.add(className);
setShortestPackageName(getPackageName(className));
}
/**
* 获取一个类型的所有的父类,并登记
*
* @param typeElement 类型元素
*/
private void handleSuperClass(TypeElement typeElement) {
TypeMirror superclass = typeElement.getSuperclass();
if (superclass.getKind() == TypeKind.DECLARED) {
TypeElement s = (TypeElement) ((DeclaredType) superclass).asElement();
String sName = s.toString();
// ignore java.**/javax.**
if (sName.startsWith("java.") || sName.startsWith("javax.")) {
return;
}
registerClass(sName);
handleSuperClass(s);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy