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"}
+  ]
+}
+]
+