目的:解决native-image中gson功能无效的问题。 可以通过项目的 native-image Profile 来启用: mvn -P native-image -Dmaven.test.skip=true clean source:jar install 编译时会在各包中增加2个文件: META-INF/native-image/.../reflection-config.json META-INF/native-image/.../native-image.propertiesdev1
| @@ -99,6 +99,7 @@ | |||
| </scm> | |||
| <modules> | |||
| <module>weixin-graal</module> | |||
| <module>weixin-java-common</module> | |||
| <module>weixin-java-cp</module> | |||
| <module>weixin-java-mp</module> | |||
| @@ -331,6 +332,14 @@ | |||
| </plugins> | |||
| </build> | |||
| </profile> | |||
| <profile> | |||
| <id>native-image</id> | |||
| <activation> | |||
| <activeByDefault>false</activeByDefault> | |||
| </activation> | |||
| </profile> | |||
| </profiles> | |||
| <build> | |||
| @@ -0,0 +1,40 @@ | |||
| <?xml version="1.0"?> | |||
| <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" | |||
| xmlns="http://maven.apache.org/POM/4.0.0"> | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <parent> | |||
| <groupId>com.github.binarywang</groupId> | |||
| <artifactId>wx-java</artifactId> | |||
| <version>3.6.7.B</version> | |||
| </parent> | |||
| <artifactId>weixin-graal</artifactId> | |||
| <name>WxJava - Graal</name> | |||
| <description>微信开发Java内部配合graal以产生native-image配置的辅助工具, 可以通过项目的 native-image Profile 来启用: mvn -P native-image ... | |||
| </description> | |||
| <dependencies> | |||
| <dependency> | |||
| <groupId>org.projectlombok</groupId> | |||
| <artifactId>lombok</artifactId> | |||
| <scope>compile</scope> | |||
| </dependency> | |||
| </dependencies> | |||
| <build> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.apache.maven.plugins</groupId> | |||
| <artifactId>maven-compiler-plugin</artifactId> | |||
| <version>3.5.1</version> | |||
| <configuration> | |||
| <proc>none</proc> | |||
| </configuration> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| </project> | |||
| @@ -0,0 +1,167 @@ | |||
| package cn.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之前执行,千万注意!!!!! | |||
| @SupportedAnnotationTypes("lombok.Data") | |||
| @SupportedSourceVersion(SourceVersion.RELEASE_7) | |||
| 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 SortedSet<String> 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); | |||
| Writer writer = fileObject.openWriter(); | |||
| writer.append("Args = -H:ReflectionConfigurationResources=${.}/" + REFLECTION_CONFIG_JSON); | |||
| writer.close(); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| try { | |||
| FileObject fileObject = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", reflectFile); | |||
| 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("]"); | |||
| writer.close(); | |||
| } 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); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1 @@ | |||
| cn.binarywang.wx.graal.GraalProcessor | |||
| @@ -1,7 +1,7 @@ | |||
| <?xml version="1.0"?> | |||
| <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" | |||
| xmlns="http://maven.apache.org/POM/4.0.0"> | |||
| <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" | |||
| xmlns="http://maven.apache.org/POM/4.0.0"> | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <parent> | |||
| <groupId>com.github.binarywang</groupId> | |||
| @@ -134,4 +134,36 @@ | |||
| </plugins> | |||
| </build> | |||
| <profiles> | |||
| <profile> | |||
| <id>native-image</id> | |||
| <activation> | |||
| <activeByDefault>false</activeByDefault> | |||
| </activation> | |||
| <build> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.apache.maven.plugins</groupId> | |||
| <artifactId>maven-compiler-plugin</artifactId> | |||
| <version>3.5.1</version> | |||
| <configuration> | |||
| <annotationProcessors> | |||
| cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor | |||
| </annotationProcessors> | |||
| <annotationProcessorPaths> | |||
| <path> | |||
| <groupId>com.github.binarywang</groupId> | |||
| <artifactId>weixin-graal</artifactId> | |||
| <version>${project.version}</version> | |||
| </path> | |||
| </annotationProcessorPaths> | |||
| </configuration> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| </profile> | |||
| </profiles> | |||
| </project> | |||
| @@ -95,4 +95,36 @@ | |||
| </plugins> | |||
| </build> | |||
| <profiles> | |||
| <profile> | |||
| <id>native-image</id> | |||
| <activation> | |||
| <activeByDefault>false</activeByDefault> | |||
| </activation> | |||
| <build> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.apache.maven.plugins</groupId> | |||
| <artifactId>maven-compiler-plugin</artifactId> | |||
| <version>3.5.1</version> | |||
| <configuration> | |||
| <annotationProcessors> | |||
| cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor | |||
| </annotationProcessors> | |||
| <annotationProcessorPaths> | |||
| <path> | |||
| <groupId>com.github.binarywang</groupId> | |||
| <artifactId>weixin-graal</artifactId> | |||
| <version>${project.version}</version> | |||
| </path> | |||
| </annotationProcessorPaths> | |||
| </configuration> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| </profile> | |||
| </profiles> | |||
| </project> | |||
| @@ -80,12 +80,12 @@ | |||
| <groupId>org.projectlombok</groupId> | |||
| <artifactId>lombok</artifactId> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.github.jedis-lock</groupId> | |||
| <artifactId>jedis-lock</artifactId> | |||
| <version>1.0.0</version> | |||
| <optional>true</optional> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.github.jedis-lock</groupId> | |||
| <artifactId>jedis-lock</artifactId> | |||
| <version>1.0.0</version> | |||
| <optional>true</optional> | |||
| </dependency> | |||
| </dependencies> | |||
| <build> | |||
| @@ -102,4 +102,35 @@ | |||
| </plugins> | |||
| </build> | |||
| <profiles> | |||
| <profile> | |||
| <id>native-image</id> | |||
| <activation> | |||
| <activeByDefault>false</activeByDefault> | |||
| </activation> | |||
| <build> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.apache.maven.plugins</groupId> | |||
| <artifactId>maven-compiler-plugin</artifactId> | |||
| <version>3.5.1</version> | |||
| <configuration> | |||
| <annotationProcessors> | |||
| cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor | |||
| </annotationProcessors> | |||
| <annotationProcessorPaths> | |||
| <path> | |||
| <groupId>com.github.binarywang</groupId> | |||
| <artifactId>weixin-graal</artifactId> | |||
| <version>${project.version}</version> | |||
| </path> | |||
| </annotationProcessorPaths> | |||
| </configuration> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| </profile> | |||
| </profiles> | |||
| </project> | |||
| @@ -96,4 +96,35 @@ | |||
| </plugins> | |||
| </build> | |||
| <profiles> | |||
| <profile> | |||
| <id>native-image</id> | |||
| <activation> | |||
| <activeByDefault>false</activeByDefault> | |||
| </activation> | |||
| <build> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.apache.maven.plugins</groupId> | |||
| <artifactId>maven-compiler-plugin</artifactId> | |||
| <version>3.5.1</version> | |||
| <configuration> | |||
| <annotationProcessors> | |||
| cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor | |||
| </annotationProcessors> | |||
| <annotationProcessorPaths> | |||
| <path> | |||
| <groupId>com.github.binarywang</groupId> | |||
| <artifactId>weixin-graal</artifactId> | |||
| <version>${project.version}</version> | |||
| </path> | |||
| </annotationProcessorPaths> | |||
| </configuration> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| </profile> | |||
| </profiles> | |||
| </project> | |||
| @@ -107,5 +107,35 @@ | |||
| </plugins> | |||
| </build> | |||
| <profiles> | |||
| <profile> | |||
| <id>native-image</id> | |||
| <activation> | |||
| <activeByDefault>false</activeByDefault> | |||
| </activation> | |||
| <build> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.apache.maven.plugins</groupId> | |||
| <artifactId>maven-compiler-plugin</artifactId> | |||
| <version>3.5.1</version> | |||
| <configuration> | |||
| <annotationProcessors> | |||
| cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor | |||
| </annotationProcessors> | |||
| <annotationProcessorPaths> | |||
| <path> | |||
| <groupId>com.github.binarywang</groupId> | |||
| <artifactId>weixin-graal</artifactId> | |||
| <version>${project.version}</version> | |||
| </path> | |||
| </annotationProcessorPaths> | |||
| </configuration> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| </profile> | |||
| </profiles> | |||
| </project> | |||
| @@ -72,4 +72,35 @@ | |||
| </dependency> | |||
| </dependencies> | |||
| <profiles> | |||
| <profile> | |||
| <id>native-image</id> | |||
| <activation> | |||
| <activeByDefault>false</activeByDefault> | |||
| </activation> | |||
| <build> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.apache.maven.plugins</groupId> | |||
| <artifactId>maven-compiler-plugin</artifactId> | |||
| <version>3.5.1</version> | |||
| <configuration> | |||
| <annotationProcessors> | |||
| cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor | |||
| </annotationProcessors> | |||
| <annotationProcessorPaths> | |||
| <path> | |||
| <groupId>com.github.binarywang</groupId> | |||
| <artifactId>weixin-graal</artifactId> | |||
| <version>${project.version}</version> | |||
| </path> | |||
| </annotationProcessorPaths> | |||
| </configuration> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| </profile> | |||
| </profiles> | |||
| </project> | |||