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