You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by di...@apache.org on 2019/07/30 09:38:32 UTC
[rocketmq-ons-cpp] 05/35: Add ONS Jar convert
This is an automated email from the ASF dual-hosted git repository.
dinglei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/rocketmq-ons-cpp.git
commit 90bdc11072fa1a316c3506a05cf88018956ac5d9
Author: ShannonDing <li...@163.com>
AuthorDate: Tue Jul 23 21:47:43 2019 +0800
Add ONS Jar convert
---
build.sh | 32 +
pom.xml | 137 +++++
.../org/apache/rocketmq/graalvm/CInterface.java | 661 +++++++++++++++++++++
.../org/apache/rocketmq/graalvm/ErrorCode.java | 21 +
.../rocketmq/graalvm/GraalMessageListener.java | 44 ++
.../graalvm/GraalMessageOrderListener.java | 43 ++
.../apache/rocketmq/graalvm/GraalSendCallback.java | 29 +
.../rocketmq/graalvm/GraalTransactionChecker.java | 47 ++
.../rocketmq/graalvm/GraalTransactionExecutor.java | 45 ++
.../graalvm/substitutions/NettySubstitutions.java | 49 ++
tools/graal/README.md | 19 +
tools/graal/reflection_config.json | 352 +++++++++++
12 files changed, 1479 insertions(+)
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..0b23ca1
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+if [ -d build ]; then
+ rm -fr build
+fi
+mkdir build
+
+native-image --shared -H:Path=./build \
+ --no-server \
+ -H:ReflectionConfigurationFiles=./tools/graal/reflection_config.json \
+ -H:Name=rocketmq_client_core \
+ -H:CLibraryPath=./src/main/c/native \
+ -jar ./target/rocketmq-ons-cpp-full.jar \
+ -Dio.netty.noUnsafe=true \
+ --report-unsupported-elements-at-runtime \
+ --allow-incomplete-classpath \
+ -H:+ReportExceptionStackTraces \
+ --enable-all-security-services \
+ --enable-url-protocols=https \
+ -H:EnableURLProtocols=http \
+ --initialize-at-build-time \
+ --initialize-at-run-time=io.netty.handler.ssl.util.BouncyCastleSelfSignedCertGenerator,io.netty.handler.ssl.ReferenceCountedOpenSslClientContext,io.netty.handler.ssl.ReferenceCountedOpenSslServerContext,io.netty.handler.ssl.JdkNpnApplicationProtocolNegotiator,io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator,io.netty.handler.ssl.util.ThreadLocalInsecureRandom,io.netty.handler.ssl.JettyNpnSslEngine,io.netty.handler.ssl.ReferenceCountedOpenSslEngine,io.netty. [...]
+
+cp build/*.h graalvm_artifacts/
+
+if test "$(uname)" = "Linux"; then
+ mv build/rocketmq-ons-cpp-full.so build/librocketmq_client_core.so
+fi
+
+if test "$(uname)" = "Darwin"; then
+ mv build/rocketmq-ons-cpp-full.dylib build/librocketmq_client_core.dylib
+ install_name_tool -id "@rpath/librocketmq_client_core.dylib" build/librocketmq_client_core.dylib
+fi
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..da77220
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ 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">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.rocketmq.graalvm</groupId>
+ <artifactId>rocketmq-ons-cpp</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <properties>
+ <maven.compiler.source>1.7</maven.compiler.source>
+ <maven.compiler.target>1.7</maven.compiler.target>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.graalvm.sdk</groupId>
+ <artifactId>graal-sdk</artifactId>
+ <version>1.0.0-rc15</version>
+ </dependency>
+ <dependency>
+ <groupId>com.oracle.substratevm</groupId>
+ <artifactId>svm</artifactId>
+ <version>1.0.0-rc15</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-all</artifactId>
+ <version>4.1.24.Final</version>
+ </dependency>
+ <dependency>
+ <groupId>com.alibaba</groupId>
+ <artifactId>fastjson</artifactId>
+ <version>1.2.50</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.rocketmq</groupId>
+ <artifactId>ons-client</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.10.19</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>/usr/local/include/rocketmq</outputDirectory>
+ <resources>
+ <resource>
+ <directory>src/main/c/native</directory>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>3.1.0</version>
+ <configuration>
+ <finalName>${project.artifactId}-full</finalName>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ <appendAssemblyId>false</appendAssemblyId>
+ <archive>
+ <manifest>
+ <mainClass>org.apache.rocketmq.graalvm.CInterface</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ <executions>
+ <execution>
+ <id>assemble-all</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>3.1.0</version>
+ <executions>
+ <execution>
+ <id>default-jar</id>
+ <!-- put the default-jar in the none phase to skip building it -->
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.6.0</version>
+ <executions>
+ <execution>
+ <id>native-image</id>
+ <phase>install</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ <configuration>
+ <executable>${basedir}/build.sh</executable>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/src/main/java/org/apache/rocketmq/graalvm/CInterface.java b/src/main/java/org/apache/rocketmq/graalvm/CInterface.java
new file mode 100644
index 0000000..f93a396
--- /dev/null
+++ b/src/main/java/org/apache/rocketmq/graalvm/CInterface.java
@@ -0,0 +1,661 @@
+package org.apache.rocketmq.graalvm;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.parser.ParserConfig;
+import com.alibaba.fastjson.serializer.SerializeConfig;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.rocketmq.graalvm.CInterface.CPropertiesDirectives;
+import org.apache.rocketmq.ons.api.Admin;
+import org.apache.rocketmq.ons.api.Consumer;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.ONSFactory;
+import org.apache.rocketmq.ons.api.Producer;
+import org.apache.rocketmq.ons.api.PropertyKeyConst;
+import org.apache.rocketmq.ons.api.SendResult;
+import org.apache.rocketmq.ons.api.exception.ONSClientException;
+import org.apache.rocketmq.ons.api.order.OrderConsumer;
+import org.apache.rocketmq.ons.api.order.OrderProducer;
+import org.apache.rocketmq.ons.api.transaction.TransactionProducer;
+import org.graalvm.nativeimage.IsolateThread;
+import org.graalvm.nativeimage.c.CContext;
+import org.graalvm.nativeimage.c.function.CEntryPoint;
+import org.graalvm.nativeimage.c.function.CFunction;
+import org.graalvm.nativeimage.c.function.CFunctionPointer;
+import org.graalvm.nativeimage.c.function.InvokeCFunctionPointer;
+import org.graalvm.nativeimage.c.struct.AllowNarrowingCast;
+import org.graalvm.nativeimage.c.struct.AllowWideningCast;
+import org.graalvm.nativeimage.c.struct.CField;
+import org.graalvm.nativeimage.c.struct.CStruct;
+import org.graalvm.nativeimage.c.type.CCharPointer;
+import org.graalvm.nativeimage.c.type.CTypeConversion;
+import org.graalvm.nativeimage.c.type.VoidPointer;
+import org.graalvm.word.PointerBase;
+import org.graalvm.word.UnsignedWord;
+import org.graalvm.word.WordFactory;
+
+@CContext(CPropertiesDirectives.class)
+public class CInterface {
+
+ static {
+ ParserConfig.getGlobalInstance().setAsmEnable(false);
+ SerializeConfig.getGlobalInstance().setAsmEnable(false);
+ }
+
+ static class CPropertiesDirectives implements CContext.Directives {
+
+ public List<String> getOptions() {
+ return Arrays.asList("-I/usr/local/include");
+ }
+
+ public List<String> getHeaderFiles() {
+ /*
+ * The header file with the C declarations that are imported. We use a helper class that
+ * locates the file in our project structure.
+ */
+ return Collections.singletonList("<rocketmq/rocketmq.h>");
+ }
+ }
+
+ @CStruct("message") interface CMessage extends PointerBase {
+ @CField("topic")
+ CCharPointer getTopic();
+
+ @CField("topic")
+ void setTopic(CCharPointer value);
+
+ @CField("tags")
+ CCharPointer getTags();
+
+ @CField("tags")
+ void setTags(CCharPointer value);
+
+ @CField("body")
+ CCharPointer getBody();
+
+ @CField("body")
+ void setBody(CCharPointer value);
+
+ @AllowWideningCast
+ @CField("body_size")
+ UnsignedWord getBodySize();
+
+ @AllowNarrowingCast
+ @CField("body_size")
+ void setBodySize(UnsignedWord value);
+
+ @CField("key")
+ CCharPointer getKey();
+
+ @CField("key")
+ void setKey(CCharPointer value);
+
+ @CField("user_prop")
+ CCharPointer getUserProp();
+
+ @CField("user_prop")
+ void setUserProp(CCharPointer value);
+
+ @CField("system_prop")
+ CCharPointer getSystemProp();
+
+ @CField("system_prop")
+ void setSystemProp(CCharPointer value);
+ }
+
+ @CStruct("send_result") interface CSendResult extends PointerBase {
+ @CField("message_id")
+ CCharPointer getMessageId();
+
+ @CField("message_id")
+ void setMessageId(CCharPointer value);
+
+ @CField("error_no")
+ int getErrorCode();
+
+ @CField("error_no")
+ void setErrorCode(int value);
+
+ @CField("error_msg")
+ CCharPointer getError();
+
+ @CField("error_msg")
+ void setError(CCharPointer value);
+
+ }
+
+ @CStruct("factory_property") interface CFactoryProperty extends PointerBase {
+
+ @CField("group_id")
+ CCharPointer getGroupId();
+
+ @CField("group_id")
+ void setGroupId(CCharPointer value);
+
+ @CField("access_key")
+ CCharPointer getAccessKey();
+
+ @CField("access_key")
+ void setAccessKey(CCharPointer value);
+
+ @CField("access_secret")
+ CCharPointer getAccessSecret();
+
+ @CField("access_secret")
+ void setAccessSecret(CCharPointer value);
+
+ @CField("name_srv_addr")
+ CCharPointer getNameServerAddress();
+
+ @CField("name_srv_addr")
+ void setNameServerAddress(CCharPointer value);
+
+ @CField("name_srv_domain")
+ CCharPointer getNameServerDomain();
+
+ @CField("name_srv_domain")
+ void setNameServerDomain(CCharPointer value);
+
+ @CField("message_model")
+ CCharPointer getMessageModel();
+
+ @CField("message_model")
+ void setMessageModel(CCharPointer value);
+
+ @CField("send_msg_timeout_millis")
+ CCharPointer getSendMsgTimeoutMillis();
+
+ @CField("send_msg_timeout_millis")
+ void setSendMsgTimeoutMillis(CCharPointer value);
+
+ @CField("consume_thread_nums")
+ CCharPointer getConsumeThreadNums();
+
+ @CField("consume_thread_nums")
+ void setConsumeThreadNums(CCharPointer value);
+
+ @CField("ons_channel")
+ CCharPointer getOnsChannel();
+
+ @CField("ons_channel")
+ void setOnsChannel(CCharPointer value);
+
+ @CField("max_msg_cache_size")
+ CCharPointer getMaxMsgCacheSize();
+
+ @CField("max_msg_cache_size")
+ void setMaxMsgCacheSize(CCharPointer value);
+
+ @CField("ons_trace_switch")
+ CCharPointer getOnsTraceSwitch();
+
+ @CField("ons_trace_switch")
+ void setOnsTraceSwitch(CCharPointer value);
+
+ @CField("consumer_instance_name")
+ CCharPointer getConsumerInstanceName();
+
+ @CField("consumer_instance_name")
+ void setConsumerInstanceName(CCharPointer value);
+
+ @CField("language_identifier")
+ CCharPointer getLanguageIdentifier();
+
+ @CField("language_identifier")
+ void setLanguageIdentifier(CCharPointer value);
+
+ @CField("instance_id")
+ CCharPointer getInstanceId();
+
+ @CField("instance_id")
+ void setInstanceId(CCharPointer value);
+
+ @CField("use_domain")
+ int getUseDomain();
+
+ @CField("use_domain")
+ void setUseDomain(int value);
+ }
+
+ @CStruct("callback_func") interface CCallbackFunc extends PointerBase {
+
+ @CField("send_callback_ons")
+ CCharPointer getSendCallbackOns();
+
+ @CField("send_callback_ons")
+ void setSendCallbackOns(CCharPointer value);
+
+ @CField("on_success")
+ SuccessFunctionPointer getSuccessFunction();
+
+ @CField("on_success")
+ void setSuccessFunction(SuccessFunctionPointer successFunction);
+
+ @CField("on_exception")
+ ExceptionFunctionPointer getExceptionFunction();
+
+ @CField("on_exception")
+ void setExceptionFunction(ExceptionFunctionPointer exceptionFunction);
+ }
+
+ @CStruct("subscription") interface CSubscription extends PointerBase {
+ @CField("topic")
+ CCharPointer getTopic();
+
+ @CField("topic")
+ void setTopic(CCharPointer value);
+
+ @CField("sub_expression")
+ CCharPointer getSubExpression();
+
+ @CField("sub_expression")
+ void setSubExpression(CCharPointer value);
+
+ @CField("on_message")
+ OnMessageFunctionPointer getOnMessageFunction();
+
+ @CField("on_message")
+ void setOnMessageFunction(OnMessageFunctionPointer value);
+
+ @CField("opaque")
+ VoidPointer getOpaque();
+
+ @CField("opaque")
+ void setOpaque(VoidPointer value);
+ }
+
+ /* Import of a C function pointer type. */
+ interface SuccessFunctionPointer extends CFunctionPointer {
+
+ /*
+ * Invocation of the function pointer. A call to the function is replaced with an indirect
+ * call of the function pointer.
+ */
+ @InvokeCFunctionPointer
+ void invoke(IsolateThread thread, CCharPointer cstr, CCharPointer sendCallbackONS);
+ }
+
+ /* Import of a C function pointer type. */
+ interface ExceptionFunctionPointer extends CFunctionPointer {
+
+ /*
+ * Invocation of the function pointer. A call to the function is replaced with an indirect
+ * call of the function pointer.
+ */
+ @InvokeCFunctionPointer
+ void invoke(IsolateThread thread, CCharPointer cstr, int cint, CCharPointer sendCallbackONS);
+ }
+
+ interface SendCallbackFunctionPointer extends CFunctionPointer {
+ @InvokeCFunctionPointer
+ void invoke(IsolateThread thread, CSendResult sendResult);
+ }
+
+ interface OnMessageFunctionPointer extends CFunctionPointer {
+ @InvokeCFunctionPointer
+ int invoke(IsolateThread thread, VoidPointer opaque, CCharPointer topic, CCharPointer userProps,
+ CCharPointer sysProps, CCharPointer body, int bodyLen);
+ }
+
+ interface TransactionCheckFunctionPointer extends CFunctionPointer {
+ @InvokeCFunctionPointer
+ int invoke(IsolateThread thread, VoidPointer opaque, CCharPointer topic, CCharPointer userProps,
+ CCharPointer sysProps, CCharPointer body, int bodyLen);
+ }
+
+ interface TransactionExecuteFunctionPointer extends CFunctionPointer {
+ @InvokeCFunctionPointer
+ int invoke(IsolateThread thread, VoidPointer opaque, CCharPointer topic, CCharPointer userProps,
+ CCharPointer sysProps, CCharPointer body, int bodyLen);
+ }
+
+ public static ConcurrentHashMap<Integer, Admin> instances = new ConcurrentHashMap<Integer, Admin>();
+
+ public static AtomicInteger INDEX = new AtomicInteger();
+
+ private static int ONS_SEND_RESULT_MSG_ID_LEN = 64;
+ private static int ONS_SEND_RESULT_ERR_MSG_LEN = 1024;
+
+ private static Properties wrapConfig(CFactoryProperty property) {
+ Properties properties = new Properties();
+ properties.put(PropertyKeyConst.GROUP_ID, CTypeConversion.toJavaString(property.getGroupId()));
+ properties.put(PropertyKeyConst.AccessKey, CTypeConversion.toJavaString(property.getAccessKey()));
+ properties.put(PropertyKeyConst.SecretKey, CTypeConversion.toJavaString(property.getAccessSecret()));
+ if (property.getUseDomain() == 1) {
+ //use ons address
+ properties.put(PropertyKeyConst.ONSAddr, CTypeConversion.toJavaString(property.getNameServerDomain()));
+ } else {
+ properties.put(PropertyKeyConst.NAMESRV_ADDR, CTypeConversion.toJavaString(property.getNameServerAddress()));
+ }
+
+ String messageModel = CTypeConversion.toJavaString(property.getMessageModel());
+ String consumeThreadNums = CTypeConversion.toJavaString(property.getConsumeThreadNums());
+ String onsChannel = CTypeConversion.toJavaString(property.getOnsChannel());
+ String maxMsgCacheSize = CTypeConversion.toJavaString(property.getMaxMsgCacheSize());
+ String onsTraceSwitch = CTypeConversion.toJavaString(property.getOnsTraceSwitch());
+ String consumerInstanceName = CTypeConversion.toJavaString(property.getConsumerInstanceName());
+ String sendMsgTimeoutMillis = CTypeConversion.toJavaString(property.getSendMsgTimeoutMillis());
+ String languageIdentifier = CTypeConversion.toJavaString(property.getLanguageIdentifier());
+ String instanceId = CTypeConversion.toJavaString(property.getInstanceId());
+
+ if (messageModel != null && !messageModel.trim().isEmpty()) {
+ properties.put(PropertyKeyConst.MessageModel, messageModel);
+ }
+ if (consumeThreadNums != null && Integer.valueOf(consumeThreadNums) > 0) {
+ properties.put(PropertyKeyConst.ConsumeThreadNums, consumeThreadNums);
+ }
+ if (onsChannel != null) {
+ properties.put(PropertyKeyConst.OnsChannel, onsChannel);
+ }
+ if (maxMsgCacheSize != null) {
+ properties.put(PropertyKeyConst.MaxCachedMessageSizeInMiB, maxMsgCacheSize);
+ }
+ if (onsTraceSwitch != null) {
+ properties.put(PropertyKeyConst.MsgTraceSwitch, onsTraceSwitch);
+ }
+ if (consumerInstanceName != null && !consumerInstanceName.trim().isEmpty()) {
+ properties.put(PropertyKeyConst.InstanceName, consumerInstanceName);
+ }
+ if (languageIdentifier != null) {
+ properties.put(PropertyKeyConst.LANGUAGE_IDENTIFIER, languageIdentifier);
+ }
+ if (sendMsgTimeoutMillis != null) {
+ int sendMsgTimeoutMillis_ = Integer.parseInt(sendMsgTimeoutMillis);
+ if (sendMsgTimeoutMillis_ >= 100 && sendMsgTimeoutMillis_ < 3000) {
+ properties.put(PropertyKeyConst.SendMsgTimeoutMillis, sendMsgTimeoutMillis);
+ }
+ }
+ if (instanceId != null) {
+ properties.put(PropertyKeyConst.INSTANCE_ID, instanceId);
+ }
+ return properties;
+ }
+
+ @CEntryPoint(name = "create_producer")
+ public static int create_producer(IsolateThread thread, CFactoryProperty property) {
+ Producer producer = ONSFactory.createProducer(wrapConfig(property));
+ producer.start();
+ int index = INDEX.getAndIncrement();
+ instances.put(index, producer);
+ return index;
+ }
+
+ @CEntryPoint(name = "create_transaction_producer")
+ public static int create_transaction_producer(IsolateThread thread, CFactoryProperty property, VoidPointer checker,
+ TransactionCheckFunctionPointer check) {
+ GraalTransactionChecker transactionChecker = new GraalTransactionChecker();
+ transactionChecker.opaque = checker;
+ transactionChecker.transactionCheck = check;
+ TransactionProducer producer = ONSFactory.createTransactionProducer(wrapConfig(property), transactionChecker);
+ producer.start();
+ int index = INDEX.getAndIncrement();
+ instances.put(index, producer);
+ return index;
+ }
+
+ @CEntryPoint(name = "create_consumer")
+ public static int create_consumer(IsolateThread thread, CFactoryProperty property) {
+ Consumer consumer = ONSFactory.createConsumer(wrapConfig(property));
+ int index = INDEX.getAndIncrement();
+ instances.put(index, consumer);
+ return index;
+ }
+
+ @CEntryPoint(name = "create_order_consumer")
+ public static int create_order_consumer(IsolateThread thread, CFactoryProperty property) {
+ OrderConsumer consumer = ONSFactory.createOrderedConsumer(wrapConfig(property));
+ int index = INDEX.getAndIncrement();
+ instances.put(index, consumer);
+ return index;
+ }
+
+ @CEntryPoint(name = "subscribe")
+ public static void subscribe(IsolateThread thread, int instanceIndex, CSubscription cSub) {
+ Admin instance = instances.get(instanceIndex);
+ if (instance instanceof Consumer) {
+ Consumer consumer = (Consumer) instance;
+ GraalMessageListener messageListener = new GraalMessageListener();
+ messageListener.opaque = cSub.getOpaque();
+ messageListener.onMessage = cSub.getOnMessageFunction();
+ consumer.subscribe(CTypeConversion.toJavaString(cSub.getTopic()),
+ CTypeConversion.toJavaString(cSub.getSubExpression()),
+ messageListener);
+ //System.out.println("Subscribe OK");
+ return;
+ }
+ //System.out.println("Subscribe failed");
+ }
+
+ @CEntryPoint(name = "subscribe_order_listener")
+ public static void subscribe_order_message_listener(IsolateThread thread, int instanceIndex, CSubscription cSub) {
+ Admin instance = instances.get(instanceIndex);
+ if (instance instanceof OrderConsumer) {
+ OrderConsumer consumer = (OrderConsumer) instance;
+ GraalMessageOrderListener messageListener = new GraalMessageOrderListener();
+ messageListener.opaque = cSub.getOpaque();
+ messageListener.onMessage = cSub.getOnMessageFunction();
+ consumer.subscribe(CTypeConversion.toJavaString(cSub.getTopic()),
+ CTypeConversion.toJavaString(cSub.getSubExpression()),
+ messageListener);
+ //System.out.println("Subscribe OK");
+ return;
+ }
+ //System.out.println("Subscribe failed");
+ }
+
+ @CEntryPoint(name = "start_instance")
+ public static void start_instance(IsolateThread thread, int instanceIndex) {
+ Admin instance = instances.get(instanceIndex);
+ if (null != instance) {
+ instance.start();
+ }
+ }
+
+ @CEntryPoint(name = "destroy_instance")
+ public static void destroy_instance(IsolateThread thread, int index) {
+ instances.get(index).shutdown();
+ instances.remove(index);
+ }
+
+ @CEntryPoint(name = "create_order_producer")
+ public static int create_order_producer(IsolateThread thread, CFactoryProperty property) {
+ OrderProducer orderProducer = ONSFactory.createOrderProducer(wrapConfig(property));
+ orderProducer.start();
+ int index = INDEX.getAndIncrement();
+ instances.put(index, orderProducer);
+ return index;
+ }
+
+ @CEntryPoint(name = "send_message")
+ public static void send_message(IsolateThread thread, int producerId, CMessage cMsg, CSendResult sendResult) {
+ Admin instance = instances.get(producerId);
+ CTypeConversion.CCharPointerHolder pin = null;
+ try {
+ if (instance instanceof Producer) {
+ try {
+ Message msg = message_transformer(cMsg);
+ SendResult result = ((Producer) instance).send(msg);
+ sendResult.setErrorCode(0);
+ //sendResult.setError(CTypeConversion.toCString(null).get());
+ //sendResult.setMessageId(CTypeConversion.toCString(result.getMessageId()).get());
+ pin = CTypeConversion.toCString(result.getMessageId());
+ int len = Math.min(ONS_SEND_RESULT_MSG_ID_LEN, result.getMessageId().length());
+ memmove(sendResult.getMessageId(), pin.get(), WordFactory.unsigned(len));
+ } catch (ONSClientException e) {
+ sendResult.setErrorCode(ErrorCode.SEND_MESSAGE_FAILURE.getCode());
+ pin = CTypeConversion.toCString(e.getMessage());
+ memmove(sendResult.getError(), pin.get(),
+ WordFactory.unsigned(Math.min(ONS_SEND_RESULT_ERR_MSG_LEN, e.getMessage().length())));
+ }
+ } else {
+ sendResult.setErrorCode(ErrorCode.BAD_PRODUCER_INDEX.getCode());
+ pin = CTypeConversion.toCString(ErrorCode.BAD_PRODUCER_INDEX.getDesc());
+ int length = Math.min(ONS_SEND_RESULT_ERR_MSG_LEN, ErrorCode.BAD_PRODUCER_INDEX.getDesc().length());
+ memmove(sendResult.getError(), pin.get(), WordFactory.unsigned(length));
+ }
+ } finally {
+ if (null != pin) {
+ pin.close();
+ }
+ }
+ }
+
+ @CEntryPoint(name = "send_message_oneway")
+ public static void send_message_oneway(IsolateThread thread, int producerId, CMessage cMsg,
+ CSendResult sendResult) {
+ Admin instance = instances.get(producerId);
+ CTypeConversion.CCharPointerHolder pin = null;
+ try {
+ if (instance instanceof Producer) {
+ Message message = message_transformer(cMsg);
+ try {
+ ((Producer) instance).sendOneway(message);
+ } catch (ONSClientException e) {
+ sendResult.setErrorCode(ErrorCode.SEND_MESSAGE_FAILURE.getCode());
+ pin = CTypeConversion.toCString(e.getMessage());
+ int len = Math.min(ONS_SEND_RESULT_ERR_MSG_LEN, e.getMessage().length());
+ memmove(sendResult.getError(), pin.get(), WordFactory.unsigned(len));
+ }
+ }
+ } finally {
+ if (null != pin) {
+ pin.close();
+ }
+ }
+ }
+
+ @CFunction
+ protected static native PointerBase memmove(PointerBase dest, PointerBase src, UnsignedWord n);
+
+ @CEntryPoint(name = "send_message_async")
+ public static void send_message_async(final IsolateThread thread, int producerId, final CMessage cMessage,
+ final CSendResult cSendResult, final CCallbackFunc cCallbackFunc) {
+
+ Admin instance = instances.get(producerId);
+ if (instance instanceof Producer) {
+ Message message = message_transformer(cMessage);
+ GraalSendCallback mcb = new GraalSendCallback();
+ mcb.sendCallbackONS = cCallbackFunc.getSendCallbackOns();
+ mcb.exceptionFunctionPtr = cCallbackFunc.getExceptionFunction();
+ mcb.successFunctionPtr = cCallbackFunc.getSuccessFunction();
+ mcb.message = cMessage.getBody();
+ CTypeConversion.CCharPointerHolder pin = null;
+ try {
+ ((Producer) instance).sendAsync(message, mcb);
+ } catch (ONSClientException e) {
+ cSendResult.setErrorCode(ErrorCode.SEND_MESSAGE_FAILURE.getCode());
+ pin = CTypeConversion.toCString(e.getMessage());
+ memmove(cSendResult.getError(), pin.get(),
+ WordFactory.unsigned(Math.min(ONS_SEND_RESULT_ERR_MSG_LEN, e.getMessage().length())));
+ } finally {
+ if (null != pin) {
+ pin.close();
+ }
+ }
+ }
+ }
+
+ @CEntryPoint(name = "send_message_transaction")
+ public static void send_message_transaction(final IsolateThread thread, int producerId, final CMessage cMessage,
+ final CSendResult sendResult, VoidPointer executor, TransactionExecuteFunctionPointer execute) {
+ Admin instance = instances.get(producerId);
+ CTypeConversion.CCharPointerHolder pin = null;
+ try {
+ if (instance instanceof TransactionProducer) {
+ try {
+ Message message = message_transformer(cMessage);
+ GraalTransactionExecutor transactionExecutor = new GraalTransactionExecutor();
+ transactionExecutor.opaque = executor;
+ transactionExecutor.transactionExecute = execute;
+ SendResult result = ((TransactionProducer) instance).send(message, transactionExecutor, null);
+ sendResult.setErrorCode(0);
+ pin = CTypeConversion.toCString(result.getMessageId());
+ int len = Math.min(ONS_SEND_RESULT_MSG_ID_LEN, result.getMessageId().length());
+ memmove(sendResult.getMessageId(), pin.get(), WordFactory.unsigned(len));
+ } catch (Exception e) {
+ sendResult.setErrorCode(ErrorCode.SEND_MESSAGE_FAILURE.getCode());
+ pin = CTypeConversion.toCString(e.getMessage());
+ memmove(sendResult.getError(), pin.get(),
+ WordFactory.unsigned(Math.min(ONS_SEND_RESULT_ERR_MSG_LEN, e.getMessage().length())));
+ }
+ } else {
+ sendResult.setErrorCode(ErrorCode.BAD_PRODUCER_INDEX.getCode());
+ sendResult.setError(CTypeConversion.toCString(ErrorCode.BAD_PRODUCER_INDEX.getDesc()).get());
+ pin = CTypeConversion.toCString(ErrorCode.BAD_PRODUCER_INDEX.getDesc());
+ int len = Math.min(ONS_SEND_RESULT_MSG_ID_LEN, ErrorCode.BAD_PRODUCER_INDEX.getDesc().length());
+ memmove(sendResult.getError(), pin.get(), WordFactory.unsigned(len));
+ }
+ } finally {
+ if (null != pin) {
+ pin.close();
+ }
+ }
+ }
+
+ @CEntryPoint(name = "send_order_message")
+ public static void send_order_message(IsolateThread thread, int producerId, CMessage cMsg, CSendResult sendResult,
+ CCharPointer shardingKey) {
+ Admin instance = instances.get(producerId);
+ CTypeConversion.CCharPointerHolder pin = null;
+ try {
+ if (instance instanceof OrderProducer) {
+ Message msg = message_transformer(cMsg);
+ try {
+ SendResult result = ((OrderProducer) instance).send(msg, CTypeConversion.toJavaString(shardingKey));
+ sendResult.setErrorCode(0);
+ pin = CTypeConversion.toCString(result.getMessageId());
+ memmove(sendResult.getMessageId(), pin.get(),
+ WordFactory.unsigned(Math.min(ONS_SEND_RESULT_MSG_ID_LEN, result.getMessageId().length())));
+ } catch (ONSClientException e) {
+ sendResult.setErrorCode(ErrorCode.SEND_MESSAGE_FAILURE.getCode());
+ pin = CTypeConversion.toCString(e.getMessage());
+ memmove(sendResult.getError(), pin.get(),
+ WordFactory.unsigned(Math.min(ONS_SEND_RESULT_ERR_MSG_LEN, e.getMessage().length())));
+ }
+ } else {
+ sendResult.setErrorCode(ErrorCode.BAD_PRODUCER_INDEX.getCode());
+ int length = Math.min(ONS_SEND_RESULT_ERR_MSG_LEN, ErrorCode.BAD_PRODUCER_INDEX.getDesc().length());
+ pin = CTypeConversion.toCString(ErrorCode.BAD_PRODUCER_INDEX.getDesc());
+ memmove(sendResult.getError(), pin.get(), WordFactory.unsigned(length));
+ }
+ } finally {
+ if (null != pin) {
+ pin.close();
+ }
+ }
+ }
+
+ private static Message message_transformer(CMessage cMsg) {
+ Message msg = new Message(
+ CTypeConversion.toJavaString(cMsg.getTopic()),
+ CTypeConversion.toJavaString(cMsg.getTags()),
+ CTypeConversion.toJavaString(cMsg.getBody(), cMsg.getBodySize()).getBytes());
+ String userProps = CTypeConversion.toJavaString(cMsg.getUserProp());
+ assignProperties(userProps, msg, false);
+
+ String sysProps = CTypeConversion.toJavaString(cMsg.getSystemProp());
+ assignProperties(sysProps, msg, true);
+ return msg;
+ }
+
+ private static void assignProperties(String json, Message msg, boolean sys) {
+ JSONObject root = JSON.parseObject(json);
+ for (Map.Entry<String, Object> entry : root.entrySet()) {
+ if (sys) {
+ msg.putSystemProperties(entry.getKey(), String.valueOf(entry.getValue()));
+ } else {
+ msg.putUserProperties(entry.getKey(), String.valueOf(entry.getValue()));
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ }
+
+}
diff --git a/src/main/java/org/apache/rocketmq/graalvm/ErrorCode.java b/src/main/java/org/apache/rocketmq/graalvm/ErrorCode.java
new file mode 100644
index 0000000..c6a4d50
--- /dev/null
+++ b/src/main/java/org/apache/rocketmq/graalvm/ErrorCode.java
@@ -0,0 +1,21 @@
+package org.apache.rocketmq.graalvm;
+
+public enum ErrorCode {
+ BAD_PRODUCER_INDEX(1, "Invalid producer ID"),
+ SEND_MESSAGE_FAILURE(2, "Send message failure");
+ private int code;
+ private String desc;
+
+ ErrorCode(int code, String desc) {
+ this.code = code;
+ this.desc = desc;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/src/main/java/org/apache/rocketmq/graalvm/GraalMessageListener.java b/src/main/java/org/apache/rocketmq/graalvm/GraalMessageListener.java
new file mode 100644
index 0000000..ed607f9
--- /dev/null
+++ b/src/main/java/org/apache/rocketmq/graalvm/GraalMessageListener.java
@@ -0,0 +1,44 @@
+package org.apache.rocketmq.graalvm;
+
+import com.alibaba.fastjson.JSON;
+import org.apache.rocketmq.ons.api.Action;
+import org.apache.rocketmq.ons.api.ConsumeContext;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.MessageListener;
+import org.graalvm.nativeimage.CurrentIsolate;
+import org.graalvm.nativeimage.IsolateThread;
+import org.graalvm.nativeimage.c.type.CTypeConversion;
+import org.graalvm.nativeimage.c.type.VoidPointer;
+
+public class GraalMessageListener implements MessageListener {
+
+ public VoidPointer opaque;
+
+ public CInterface.OnMessageFunctionPointer onMessage;
+
+
+ public Action consume(Message message, ConsumeContext context) {
+ IsolateThread currentThread = CurrentIsolate.getCurrentThread();
+ CTypeConversion.CCharPointerHolder pin_topic = CTypeConversion.toCString(message.getTopic());
+ CTypeConversion.CCharPointerHolder pin_u_prop = CTypeConversion.toCString(JSON.toJSONString(message.getUserProperties()));
+ CTypeConversion.CCharPointerHolder pin_s_prop = CTypeConversion.toCString(JSON.toJSONString(message.getSystemProperties()));
+ CTypeConversion.CCharPointerHolder pin_body = CTypeConversion.toCString(new String(message.getBody()));
+ try {
+ if (0 != onMessage.invoke(currentThread, opaque,
+ pin_topic.get(),
+ pin_u_prop.get(),
+ pin_s_prop.get(),
+ pin_body.get(),
+ message.getBody().length)
+ ) {
+ return Action.ReconsumeLater;
+ }
+ return Action.CommitMessage;
+ } finally {
+ pin_body.close();
+ pin_s_prop.close();
+ pin_u_prop.close();
+ pin_topic.close();
+ }
+ }
+}
diff --git a/src/main/java/org/apache/rocketmq/graalvm/GraalMessageOrderListener.java b/src/main/java/org/apache/rocketmq/graalvm/GraalMessageOrderListener.java
new file mode 100644
index 0000000..f789b72
--- /dev/null
+++ b/src/main/java/org/apache/rocketmq/graalvm/GraalMessageOrderListener.java
@@ -0,0 +1,43 @@
+package org.apache.rocketmq.graalvm;
+
+import com.alibaba.fastjson.JSON;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.order.ConsumeOrderContext;
+import org.apache.rocketmq.ons.api.order.MessageOrderListener;
+import org.apache.rocketmq.ons.api.order.OrderAction;
+import org.graalvm.nativeimage.CurrentIsolate;
+import org.graalvm.nativeimage.IsolateThread;
+import org.graalvm.nativeimage.c.type.CTypeConversion;
+import org.graalvm.nativeimage.c.type.VoidPointer;
+
+public class GraalMessageOrderListener implements MessageOrderListener {
+
+ public VoidPointer opaque;
+ public CInterface.OnMessageFunctionPointer onMessage;
+
+ public OrderAction consume(Message message, ConsumeOrderContext context) {
+ IsolateThread currentThread = CurrentIsolate.getCurrentThread();
+ CTypeConversion.CCharPointerHolder pin_topic = CTypeConversion.toCString(message.getTopic());
+ CTypeConversion.CCharPointerHolder pin_u_prop = CTypeConversion.toCString(JSON.toJSONString(message.getUserProperties()));
+ CTypeConversion.CCharPointerHolder pin_s_prop = CTypeConversion.toCString(JSON.toJSONString(message.getSystemProperties()));
+ CTypeConversion.CCharPointerHolder pin_body = CTypeConversion.toCString(new String(message.getBody()));
+ try {
+ if (0 != onMessage.invoke(currentThread, opaque,
+ pin_topic.get(),
+ pin_u_prop.get(),
+ pin_s_prop.get(),
+ pin_body.get(),
+ message.getBody().length)
+ ) {
+ return OrderAction.Suspend;
+ }
+ return OrderAction.Success;
+ } finally {
+ pin_body.close();
+ pin_s_prop.close();
+ pin_u_prop.close();
+ pin_topic.close();
+ }
+
+ }
+}
diff --git a/src/main/java/org/apache/rocketmq/graalvm/GraalSendCallback.java b/src/main/java/org/apache/rocketmq/graalvm/GraalSendCallback.java
new file mode 100644
index 0000000..a395b02
--- /dev/null
+++ b/src/main/java/org/apache/rocketmq/graalvm/GraalSendCallback.java
@@ -0,0 +1,29 @@
+package org.apache.rocketmq.graalvm;
+
+import org.apache.rocketmq.ons.api.OnExceptionContext;
+import org.apache.rocketmq.ons.api.SendCallback;
+import org.apache.rocketmq.ons.api.SendResult;
+import org.graalvm.nativeimage.CurrentIsolate;
+import org.graalvm.nativeimage.IsolateThread;
+import org.graalvm.nativeimage.c.type.CCharPointer;
+import org.graalvm.nativeimage.c.type.CTypeConversion;
+import org.graalvm.word.WordFactory;
+
+public class GraalSendCallback implements SendCallback, Cloneable {
+ public CInterface.SuccessFunctionPointer successFunctionPtr;
+ public CInterface.ExceptionFunctionPointer exceptionFunctionPtr;
+ public CCharPointer sendCallbackONS;
+ public CCharPointer message;
+
+ public void onSuccess(SendResult var1) {
+ IsolateThread currentThread = CurrentIsolate.getCurrentThread();
+ CTypeConversion.CCharPointerHolder pin = CTypeConversion.toCString(var1.getMessageId());
+ successFunctionPtr.invoke(currentThread, pin.get(), sendCallbackONS);
+ pin.close();
+ }
+
+ public void onException(OnExceptionContext var1) {
+ IsolateThread currentThread = CurrentIsolate.getCurrentThread();
+ exceptionFunctionPtr.invoke(currentThread, message, ErrorCode.SEND_MESSAGE_FAILURE.getCode(), sendCallbackONS);
+ }
+}
diff --git a/src/main/java/org/apache/rocketmq/graalvm/GraalTransactionChecker.java b/src/main/java/org/apache/rocketmq/graalvm/GraalTransactionChecker.java
new file mode 100644
index 0000000..2b6661a
--- /dev/null
+++ b/src/main/java/org/apache/rocketmq/graalvm/GraalTransactionChecker.java
@@ -0,0 +1,47 @@
+package org.apache.rocketmq.graalvm;
+
+import com.alibaba.fastjson.JSON;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.transaction.LocalTransactionChecker;
+import org.apache.rocketmq.ons.api.transaction.TransactionStatus;
+import org.graalvm.nativeimage.CurrentIsolate;
+import org.graalvm.nativeimage.IsolateThread;
+import org.graalvm.nativeimage.c.type.CTypeConversion;
+import org.graalvm.nativeimage.c.type.VoidPointer;
+
+
+public class GraalTransactionChecker implements LocalTransactionChecker {
+
+ public VoidPointer opaque;
+
+ public CInterface.TransactionCheckFunctionPointer transactionCheck;
+
+ @Override
+ public TransactionStatus check(Message message) {
+ IsolateThread currentThread = CurrentIsolate.getCurrentThread();
+ CTypeConversion.CCharPointerHolder pin_topic = CTypeConversion.toCString(message.getTopic());
+ CTypeConversion.CCharPointerHolder pin_u_prop = CTypeConversion.toCString(JSON.toJSONString(message.getUserProperties()));
+ CTypeConversion.CCharPointerHolder pin_s_prop = CTypeConversion.toCString(JSON.toJSONString(message.getSystemProperties()));
+ CTypeConversion.CCharPointerHolder pin_body = CTypeConversion.toCString(new String(message.getBody()));
+ try {
+ int status = transactionCheck.invoke(currentThread, opaque,
+ pin_topic.get(),
+ pin_u_prop.get(),
+ pin_s_prop.get(),
+ pin_body.get(),
+ message.getBody().length);
+ if (status == 0) {
+ return TransactionStatus.CommitTransaction;
+ } else if (status == 1) {
+ return TransactionStatus.RollbackTransaction;
+ } else {
+ return TransactionStatus.Unknow;
+ }
+ } finally {
+ pin_body.close();
+ pin_s_prop.close();
+ pin_u_prop.close();
+ pin_topic.close();
+ }
+ }
+}
diff --git a/src/main/java/org/apache/rocketmq/graalvm/GraalTransactionExecutor.java b/src/main/java/org/apache/rocketmq/graalvm/GraalTransactionExecutor.java
new file mode 100644
index 0000000..b1cdfd9
--- /dev/null
+++ b/src/main/java/org/apache/rocketmq/graalvm/GraalTransactionExecutor.java
@@ -0,0 +1,45 @@
+package org.apache.rocketmq.graalvm;
+
+import com.alibaba.fastjson.JSON;
+import org.apache.rocketmq.ons.api.Message;
+import org.apache.rocketmq.ons.api.transaction.LocalTransactionExecuter;
+import org.apache.rocketmq.ons.api.transaction.TransactionStatus;
+import org.graalvm.nativeimage.CurrentIsolate;
+import org.graalvm.nativeimage.IsolateThread;
+import org.graalvm.nativeimage.c.type.CTypeConversion;
+import org.graalvm.nativeimage.c.type.VoidPointer;
+
+public class GraalTransactionExecutor implements LocalTransactionExecuter {
+ public VoidPointer opaque;
+ public CInterface.TransactionExecuteFunctionPointer transactionExecute;
+
+ @Override
+ public TransactionStatus execute(Message message, Object ob) {
+ IsolateThread currentThread = CurrentIsolate.getCurrentThread();
+ CTypeConversion.CCharPointerHolder pin_topic = CTypeConversion.toCString(message.getTopic());
+ CTypeConversion.CCharPointerHolder pin_u_prop = CTypeConversion.toCString(JSON.toJSONString(message.getUserProperties()));
+ CTypeConversion.CCharPointerHolder pin_s_prop = CTypeConversion.toCString(JSON.toJSONString(message.getSystemProperties()));
+ CTypeConversion.CCharPointerHolder pin_body = CTypeConversion.toCString(new String(message.getBody()));
+ try {
+ int status = transactionExecute.invoke(currentThread, opaque,
+ pin_topic.get(),
+ pin_u_prop.get(),
+ pin_s_prop.get(),
+ pin_body.get(),
+ message.getBody().length);
+ if (status == 0) {
+ return TransactionStatus.CommitTransaction;
+ } else if (status == 1) {
+ return TransactionStatus.RollbackTransaction;
+ } else {
+ return TransactionStatus.Unknow;
+ }
+ } finally {
+ pin_body.close();
+ pin_s_prop.close();
+ pin_u_prop.close();
+ pin_topic.close();
+ }
+ }
+
+}
diff --git a/src/main/java/org/apache/rocketmq/graalvm/substitutions/NettySubstitutions.java b/src/main/java/org/apache/rocketmq/graalvm/substitutions/NettySubstitutions.java
new file mode 100644
index 0000000..0440452
--- /dev/null
+++ b/src/main/java/org/apache/rocketmq/graalvm/substitutions/NettySubstitutions.java
@@ -0,0 +1,49 @@
+package org.apache.rocketmq.graalvm.substitutions;
+
+import com.oracle.svm.core.annotate.Alias;
+import com.oracle.svm.core.annotate.RecomputeFieldValue;
+import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind;
+import com.oracle.svm.core.annotate.Substitute;
+import com.oracle.svm.core.annotate.TargetClass;
+
+import io.netty.util.internal.logging.InternalLoggerFactory;
+import io.netty.util.internal.logging.JdkLoggerFactory;
+
+
+@TargetClass(io.netty.util.internal.logging.InternalLoggerFactory.class)
+final class Target_io_netty_util_internal_logging_InternalLoggerFactory {
+ @Substitute
+ private static InternalLoggerFactory newDefaultFactory(String name) {
+ return JdkLoggerFactory.INSTANCE;
+ }
+}
+
+@TargetClass(className = "io.netty.util.internal.PlatformDependent0")
+final class Target_io_netty_util_internal_PlatformDependent0 {
+
+ @Alias
+ @RecomputeFieldValue(kind = Kind.FieldOffset, //
+ declClassName = "java.nio.Buffer", //
+ name = "address") //
+ private static long ADDRESS_FIELD_OFFSET;
+}
+
+@TargetClass(className = "io.netty.util.internal.CleanerJava6")
+final class Target_io_netty_util_internal_CleanerJava6 {
+ @Alias
+ @RecomputeFieldValue(kind = Kind.FieldOffset, //
+ declClassName = "java.nio.DirectByteBuffer", //
+ name = "cleaner") //
+ private static long CLEANER_FIELD_OFFSET;
+}
+
+@TargetClass(className = "io.netty.util.internal.shaded.org.jctools.util.UnsafeRefArrayAccess")
+final class Target_io_netty_util_internal_shaded_org_jctools_util_UnsafeRefArrayAccess {
+ @Alias
+ @RecomputeFieldValue(kind = Kind.ArrayIndexShift, declClass = Object[].class) //
+ public static int REF_ELEMENT_SHIFT;
+}
+
+
+public class NettySubstitutions {
+}
\ No newline at end of file
diff --git a/tools/graal/README.md b/tools/graal/README.md
new file mode 100644
index 0000000..3a76f4e
--- /dev/null
+++ b/tools/graal/README.md
@@ -0,0 +1,19 @@
+# Generating reflection json file
+
+1. You need to package your java program in a JAR files.
+
+2. Check the native-image-configure tool by command:
+```bash
+native-image-configure --help
+```
+3. Execute the command below (we assume that your JAR file named demo.jar):
+```bash
+java -agentlib:native-image-agent=trace-output=./trace-file.json -jar demo.jar
+```
+4. Generate the reflection config json file.
+```bash
+native-image-configure process-trace --output-dir=./graal/ ./trace-file.json
+```
+5. Then, you will find `reflection_config.json` in the output directory: `./graal/`.
+
+6. More detail: [CONFIGURE.md](https://github.com/oracle/graal/blob/master/substratevm/CONFIGURE.md), [REFLECTION.md](https://github.com/oracle/graal/blob/master/substratevm/REFLECTION.md).
\ No newline at end of file
diff --git a/tools/graal/reflection_config.json b/tools/graal/reflection_config.json
new file mode 100644
index 0000000..43ca4c7
--- /dev/null
+++ b/tools/graal/reflection_config.json
@@ -0,0 +1,352 @@
+[
+{
+ "name":"org.apache.rocketmq.client.consumer.DefaultMQPushConsumer",
+ "allDeclaredFields":true
+},
+{
+ "name":"org.apache.rocketmq.client.consumer.store.OffsetSerializeWrapper",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true
+},
+{
+ "name":"org.apache.rocketmq.common.message.MessageQueue",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.body.ConsumeMessageDirectlyResult",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.body.ConsumeStatus",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.body.ConsumerRunningInfo",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.body.ProcessQueueInfo",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.body.ResetOffsetBody",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.ConsumeMessageDirectlyResultRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.ViewMessageRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.GetMaxOffsetRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.GetMaxOffsetResponseHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.GetMinOffsetRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.GetMinOffsetResponseHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.SearchOffsetRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.SearchOffsetResponseHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.GetEarliestMsgStoretimeRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.GetEarliestMsgStoretimeRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.CheckTransactionStateRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.CheckTransactionStateResponseHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.EndTransactionRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.body.LockBatchRequestBody",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.body.LockBatchResponseBody",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.body.UnlockBatchRequestBody",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.GetConsumerListByGroupRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.GetConsumerListByGroupResponseBody",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.GetConsumerRunningInfoRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.NotifyConsumerIdsChangedRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.PullMessageRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.PullMessageResponseHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.QueryConsumerOffsetRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.QueryConsumerOffsetResponseHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.ResetOffsetRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.SendMessageRequestHeaderV2",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.SendMessageResponseHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.UnregisterClientRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.UpdateConsumerOffsetRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.header.namesrv.GetRouteInfoRequestHeader",
+ "allDeclaredFields":true,
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.heartbeat.ConsumerData",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.heartbeat.HeartbeatData",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.heartbeat.ProducerData",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.route.BrokerData",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.route.QueueData",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.common.protocol.route.TopicRouteData",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.remoting.protocol.RemotingCommand",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allDeclaredConstructors":true
+},
+{
+ "name":"org.apache.rocketmq.remoting.protocol.RemotingSerializable",
+ "allDeclaredFields":true,
+ "allDeclaredMethods":true,
+ "allPublicMethods":true
+},
+{
+ "name":"org.apache.rocketmq.ons.api.impl.ONSFactoryImpl",
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"io.netty.buffer.AbstractByteBufAllocator",
+ "allDeclaredMethods":true
+},
+{
+ "name":"io.netty.channel.socket.nio.NioSocketChannel",
+ "methods":[{"name":"<init>","parameterTypes":[] }]
+},
+{
+ "name":"io.netty.util.ReferenceCountUtil",
+ "allDeclaredMethods":true
+},
+{
+ "name":"io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueColdProducerFields",
+ "fields":[{"name":"producerLimit"}]
+},
+{
+ "name":"io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueConsumerFields",
+ "fields":[{"name":"consumerIndex"}]
+},
+{
+ "name":"io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueProducerFields",
+ "fields":[{"name":"producerIndex"}]
+},
+{
+ "name":"io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueConsumerIndexField",
+ "fields":[{"name":"consumerIndex"}]
+},
+{
+ "name":"io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerIndexField",
+ "fields":[{"name":"producerIndex"}]
+},
+{
+ "name":"io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerLimitField",
+ "fields":[{"name":"producerLimit"}]
+},
+{
+ "name":"java.io.Serializable",
+ "allPublicMethods":true
+},
+{
+ "name":"java.lang.Comparable",
+ "allPublicMethods":true
+},
+{
+ "name":"java.lang.management.ManagementFactory",
+ "methods":[{"name":"getRuntimeMXBean","parameterTypes":[] }]
+},
+{
+ "name":"java.lang.management.RuntimeMXBean",
+ "methods":[{"name":"getName","parameterTypes":[] }]
+},
+{
+ "name":"java.nio.Bits",
+ "methods":[{"name":"unaligned","parameterTypes":[] }]
+},
+{
+ "name":"java.nio.Buffer",
+ "fields":[{"name":"address"}]
+},
+{
+ "name":"java.nio.DirectByteBuffer",
+ "fields":[{"name":"cleaner"}],
+ "methods":[{"name":"<init>","parameterTypes":["long","int"] }]
+},
+{
+ "name":"java.util.Properties",
+ "fields":[{"name":"defaults"}]
+},
+{
+ "name":"sun.misc.Cleaner",
+ "methods":[{"name":"clean","parameterTypes":[] }]
+},
+{
+ "name":"sun.misc.Unsafe",
+ "fields":[{"name":"theUnsafe"}],
+ "methods":[
+ {"name":"copyMemory","parameterTypes":["java.lang.Object","long","java.lang.Object","long","long"] },
+ {"name":"getAndSetObject","parameterTypes":["java.lang.Object","long","java.lang.Object"] }
+ ]
+},
+{
+ "name":"sun.misc.VM",
+ "methods":[{"name":"maxDirectMemory","parameterTypes":[] }]
+},
+{
+ "name":"sun.nio.ch.SelectorImpl",
+ "fields":[
+ {"name":"publicSelectedKeys"},
+ {"name":"selectedKeys"}
+ ]
+}
+]
+