Skip to content

Commit

Permalink
🆕 #1392 增加weixin-graal模块,配合graal以产生native-image配置。
Browse files Browse the repository at this point in the history
目的:解决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.properties
  • Loading branch information
outersky authored Jan 31, 2020
1 parent ccb2534 commit e9efa90
Show file tree
Hide file tree
Showing 10 changed files with 413 additions and 9 deletions.
9 changes: 9 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -331,6 +332,14 @@
</plugins>
</build>
</profile>

<profile>
<id>native-image</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
</profile>

</profiles>

<build>
Expand Down
40 changes: 40 additions & 0 deletions weixin-graal/pom.xml
Original file line number Diff line number Diff line change
@@ -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>
167 changes: 167 additions & 0 deletions weixin-graal/src/main/java/cn/binarywang/wx/graal/GraalProcessor.java
Original file line number Diff line number Diff line change
@@ -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);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cn.binarywang.wx.graal.GraalProcessor
38 changes: 35 additions & 3 deletions weixin-java-common/pom.xml
Original file line number Diff line number Diff line change
@@ -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>
Expand Down Expand Up @@ -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>
32 changes: 32 additions & 0 deletions weixin-java-cp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
43 changes: 37 additions & 6 deletions weixin-java-miniapp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Loading

0 comments on commit e9efa90

Please sign in to comment.