This is an automated email from the ASF dual-hosted git repository.

likeguo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 5120c3fab [TASK] save plugin jar to db (#4416)
5120c3fab is described below

commit 5120c3faba10395a98e0207ab47262c0c6f8de2d
Author: Misaya295 <[email protected]>
AuthorDate: Mon Mar 6 22:37:59 2023 +0800

    [TASK] save plugin jar to db (#4416)
    
    * feature:sava plugin jat to db
    
    * fix ci
    
    * fix ci
    
    * feature: modify to plugin_jar
    
    * feature: add sql and check jar
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * delete useless code
    
    * modify check jar
    
    * sql format
    
    * fix ci
    
    * add log
    
    * format code & add license
    
    ---------
    
    Co-authored-by: likeguo <[email protected]>
    Co-authored-by: moremind <[email protected]>
---
 db/init/mysql/schema.sql                           | 79 +++++++++---------
 db/init/oracle/schema.sql                          | 82 +++++++++---------
 db/init/pg/create-table.sql                        | 82 +++++++++---------
 db/upgrade/2.5.1-upgrade-2.6.0-mysql.sql           |  5 +-
 db/upgrade/2.5.1-upgrade-2.6.0-oracle.sql          |  6 +-
 db/upgrade/2.5.1-upgrade-2.6.0-pg.sql              |  6 +-
 pom.xml                                            |  7 ++
 .../src/http/http-debug-plugin-controller-api.http | 19 +----
 .../shenyu/admin/controller/PluginController.java  | 14 ++--
 .../apache/shenyu/admin/model/dto/PluginDTO.java   | 33 +++++++-
 .../apache/shenyu/admin/model/entity/PluginDO.java | 58 ++++++++++++-
 .../admin/service/impl/PluginServiceImpl.java      | 37 ++++++++-
 .../src/main/resources/mappers/plugin-sqlmap.xml   | 12 ++-
 .../src/main/resources/sql-script/h2/schema.sql    |  1 +
 .../admin/controller/PluginControllerTest.java     | 66 ++++++++++-----
 shenyu-common/pom.xml                              |  5 ++
 .../shenyu/common/constant/AdminConstants.java     |  7 ++
 .../org/apache/shenyu/common/dto/PluginData.java   | 73 +++++++++++-----
 .../shenyu/common/utils/JarDependencyUtils.java    | 96 ++++++++++++++++++++++
 .../src/main/release-docs/LICENSE                  |  1 +
 .../test/http/combination/MqttPluginTest.java      |  2 +-
 .../brpc/handler/BrpcPluginDataHandlerTest.java    |  2 +-
 .../shenyu/plugin/casdoor/CasdoorPluginTest.java   |  2 +-
 .../handle/CasdoorPluginDateHandlerTest.java       |  2 +-
 .../dubbo/handler/AlibabaDubboPluginDataTest.java  |  4 +-
 .../apache/shenyu/plugin/jwt/JwtPluginTest.java    |  2 +-
 .../jwt/handle/JwtPluginDataHandlerTest.java       |  2 +-
 .../mqtt/handler/MqttPluginDataHandlerTest.java    |  4 +-
 .../sofa/handler/SofaPluginDataHandlerTest.java    |  4 +-
 .../tars/handler/TarsPluginDataHandlerTest.java    |  2 +-
 .../apache/shenyu/plugin/waf/WafPluginTest.java    |  4 +-
 .../waf/handler/WafPluginDataHandlerTest.java      |  2 +-
 .../web/controller/LocalPluginControllerTest.java  |  2 +-
 33 files changed, 511 insertions(+), 212 deletions(-)

diff --git a/db/init/mysql/schema.sql b/db/init/mysql/schema.sql
index 9e355458e..1b6e693fe 100644
--- a/db/init/mysql/schema.sql
+++ b/db/init/mysql/schema.sql
@@ -773,51 +773,52 @@ CREATE TABLE `plugin`  (
   `enabled` tinyint(0) NOT NULL DEFAULT 0 COMMENT 'whether to open (0, not 
open, 1 open)',
   `date_created` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 
'create time',
   `date_updated` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE 
CURRENT_TIMESTAMP(3) COMMENT 'update time',
+  `plugin_jar` mediumblob  DEFAULT NULL COMMENT 'plugin jar',
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci 
ROW_FORMAT = Dynamic;
 
 -- ----------------------------
 -- Records of plugin
 -- ----------------------------
-INSERT INTO `plugin` VALUES ('1', 'sign', NULL, 'Authentication', 20, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('31', 'mock', null, 'Mock', 1, 0, '2022-06-16 
14:40:35', '2022-06-16 14:40:55');
-INSERT INTO `plugin` VALUES ('10', 'sentinel', NULL, 'FaultTolerance', 140, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('11', 'sofa', 
'{\"protocol\":\"zookeeper\",\"register\":\"127.0.0.1:2181\",\"threadpool\":\"shared\"}',
 'Proxy', 310, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('12', 'resilience4j', NULL, 'FaultTolerance', 
310, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('13', 'tars', 
'{\"multiSelectorHandle\":\"1\",\"multiRuleHandle\":\"0\",\"threadpool\":\"shared\"}',
 'Proxy', 310, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('14', 'contextPath', NULL, 'HttpProcess', 80, 1, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('15', 'grpc', 
'{\"multiSelectorHandle\":\"1\",\"multiRuleHandle\":\"0\",\"threadpool\":\"shared\"}',
 'Proxy', 310, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('16', 'redirect', NULL, 'HttpProcess', 110, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('17', 'motan', 
'{\"register\":\"127.0.0.1:2181\",\"corethreads\":0,\"threads\":2147483647,\"queues\":0,\"threadpool\":\"shared\"}',
 'Proxy', 310, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('18', 'loggingConsole', NULL, 'Logging', 160, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('19', 'jwt', '{\"secretKey\":\"key\"}', 
'Authentication', 30, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('2', 'waf', '{\"model\":\"black\"}', 
'Authentication', 50, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('20', 'request', NULL, 'HttpProcess', 120, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('21', 'oauth2', NULL, 'Authentication', 40, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('22', 'paramMapping', 
'{\"ruleHandlePageType\":\"custom\"}', 'HttpProcess', 70, 0, '2022-05-25 
18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('23', 'modifyResponse', 
'{\"ruleHandlePageType\":\"custom\"}', 'HttpProcess', 220, 0, '2022-05-25 
18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('24', 'cryptorRequest', NULL, 'Cryptor', 100, 1, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('25', 'cryptorResponse', NULL, 'Cryptor', 410, 1, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('26', 'websocket', 
'{\"multiSelectorHandle\":\"1\"}', 'Proxy', 200, 1, '2022-05-25 18:02:53', 
'2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('27', 'generalContext', NULL, 'Common', 125, 1, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('28', 'mqtt', '{\"port\": 
9500,\"bossGroupThreadCount\": 1,\"maxPayloadSize\": 
65536,\"workerGroupThreadCount\": 12,\"userName\": \"shenyu\",\"password\": 
\"shenyu\",\"isEncryptPassword\": false,\"encryptMode\": 
\"\",\"leakDetectorLevel\": \"DISABLED\"}', 'Proxy', 125, 0, '2022-05-25 
18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('29', 'loggingRocketMQ', 
'{\"topic\":\"shenyu-access-logging\", \"namesrvAddr\": 
\"localhost:9876\",\"producerGroup\":\"shenyu-plugin-logging-rocketmq\"}', 
'Logging', 170, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('3', 'rewrite', NULL, 'HttpProcess', 90, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('30', 'cache', '{\"cacheType\":\"memory\"}', 
'Cache', 10, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('4', 'rateLimiter', 
'{\"master\":\"mymaster\",\"mode\":\"standalone\",\"url\":\"192.168.1.1:6379\",\"password\":\"abc\"}',
 'FaultTolerance', 60, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('5', 'divide', 
'{\"multiSelectorHandle\":\"1\",\"multiRuleHandle\":\"0\"}', 'Proxy', 200, 1, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('6', 'dubbo', 
'{\"register\":\"zookeeper://localhost:2181\",\"multiSelectorHandle\":\"1\",\"threadpool\":\"shared\",\"corethreads\":0,\"threads\":2147483647,\"queues\":0}',
 'Proxy', 310, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('8', 'springCloud', NULL, 'Proxy', 200, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('9', 'hystrix', NULL, 'FaultTolerance', 130, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
-INSERT INTO `plugin` VALUES ('32', 
'loggingElasticSearch','{\"host\":\"localhost\", \"port\": \"9200\"}', 
'Logging', 190, 0, '2022-06-19 22:00:00', '2022-06-19 22:00:00');
-INSERT INTO `plugin` VALUES ('33', 'loggingKafka','{\"host\":\"localhost\", 
\"port\": \"9092\"}', 'Logging', 180, 0, '2022-07-04 22:00:00', '2022-07-02 
22:00:00');
-INSERT INTO `plugin` VALUES ('34', 'loggingAliyunSls','{\"projectName\": 
\"shenyu\", \"logStoreName\": \"shenyu-logstore\", \"topic\": 
\"shenyu-topic\"}', 'Logging', 175, 0, '2022-06-30 21:00:00', '2022-06-30 
21:00:00');
-INSERT INTO `plugin` VALUES ('35', 'loggingPulsar', 
'{\"topic":\"shenyu-access-logging\", \"serviceUrl\": 
\"pulsar://localhost:6650\"}', 'Logging', 185, 0, '2022-06-30 21:00:00', 
'2022-06-30 21:00:00');
-INSERT INTO `plugin` VALUES ('36', 'loggingTencentCls','{\"endpoint\": 
\"ap-guangzhou.cls.tencentcs.com\", \"topic\": \"shenyu-topic\"}', 'Logging', 
176, 0, '2022-06-30 21:00:00', '2022-06-30 21:00:00');
-INSERT INTO `plugin` VALUES ('38', 'loggingClickHouse', 
'{\"host\":\"127.0.0.1\",\"port\":\"8123\",\"databse\":\"shenyu-gateway\",\"username\":\"foo\",\"password\":\"bar\"}',
 'Logging', 195, 0, '2022-06-30 21:00:00', '2022-06-30 21:00:00');
-INSERT INTO `plugin` VALUES ('39', 'casdoor', 
'{\"endpoint\":\"http://localhost:8000\"}', 'Authentication', 40, 0, 
'2022-09-11 12:00:00', '2022-09-11 12:00:00');
-INSERT INTO `plugin` VALUES ('40', 'keyAuth', NULL, 'Authentication', 150, 0, 
'2022-07-24 19:00:00', '2022-07-24 19:00:00');
-INSERT INTO `plugin` VALUES ('41', 'brpc', '{\"address\":\"127.0.0.1\", 
\"port\":\"8005\", \"corethreads\":0, \"threads\":2147483647, \"queues\":0, 
\"threadpool\":\"shared\"}', 'Proxy', 310, 0, '2023-01-10 10:08:01', 
'2023-01-10 10:08:01');
+INSERT INTO `plugin` VALUES ('1', 'sign', NULL, 'Authentication', 20, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('31', 'mock', null, 'Mock', 1, 0, '2022-06-16 
14:40:35', '2022-06-16 14:40:55',null);
+INSERT INTO `plugin` VALUES ('10', 'sentinel', NULL, 'FaultTolerance', 140, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('11', 'sofa', 
'{\"protocol\":\"zookeeper\",\"register\":\"127.0.0.1:2181\",\"threadpool\":\"shared\"}',
 'Proxy', 310, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('12', 'resilience4j', NULL, 'FaultTolerance', 
310, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('13', 'tars', 
'{\"multiSelectorHandle\":\"1\",\"multiRuleHandle\":\"0\",\"threadpool\":\"shared\"}',
 'Proxy', 310, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('14', 'contextPath', NULL, 'HttpProcess', 80, 1, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('15', 'grpc', 
'{\"multiSelectorHandle\":\"1\",\"multiRuleHandle\":\"0\",\"threadpool\":\"shared\"}',
 'Proxy', 310, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('16', 'redirect', NULL, 'HttpProcess', 110, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('17', 'motan', 
'{\"register\":\"127.0.0.1:2181\",\"corethreads\":0,\"threads\":2147483647,\"queues\":0,\"threadpool\":\"shared\"}',
 'Proxy', 310, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('18', 'loggingConsole', NULL, 'Logging', 160, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('19', 'jwt', '{\"secretKey\":\"key\"}', 
'Authentication', 30, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('2', 'waf', '{\"model\":\"black\"}', 
'Authentication', 50, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('20', 'request', NULL, 'HttpProcess', 120, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('21', 'oauth2', NULL, 'Authentication', 40, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('22', 'paramMapping', 
'{\"ruleHandlePageType\":\"custom\"}', 'HttpProcess', 70, 0, '2022-05-25 
18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('23', 'modifyResponse', 
'{\"ruleHandlePageType\":\"custom\"}', 'HttpProcess', 220, 0, '2022-05-25 
18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('24', 'cryptorRequest', NULL, 'Cryptor', 100, 1, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('25', 'cryptorResponse', NULL, 'Cryptor', 410, 1, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('26', 'websocket', 
'{\"multiSelectorHandle\":\"1\"}', 'Proxy', 200, 1, '2022-05-25 18:02:53', 
'2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('27', 'generalContext', NULL, 'Common', 125, 1, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('28', 'mqtt', '{\"port\": 
9500,\"bossGroupThreadCount\": 1,\"maxPayloadSize\": 
65536,\"workerGroupThreadCount\": 12,\"userName\": \"shenyu\",\"password\": 
\"shenyu\",\"isEncryptPassword\": false,\"encryptMode\": 
\"\",\"leakDetectorLevel\": \"DISABLED\"}', 'Proxy', 125, 0, '2022-05-25 
18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('29', 'loggingRocketMQ', 
'{\"topic\":\"shenyu-access-logging\", \"namesrvAddr\": 
\"localhost:9876\",\"producerGroup\":\"shenyu-plugin-logging-rocketmq\"}', 
'Logging', 170, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('3', 'rewrite', NULL, 'HttpProcess', 90, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('30', 'cache', '{\"cacheType\":\"memory\"}', 
'Cache', 10, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('4', 'rateLimiter', 
'{\"master\":\"mymaster\",\"mode\":\"standalone\",\"url\":\"192.168.1.1:6379\",\"password\":\"abc\"}',
 'FaultTolerance', 60, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('5', 'divide', 
'{\"multiSelectorHandle\":\"1\",\"multiRuleHandle\":\"0\"}', 'Proxy', 200, 1, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('6', 'dubbo', 
'{\"register\":\"zookeeper://localhost:2181\",\"multiSelectorHandle\":\"1\",\"threadpool\":\"shared\",\"corethreads\":0,\"threads\":2147483647,\"queues\":0}',
 'Proxy', 310, 0, '2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('8', 'springCloud', NULL, 'Proxy', 200, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('9', 'hystrix', NULL, 'FaultTolerance', 130, 0, 
'2022-05-25 18:02:53', '2022-05-25 18:02:53',null);
+INSERT INTO `plugin` VALUES ('32', 
'loggingElasticSearch','{\"host\":\"localhost\", \"port\": \"9200\"}', 
'Logging', 190, 0, '2022-06-19 22:00:00', '2022-06-19 22:00:00',null);
+INSERT INTO `plugin` VALUES ('33', 'loggingKafka','{\"host\":\"localhost\", 
\"port\": \"9092\"}', 'Logging', 180, 0, '2022-07-04 22:00:00', '2022-07-02 
22:00:00',null);
+INSERT INTO `plugin` VALUES ('34', 'loggingAliyunSls','{\"projectName\": 
\"shenyu\", \"logStoreName\": \"shenyu-logstore\", \"topic\": 
\"shenyu-topic\"}', 'Logging', 175, 0, '2022-06-30 21:00:00', '2022-06-30 
21:00:00',null);
+INSERT INTO `plugin` VALUES ('35', 'loggingPulsar', 
'{\"topic":\"shenyu-access-logging\", \"serviceUrl\": 
\"pulsar://localhost:6650\"}', 'Logging', 185, 0, '2022-06-30 21:00:00', 
'2022-06-30 21:00:00',null);
+INSERT INTO `plugin` VALUES ('36', 'loggingTencentCls','{\"endpoint\": 
\"ap-guangzhou.cls.tencentcs.com\", \"topic\": \"shenyu-topic\"}', 'Logging', 
176, 0, '2022-06-30 21:00:00', '2022-06-30 21:00:00',null);
+INSERT INTO `plugin` VALUES ('38', 'loggingClickHouse', 
'{\"host\":\"127.0.0.1\",\"port\":\"8123\",\"databse\":\"shenyu-gateway\",\"username\":\"foo\",\"password\":\"bar\"}',
 'Logging', 195, 0, '2022-06-30 21:00:00', '2022-06-30 21:00:00',null);
+INSERT INTO `plugin` VALUES ('39', 'casdoor', 
'{\"endpoint\":\"http://localhost:8000\"}', 'Authentication', 40, 0, 
'2022-09-11 12:00:00', '2022-09-11 12:00:00',null);
+INSERT INTO `plugin` VALUES ('40', 'keyAuth', NULL, 'Authentication', 150, 0, 
'2022-07-24 19:00:00', '2022-07-24 19:00:00',null);
+INSERT INTO `plugin` VALUES ('41', 'brpc', '{\"address\":\"127.0.0.1\", 
\"port\":\"8005\", \"corethreads\":0, \"threads\":2147483647, \"queues\":0, 
\"threadpool\":\"shared\"}', 'Proxy', 310, 0, '2023-01-10 10:08:01', 
'2023-01-10 10:08:01',null);
 
 -- ----------------------------
 -- Table structure for plugin_handle
diff --git a/db/init/oracle/schema.sql b/db/init/oracle/schema.sql
index a5ae95674..12e724e05 100644
--- a/db/init/oracle/schema.sql
+++ b/db/init/oracle/schema.sql
@@ -52,6 +52,7 @@ create table plugin
     enabled      NUMBER(3) default '0' not null,
     date_created timestamp(3) default SYSDATE not null,
     date_updated timestamp(3) default SYSDATE not null,
+    plugin_jar   BLOB
     PRIMARY KEY (id)
 );
 -- Add comments to the columns
@@ -71,6 +72,9 @@ comment on column PLUGIN.date_created
   is 'create time';
 comment on column PLUGIN.date_updated
   is 'update time';
+comment on column PLUGIN.plugin_jar
+  is 'plugin jar';
+
 
 create table plugin_handle
 (
@@ -1085,45 +1089,45 @@ VALUES ('1545812228228259843', 'loadBalance', 
'LOAD_BALANCE', 'leastActive', 'le
 
 
 /*plugin*/
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('1','sign','Authentication',  20, '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort,config,enabled) VALUES ('2','waf', 'Authentication', 
50,'{"model":"black"}','0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('3','rewrite', 'HttpProcess', 90,'0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config,enabled) VALUES ('4','rateLimiter','FaultTolerance', 
60,'{"master":"mymaster","mode":"standalone","url":"192.168.1.1:6379","password":"abc"}',
 '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config,enabled) VALUES ('5','divide', 'Proxy', 
200,'{"multiSelectorHandle":"1","multiRuleHandle":"0"}','1');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config,enabled) VALUES ('6','dubbo','Proxy', 
310,'{"register":"zookeeper://localhost:2181","multiSelectorHandle":"1","threadpool":"shared","corethreads":0,"threads":2147483647,"queues":0}',
 '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('8','springCloud','Proxy', 200, '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('9','hystrix', 'FaultTolerance', 130,'0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('10','sentinel', 'FaultTolerance', 140,'0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('11','sofa', 'Proxy', 310, 
'{"protocol":"zookeeper","register":"127.0.0.1:2181","threadpool":"shared"}', 
'0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('12','resilience4j', 'FaultTolerance', 310,'0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('13', 'tars', 'Proxy', 
310,'{"multiSelectorHandle":"1","multiRuleHandle":"0","threadpool":"shared"}','0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('14', 'contextPath', 'HttpProcess', 80,'1');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('15', 'grpc', 'Proxy', 
310,'{"multiSelectorHandle":"1","multiRuleHandle":"0","threadpool":"shared"}','0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('16', 'redirect', 'HttpProcess', 110,'0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('17', 'motan', 'Proxy', 
310,'{"register":"127.0.0.1:2181","corethreads":0,"threads":2147483647,"queues":0,"threadpool":"shared"}','0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('18', 'loggingConsole', 'Logging', 160, '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('19', 'jwt', 'Authentication', 30, 
'{"secretKey":"key"}', '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('20', 'request', 'HttpProcess', 120, '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('21', 'oauth2', 'Authentication', 40, '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('22', 'paramMapping','HttpProcess', 
70,'{"ruleHandlePageType":"custom"}', '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('23', 'modifyResponse', 'HttpProcess', 
220, '{"ruleHandlePageType":"custom"}', '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('24', 'cryptorRequest', 'Cryptor', 100, '1');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('25', 'cryptorResponse', 'Cryptor', 410, '1');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('26', 'websocket', 'Proxy', 200, 
'{"multiSelectorHandle":"1"}', '1');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('27', 'generalContext', 'Common', 125, '1');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('28', 'mqtt', 'Proxy', 125, '{"port": 
9500,"bossGroupThreadCount": 1,"maxPayloadSize": 
65536,"workerGroupThreadCount": 12,"userName": "shenyu","password": 
"shenyu","isEncryptPassword": false,"encryptMode": "","leakDetectorLevel": 
"DISABLED"}', '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('29', 'loggingRocketMQ', 'Logging', 
170,'{"topic":"shenyu-access-logging", "namesrvAddr": 
"localhost:9876","producerGroup":"shenyu-plugin-logging-rocketmq"}', '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('30', 'cache', '{"cacheType":"memory"}', 
'Cache', 10, 0);
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('31', 'mock', 'Mock', 1, 0);
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('32', 'loggingElasticSearch', 
'{"host":"localhost", "port": "9200"}', 'Logging', 190, 0);
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('33', 'loggingKafka', 
'{"topic":"shenyu-access-logging", "namesrvAddr": "localhost:9092"}', 
'Logging', 180, 0);
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('34', 'loggingAliyunSls', '{"projectName": 
"shenyu", "logStoreName": "shenyu-logstore", "topic": "shenyu-topic"}', 
'Logging', 175, '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('35', 'loggingPulsar', 
'{"topic":"shenyu-access-logging", "serviceUrl": "pulsar://localhost:6650"}', 
'Logging', 185, '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('36', 'loggingTencentCls', '{"endpoint": 
"ap-guangzhou.cls.tencentcs.com", "topic": "shenyu-topic"}', 'Logging', 176, 
'0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('38', 'loggingClickHouse', 
'{"host":"127.0.0.1","port":"8123","databse":"shenyu-gateway","username":"foo","password":"bar"}',
 'Logging', 195, '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('39', 'casdoor', 
'{"endpoint":"http://localhost:8000"}' ,'Authentication', 40, '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('40', 'keyAuth', 'Authentication', 150, '0');
-INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES VALUES ('41', 'brpc', 'Proxy', 
310,'{"address":"127.0.0.1","port":"8005","corethreads":0,"threads":2147483647,"queues":0,"threadpool":"shared"}','0');
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('1','sign','Authentication',  20, '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort,config,enabled) VALUES ('2','waf', 'Authentication', 
50,'{"model":"black"}','0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('3','rewrite', 'HttpProcess', 90,'0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config,enabled) VALUES ('4','rateLimiter','FaultTolerance', 
60,'{"master":"mymaster","mode":"standalone","url":"192.168.1.1:6379","password":"abc"}',
 '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config,enabled) VALUES ('5','divide', 'Proxy', 
200,'{"multiSelectorHandle":"1","multiRuleHandle":"0"}','1', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config,enabled) VALUES ('6','dubbo','Proxy', 
310,'{"register":"zookeeper://localhost:2181","multiSelectorHandle":"1","threadpool":"shared","corethreads":0,"threads":2147483647,"queues":0}',
 '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('8','springCloud','Proxy', 200, '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('9','hystrix', 'FaultTolerance', 130,'0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('10','sentinel', 'FaultTolerance', 140,'0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('11','sofa', 'Proxy', 310, 
'{"protocol":"zookeeper","register":"127.0.0.1:2181","threadpool":"shared"}', 
'0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('12','resilience4j', 'FaultTolerance', 310,'0', 
null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('13', 'tars', 'Proxy', 
310,'{"multiSelectorHandle":"1","multiRuleHandle":"0","threadpool":"shared"}','0',
 null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('14', 'contextPath', 'HttpProcess', 80,'1', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('15', 'grpc', 'Proxy', 
310,'{"multiSelectorHandle":"1","multiRuleHandle":"0","threadpool":"shared"}','0',
 null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('16', 'redirect', 'HttpProcess', 110,'0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('17', 'motan', 'Proxy', 
310,'{"register":"127.0.0.1:2181","corethreads":0,"threads":2147483647,"queues":0,"threadpool":"shared"}','0',
 null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('18', 'loggingConsole', 'Logging', 160, '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('19', 'jwt', 'Authentication', 30, 
'{"secretKey":"key"}', '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('20', 'request', 'HttpProcess', 120, '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('21', 'oauth2', 'Authentication', 40, '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('22', 'paramMapping','HttpProcess', 
70,'{"ruleHandlePageType":"custom"}', '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('23', 'modifyResponse', 'HttpProcess', 
220, '{"ruleHandlePageType":"custom"}', '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('24', 'cryptorRequest', 'Cryptor', 100, '1', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('25', 'cryptorResponse', 'Cryptor', 410, '1', 
null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('26', 'websocket', 'Proxy', 200, 
'{"multiSelectorHandle":"1"}', '1', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('27', 'generalContext', 'Common', 125, '1', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('28', 'mqtt', 'Proxy', 125, '{"port": 
9500,"bossGroupThreadCount": 1,"maxPayloadSize": 
65536,"workerGroupThreadCount": 12,"userName": "shenyu","password": 
"shenyu","isEncryptPassword": false,"encryptMode": "","leakDetectorLevel": 
"DISABLED"}', '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES ('29', 'loggingRocketMQ', 'Logging', 
170,'{"topic":"shenyu-access-logging", "namesrvAddr": 
"localhost:9876","producerGroup":"shenyu-plugin-logging-rocketmq"}', '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('30', 'cache', '{"cacheType":"memory"}', 
'Cache', 10, 0, null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('31', 'mock', 'Mock', 1, 0, null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('32', 'loggingElasticSearch', 
'{"host":"localhost", "port": "9200"}', 'Logging', 190, 0, null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('33', 'loggingKafka', 
'{"topic":"shenyu-access-logging", "namesrvAddr": "localhost:9092"}', 
'Logging', 180, 0, null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('34', 'loggingAliyunSls', '{"projectName": 
"shenyu", "logStoreName": "shenyu-logstore", "topic": "shenyu-topic"}', 
'Logging', 175, '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('35', 'loggingPulsar', 
'{"topic":"shenyu-access-logging", "serviceUrl": "pulsar://localhost:6650"}', 
'Logging', 185, '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('36', 'loggingTencentCls', '{"endpoint": 
"ap-guangzhou.cls.tencentcs.com", "topic": "shenyu-topic"}', 'Logging', 176, 
'0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('38', 'loggingClickHouse', 
'{"host":"127.0.0.1","port":"8123","databse":"shenyu-gateway","username":"foo","password":"bar"}',
 'Logging', 195, '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled) VALUES ('39', 'casdoor', 
'{"endpoint":"http://localhost:8000"}' ,'Authentication', 40, '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, enabled) VALUES ('40', 'keyAuth', 'Authentication', 150, '0', null);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
role, sort, config, enabled) VALUES VALUES ('41', 'brpc', 'Proxy', 
310,'{"address":"127.0.0.1","port":"8005","corethreads":0,"threads":2147483647,"queues":0,"threadpool":"shared"}','0',
 null);
 
 
 
diff --git a/db/init/pg/create-table.sql b/db/init/pg/create-table.sql
index 151e24456..f391b1024 100644
--- a/db/init/pg/create-table.sql
+++ b/db/init/pg/create-table.sql
@@ -899,7 +899,8 @@ CREATE TABLE "public"."plugin" (
   "sort" int4,
   "enabled" int2 NOT NULL,
   "date_created" timestamp(6) NOT NULL DEFAULT timezone('UTC-8'::text, 
(now())::timestamp(0) without time zone),
-  "date_updated" timestamp(6) NOT NULL DEFAULT timezone('UTC-8'::text, 
(now())::timestamp(0) without time zone)
+  "date_updated" timestamp(6) NOT NULL DEFAULT timezone('UTC-8'::text, 
(now())::timestamp(0) without time zone),
+  "plugin_jar" bytea
 );
 COMMENT ON COLUMN "public"."plugin"."id" IS 'primary key id';
 COMMENT ON COLUMN "public"."plugin"."name" IS 'plugin name';
@@ -909,49 +910,50 @@ COMMENT ON COLUMN "public"."plugin"."sort" IS 'sort';
 COMMENT ON COLUMN "public"."plugin"."enabled" IS 'whether to open (0, not 
open, 1 open)';
 COMMENT ON COLUMN "public"."plugin"."date_created" IS 'create time';
 COMMENT ON COLUMN "public"."plugin"."date_updated" IS 'update time';
+COMMENT ON COLUMN "public"."plugin"."plugin_jar" IS 'plugin jar';
 
 -- ----------------------------
 -- Records of plugin
 -- ----------------------------
-INSERT INTO "public"."plugin" VALUES ('1', 'sign', NULL, 'Authentication', 20, 
0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('10', 'sentinel', NULL, 
'FaultTolerance', 140, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('11', 'sofa', 
'{"protocol":"zookeeper","register":"127.0.0.1:2181","threadpool":"shared"}', 
'Proxy', 310, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('12', 'resilience4j', NULL, 
'FaultTolerance', 310, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('13', 'tars', 
'{"multiSelectorHandle":"1","multiRuleHandle":"0","threadpool":"shared"}', 
'Proxy', 310, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('14', 'contextPath', NULL, 
'HttpProcess', 80, 1, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('15', 'grpc', 
'{"multiSelectorHandle":"1","multiRuleHandle":"0","threadpool":"shared"}', 
'Proxy', 310, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('16', 'redirect', NULL, 'HttpProcess', 
110, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('17', 'motan', 
'{"register":"127.0.0.1:2181","corethreads":0,"threads":2147483647,"queues":0,"threadpool":"shared"}',
 'Proxy', 310, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('18', 'loggingConsole', NULL, 'Logging', 
160, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('19', 'jwt', '{"secretKey":"key"}', 
'Authentication', 30, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('2', 'waf', '{"model":"black"}', 
'Authentication', 50, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('20', 'request', NULL, 'HttpProcess', 
120, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('21', 'oauth2', NULL, 'Authentication', 
40, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('22', 'paramMapping', 
'{"ruleHandlePageType":"custom"}', 'HttpProcess', 70, 0, '2022-05-25 18:08:01', 
'2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('23', 'modifyResponse', 
'{"ruleHandlePageType":"custom"}', 'HttpProcess', 220, 0, '2022-05-25 
18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('24', 'cryptorRequest', NULL, 'Cryptor', 
100, 1, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('25', 'cryptorResponse', NULL, 
'Cryptor', 410, 1, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('26', 'websocket', 
'{"multiSelectorHandle":"1"}', 'Proxy', 200, 1, '2022-05-25 18:08:01', 
'2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('3', 'rewrite', NULL, 'HttpProcess', 90, 
0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('4', 'rateLimiter', 
'{"master":"mymaster","mode":"standalone","url":"192.168.1.1:6379","password":"abc"}',
 'FaultTolerance', 60, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('5', 'divide', 
'{"multiSelectorHandle":"1","multiRuleHandle":"0"}', 'Proxy', 200, 1, 
'2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('6', 'dubbo', 
'{"register":"zookeeper://localhost:2181","multiSelectorHandle":"1","threadpool":"shared","corethreads":0,"threads":2147483647,"queues":0}',
 'Proxy', 310, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('8', 'springCloud', NULL, 'Proxy', 200, 
0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('9', 'hystrix', NULL, 'FaultTolerance', 
130, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('27', 'generalContext', NULL, 'Common', 
125, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('28', 'mqtt', '{"port": 
9500,"bossGroupThreadCount": 1,"maxPayloadSize": 
65536,"workerGroupThreadCount": 12,"userName": "shenyu","password": 
"shenyu","isEncryptPassword": false,"encryptMode": "","leakDetectorLevel": 
"DISABLED"}', 'Proxy', 125, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('29', 'loggingRocketMQ', 
'{"topic":"shenyu-access-logging", "namesrvAddr": 
"localhost:9876","producerGroup":"shenyu-plugin-logging-rocketmq"}', 'Logging', 
170, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('30', 'cache', '{"cacheType":"memory"}', 
'Cache', 10, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('31', 'mock', null, 'Mock', 1, 0, 
'2022-06-16 14:40:35', '2022-06-16 14:40:55');
-INSERT INTO "public"."plugin" VALUES ('32', 'loggingElasticSearch', 
'{"host":"localhost", "port": "9200"}', 'Logging', 190, 0, '2022-06-19 
22:00:00', '2022-06-19 22:00:00');
-INSERT INTO "public"."plugin" VALUES ('33', 'loggingKafka', 
'{"topic":"shenyu-access-logging", "namesrvAddr": "localhost:9092"}', 
'Logging', 180, 0, '2022-07-04 22:00:00', '2022-07-04 22:00:00');
-INSERT INTO "public"."plugin" VALUES ('34', 'loggingAliyunSls', 
'{"projectName": "shenyu", "logStoreName": "shenyu-logstore", "topic": 
"shenyu-topic"}', 'Logging', 175, 0, '2022-06-30 21:00:00', '2022-06-30 
21:00:00');
-INSERT INTO "public"."plugin" VALUES ('35', 'loggingPulsar', 
'{"topic":"shenyu-access-logging", "serviceUrl": "pulsar://localhost:6650"}', 
'Logging', 185, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01');
-INSERT INTO "public"."plugin" VALUES ('36', 'loggingTencentCls', '{"endpoint": 
"ap-guangzhou.cls.tencentcs.com", "topic": "shenyu-topic"}', 'Logging', 176, 0, 
'2022-06-30 21:00:00', '2022-06-30 21:00:00');
-INSERT INTO "public"."plugin" VALUES ('38', 'loggingClickHouse', 
'{"host":"127.0.0.1","port":"8123","databse":"shenyu-gateway","username":"foo","password":"bar"}',
 'Logging', 195, 0, '2022-06-30 21:00:00', '2022-06-30 21:00:00');
-INSERT INTO "public"."plugin" VALUES ('39', 'casdoor', 
'{"endpoint":"http://localhost:8000"}', 'Authentication', 40, 0, '2022-09-11 
12:00:00', '2022-09-11 12:00:00');
-INSERT INTO "public"."plugin" VALUES ('40', 'keyAuth', NULL, 'Authentication', 
150, 0, '2022-07-24 19:00:00', '2022-07-24 19:00:00');
-INSERT INTO "public"."plugin" VALUES ('41', 'brpc', 
'{"address":"127.0.0.1","port":"8005","corethreads":0,"threads":2147483647,"queues":0,"threadpool":"shared"}',
 'Proxy', 310, 0, '2023-01-10 10:08:01', '2023-01-10 10:08:01');
+INSERT INTO "public"."plugin" VALUES ('1', 'sign', NULL, 'Authentication', 20, 
0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('10', 'sentinel', NULL, 
'FaultTolerance', 140, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('11', 'sofa', 
'{"protocol":"zookeeper","register":"127.0.0.1:2181","threadpool":"shared"}', 
'Proxy', 310, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('12', 'resilience4j', NULL, 
'FaultTolerance', 310, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('13', 'tars', 
'{"multiSelectorHandle":"1","multiRuleHandle":"0","threadpool":"shared"}', 
'Proxy', 310, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('14', 'contextPath', NULL, 
'HttpProcess', 80, 1, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('15', 'grpc', 
'{"multiSelectorHandle":"1","multiRuleHandle":"0","threadpool":"shared"}', 
'Proxy', 310, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('16', 'redirect', NULL, 'HttpProcess', 
110, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('17', 'motan', 
'{"register":"127.0.0.1:2181","corethreads":0,"threads":2147483647,"queues":0,"threadpool":"shared"}',
 'Proxy', 310, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('18', 'loggingConsole', NULL, 'Logging', 
160, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('19', 'jwt', '{"secretKey":"key"}', 
'Authentication', 30, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('2', 'waf', '{"model":"black"}', 
'Authentication', 50, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('20', 'request', NULL, 'HttpProcess', 
120, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('21', 'oauth2', NULL, 'Authentication', 
40, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('22', 'paramMapping', 
'{"ruleHandlePageType":"custom"}', 'HttpProcess', 70, 0, '2022-05-25 18:08:01', 
'2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('23', 'modifyResponse', 
'{"ruleHandlePageType":"custom"}', 'HttpProcess', 220, 0, '2022-05-25 
18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('24', 'cryptorRequest', NULL, 'Cryptor', 
100, 1, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('25', 'cryptorResponse', NULL, 
'Cryptor', 410, 1, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('26', 'websocket', 
'{"multiSelectorHandle":"1"}', 'Proxy', 200, 1, '2022-05-25 18:08:01', 
'2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('3', 'rewrite', NULL, 'HttpProcess', 90, 
0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('4', 'rateLimiter', 
'{"master":"mymaster","mode":"standalone","url":"192.168.1.1:6379","password":"abc"}',
 'FaultTolerance', 60, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('5', 'divide', 
'{"multiSelectorHandle":"1","multiRuleHandle":"0"}', 'Proxy', 200, 1, 
'2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('6', 'dubbo', 
'{"register":"zookeeper://localhost:2181","multiSelectorHandle":"1","threadpool":"shared","corethreads":0,"threads":2147483647,"queues":0}',
 'Proxy', 310, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('8', 'springCloud', NULL, 'Proxy', 200, 
0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('9', 'hystrix', NULL, 'FaultTolerance', 
130, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('27', 'generalContext', NULL, 'Common', 
125, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('28', 'mqtt', '{"port": 
9500,"bossGroupThreadCount": 1,"maxPayloadSize": 
65536,"workerGroupThreadCount": 12,"userName": "shenyu","password": 
"shenyu","isEncryptPassword": false,"encryptMode": "","leakDetectorLevel": 
"DISABLED"}', 'Proxy', 125, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', 
null);
+INSERT INTO "public"."plugin" VALUES ('29', 'loggingRocketMQ', 
'{"topic":"shenyu-access-logging", "namesrvAddr": 
"localhost:9876","producerGroup":"shenyu-plugin-logging-rocketmq"}', 'Logging', 
170, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('30', 'cache', '{"cacheType":"memory"}', 
'Cache', 10, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('31', 'mock', null, 'Mock', 1, 0, 
'2022-06-16 14:40:35', '2022-06-16 14:40:55', null);
+INSERT INTO "public"."plugin" VALUES ('32', 'loggingElasticSearch', 
'{"host":"localhost", "port": "9200"}', 'Logging', 190, 0, '2022-06-19 
22:00:00', '2022-06-19 22:00:00', null);
+INSERT INTO "public"."plugin" VALUES ('33', 'loggingKafka', 
'{"topic":"shenyu-access-logging", "namesrvAddr": "localhost:9092"}', 
'Logging', 180, 0, '2022-07-04 22:00:00', '2022-07-04 22:00:00', null);
+INSERT INTO "public"."plugin" VALUES ('34', 'loggingAliyunSls', 
'{"projectName": "shenyu", "logStoreName": "shenyu-logstore", "topic": 
"shenyu-topic"}', 'Logging', 175, 0, '2022-06-30 21:00:00', '2022-06-30 
21:00:00', null);
+INSERT INTO "public"."plugin" VALUES ('35', 'loggingPulsar', 
'{"topic":"shenyu-access-logging", "serviceUrl": "pulsar://localhost:6650"}', 
'Logging', 185, 0, '2022-05-25 18:08:01', '2022-05-25 18:08:01', null);
+INSERT INTO "public"."plugin" VALUES ('36', 'loggingTencentCls', '{"endpoint": 
"ap-guangzhou.cls.tencentcs.com", "topic": "shenyu-topic"}', 'Logging', 176, 0, 
'2022-06-30 21:00:00', '2022-06-30 21:00:00', null);
+INSERT INTO "public"."plugin" VALUES ('38', 'loggingClickHouse', 
'{"host":"127.0.0.1","port":"8123","databse":"shenyu-gateway","username":"foo","password":"bar"}',
 'Logging', 195, 0, '2022-06-30 21:00:00', '2022-06-30 21:00:00', null);
+INSERT INTO "public"."plugin" VALUES ('39', 'casdoor', 
'{"endpoint":"http://localhost:8000"}', 'Authentication', 40, 0, '2022-09-11 
12:00:00', '2022-09-11 12:00:00', null);
+INSERT INTO "public"."plugin" VALUES ('40', 'keyAuth', NULL, 'Authentication', 
150, 0, '2022-07-24 19:00:00', '2022-07-24 19:00:00', null);
+INSERT INTO "public"."plugin" VALUES ('41', 'brpc', 
'{"address":"127.0.0.1","port":"8005","corethreads":0,"threads":2147483647,"queues":0,"threadpool":"shared"}',
 'Proxy', 310, 0, '2023-01-10 10:08:01', '2023-01-10 10:08:01', null);
 
 -- ----------------------------
 -- Table structure for plugin_handle
diff --git a/db/upgrade/2.5.1-upgrade-2.6.0-mysql.sql 
b/db/upgrade/2.5.1-upgrade-2.6.0-mysql.sql
index c4af93a85..3fb707da1 100644
--- a/db/upgrade/2.5.1-upgrade-2.6.0-mysql.sql
+++ b/db/upgrade/2.5.1-upgrade-2.6.0-mysql.sql
@@ -23,4 +23,7 @@ INSERT INTO `plugin_handle` VALUES ('1630768384280514560', 
'25', 'mapType', 'map
 
 /* insert plugin_handle data for plugin_handle mapType */
 INSERT INTO `shenyu_dict` VALUES ('1630761573833920512', 'mapType', 'mapType', 
'all', 'all', '', 0, 1, '2023-03-01 10:47:11', '2023-03-01 10:47:11');
-INSERT INTO `shenyu_dict` VALUES ('1630761984393367552', 'mapType', 'mapType', 
'field', 'field', '', 1, 1, '2023-03-01 10:48:49', '2023-03-01 10:48:49');
\ No newline at end of file
+INSERT INTO `shenyu_dict` VALUES ('1630761984393367552', 'mapType', 'mapType', 
'field', 'field', '', 1, 1, '2023-03-01 10:48:49', '2023-03-01 10:48:49');
+
+/* add column into plugin table */
+ALTER TABLE `plugin` ADD COLUMN `plugin_jar` mediumblob NULL COMMENT 'plugin 
jar';
\ No newline at end of file
diff --git a/db/upgrade/2.5.1-upgrade-2.6.0-oracle.sql 
b/db/upgrade/2.5.1-upgrade-2.6.0-oracle.sql
index 8893d5ae8..b46713f5c 100644
--- a/db/upgrade/2.5.1-upgrade-2.6.0-oracle.sql
+++ b/db/upgrade/2.5.1-upgrade-2.6.0-oracle.sql
@@ -27,4 +27,8 @@ values ('1630768384280514560', '25', 'mapType', 'mapType', 3, 
2, 4, '{\"required
 insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name)) 
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT, 
ENABLED)
 values ('1630761573833920512', 'mapType', 'mapType', 'all', 'all', '', 0, 1);
 insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name)) 
*/ into SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT, 
ENABLED)
-values ('1630761984393367552', 'mapType', 'mapType', 'field', 'field', '', 1, 
1);
\ No newline at end of file
+values ('1630761984393367552', 'mapType', 'mapType', 'field', 'field', '', 1, 
1);
+
+/* add column into plugin table */
+ALTER TABLE plugin ADD plugin_jar BLOB NULL;
+COMMENT ON COLUMN plugin.plugin_jar IS 'plugin jar';
diff --git a/db/upgrade/2.5.1-upgrade-2.6.0-pg.sql 
b/db/upgrade/2.5.1-upgrade-2.6.0-pg.sql
index 70010a7ad..f95c12074 100644
--- a/db/upgrade/2.5.1-upgrade-2.6.0-pg.sql
+++ b/db/upgrade/2.5.1-upgrade-2.6.0-pg.sql
@@ -23,4 +23,8 @@ INSERT INTO "public"."plugin_handle" VALUES 
('1630768384280514560', '25', 'mapTy
 
 /* insert plugin_handle data for plugin_handle mapType */
 INSERT INTO "public"."shenyu_dict" VALUES ('1630761573833920512', 'mapType', 
'mapType', 'all', 'all', '', 0, 1, '2023-03-01 10:47:11', '2023-03-01 
10:47:11');
-INSERT INTO "public"."shenyu_dict" VALUES ('1630761984393367552', 'mapType', 
'mapType', 'field', 'field', '', 1, 1, '2023-03-01 10:48:49', '2023-03-01 
10:48:49');
\ No newline at end of file
+INSERT INTO "public"."shenyu_dict" VALUES ('1630761984393367552', 'mapType', 
'mapType', 'field', 'field', '', 1, 1, '2023-03-01 10:48:49', '2023-03-01 
10:48:49');
+
+/* add column into plugin table */
+ALTER TABLE "public"."plugin" ADD COLUMN plugin_jar bytea NULL;
+COMMENT ON COLUMN "public"."plugin".plugin_jar IS 'plugin jar';
diff --git a/pom.xml b/pom.xml
index 61505c0f9..0ad858524 100644
--- a/pom.xml
+++ b/pom.xml
@@ -166,6 +166,7 @@
         <log4j-1.2-api.vetsion>2.17.2</log4j-1.2-api.vetsion>
         <caffeine.version>2.9.3</caffeine.version>
         <httpasyncclient.version>4.1.5</httpasyncclient.version>
+        <asm.version>9.2</asm.version>
     </properties>
 
     <dependencyManagement>
@@ -179,6 +180,12 @@
                 <scope>import</scope>
             </dependency>
 
+            <dependency>
+                <groupId>org.ow2.asm</groupId>
+                <artifactId>asm-tree</artifactId>
+                <version>${asm.version}</version>
+            </dependency>
+
             <dependency>
                 <groupId>com.alibaba.cloud</groupId>
                 <artifactId>spring-cloud-alibaba-dependencies</artifactId>
diff --git a/shenyu-admin/src/http/http-debug-plugin-controller-api.http 
b/shenyu-admin/src/http/http-debug-plugin-controller-api.http
index 27b9e6d1c..aa4f774f1 100644
--- a/shenyu-admin/src/http/http-debug-plugin-controller-api.http
+++ b/shenyu-admin/src/http/http-debug-plugin-controller-api.http
@@ -68,29 +68,18 @@ X-Access-Token: 
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6ImFkbWluIiw
 ### create
 POST http://localhost:9095/plugin
 Accept: application/json
-Content-Type: application/json
+Content-Type: application/x-www-form-urlencoded
 X-Access-Token: 
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6ImFkbWluIiwiZXhwIjoxNjQ3MjUzNzg2fQ.37fddsUZRFVNc2pTlACHEI9oZSj9gnE5hhpK5Yaf-6s
 
-{
-
-  "name": "test-create-plugin",
-  "role": "test-create-plugin",
-  "enabled": true,
-  "sort": 100
-}
+name=test-create-plugin&role=test-create-plugin&enabled=true&sort=100
 
 ### update
 PUT http://localhost:9095/plugin/1503021118890123264
 Accept: application/json
-Content-Type: application/json
+Content-Type: application/x-www-form-urlencoded
 X-Access-Token: 
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6ImFkbWluIiwiZXhwIjoxNjQ3MjUzNzg2fQ.37fddsUZRFVNc2pTlACHEI9oZSj9gnE5hhpK5Yaf-6s
 
-{
-  "name": "test-create-plugin",
-  "role": "test-create-plugin",
-  "enabled": true,
-  "sort": 100
-}
+name=test-create-plugin&role=test-create-plugin&enabled=true&sort=100
 
 ### delete
 DELETE http://localhost:9095/plugin/batch
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/PluginController.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/PluginController.java
index a14ad33d7..f768ba4b3 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/PluginController.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/PluginController.java
@@ -36,14 +36,15 @@ import org.apache.shenyu.common.dto.PluginData;
 import org.apache.shenyu.common.enums.DataEventTypeEnum;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
 import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
 
 import javax.validation.Valid;
 import javax.validation.constraints.NotBlank;
@@ -110,7 +111,7 @@ public class PluginController implements 
PagedController<PluginQueryCondition, P
         PluginVO pluginVO = pluginService.findById(id);
         return ShenyuAdminResult.success(ShenyuResultMessage.DETAIL_SUCCESS, 
pluginVO);
     }
-    
+
     /**
      * create plugin.
      *
@@ -119,9 +120,10 @@ public class PluginController implements 
PagedController<PluginQueryCondition, P
      */
     @PostMapping("")
     @RequiresPermissions("system:plugin:add")
-    public ShenyuAdminResult createPlugin(@Valid @RequestBody final PluginDTO 
pluginDTO) {
+    public ShenyuAdminResult createPlugin(@Valid @ModelAttribute final 
PluginDTO pluginDTO) {
         return 
ShenyuAdminResult.success(pluginService.createOrUpdate(pluginDTO));
     }
+
     
     /**
      * update plugin.
@@ -135,7 +137,7 @@ public class PluginController implements 
PagedController<PluginQueryCondition, P
     public ShenyuAdminResult updatePlugin(@PathVariable("id")
                                           @Existed(message = "plugin is not 
existed",
                                                   provider = 
PluginMapper.class) final String id,
-                                          @Valid @RequestBody final PluginDTO 
pluginDTO) {
+                                          @Valid @ModelAttribute final 
PluginDTO pluginDTO) {
         pluginDTO.setId(id);
         return createPlugin(pluginDTO);
     }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/PluginDTO.java 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/PluginDTO.java
index 3e3a6b89d..b1eb01c9c 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/PluginDTO.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/PluginDTO.java
@@ -20,6 +20,7 @@ package org.apache.shenyu.admin.model.dto;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.shenyu.admin.mapper.PluginMapper;
 import org.apache.shenyu.admin.validation.annotation.Existed;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
@@ -61,13 +62,36 @@ public class PluginDTO implements Serializable {
      */
     @NotNull
     private Integer sort;
-    
+
     /**
      * whether enabled.
      */
     @NotNull
     private Boolean enabled;
-    
+
+    /**
+     * plugin jar.
+     */
+    private MultipartFile file;
+
+    /**
+     * Gets the value of file.
+     *
+     * @return the value of file
+     */
+    public MultipartFile getFile() {
+        return file;
+    }
+
+    /**
+     * Sets the file.
+     *
+     * @param file file
+     */
+    public void setFile(final MultipartFile file) {
+        this.file = file;
+    }
+
     /**
      * Gets the value of id.
      *
@@ -193,11 +217,12 @@ public class PluginDTO implements Serializable {
                 && Objects.equals(config, pluginDTO.config)
                 && Objects.equals(role, pluginDTO.role)
                 && Objects.equals(sort, pluginDTO.sort)
-                && Objects.equals(enabled, pluginDTO.enabled);
+                && Objects.equals(enabled, pluginDTO.enabled)
+                && Objects.equals(file, pluginDTO.file);
     }
     
     @Override
     public int hashCode() {
-        return Objects.hash(id, name, config, role, sort, enabled);
+        return Objects.hash(id, name, config, role, sort, enabled, file);
     }
 }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/PluginDO.java 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/PluginDO.java
index 0f8e26ac2..87d519f5a 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/PluginDO.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/PluginDO.java
@@ -19,9 +19,12 @@ package org.apache.shenyu.admin.model.entity;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.shenyu.admin.model.dto.PluginDTO;
+import org.apache.shenyu.common.exception.ShenyuException;
 import org.apache.shenyu.common.utils.UUIDUtils;
 
+import java.io.IOException;
 import java.sql.Timestamp;
+import java.util.Arrays;
 import java.util.Objects;
 import java.util.Optional;
 
@@ -58,15 +61,36 @@ public final class PluginDO extends BaseDO {
      */
     private Integer sort;
 
+    private byte[] pluginJar;
+
     public PluginDO() {
     }
 
-    public PluginDO(final String name, final String config, final Boolean 
enabled, final String role, final Integer sort) {
+    public PluginDO(final String name, final String config, final Boolean 
enabled, final String role, final Integer sort, final byte[] pluginJar) {
         this.name = name;
         this.config = config;
         this.enabled = enabled;
         this.role = role;
         this.sort = sort;
+        this.pluginJar = pluginJar;
+    }
+
+    /**
+     * Gets the value of pluginJar.
+     *
+     * @return the value of pluginJar
+     */
+    public byte[] getPluginJar() {
+        return pluginJar;
+    }
+
+    /**
+     * Sets the pluginJar.
+     *
+     * @param pluginJar pluginJar
+     */
+    public void setPluginJar(final byte[] pluginJar) {
+        this.pluginJar = pluginJar;
     }
 
     /**
@@ -164,8 +188,8 @@ public final class PluginDO extends BaseDO {
      *
      * @return builder object.
      */
-    public static PluginDO.PluginDOBuilder builder() {
-        return new PluginDO.PluginDOBuilder();
+    public static PluginDOBuilder builder() {
+        return new PluginDOBuilder();
     }
 
     /**
@@ -185,12 +209,21 @@ public final class PluginDO extends BaseDO {
                     .sort(item.getSort())
                     .dateUpdated(currentTime)
                     .build();
+
             if (StringUtils.isEmpty(item.getId())) {
                 pluginDO.setId(UUIDUtils.getInstance().generateShortUuid());
                 pluginDO.setDateCreated(currentTime);
             } else {
                 pluginDO.setId(item.getId());
             }
+            if (Objects.nonNull(item.getFile())) {
+                try {
+                    pluginDO.setPluginJar(item.getFile().getBytes());
+                } catch (IOException e) {
+                    throw new ShenyuException(e);
+                }
+
+            }
             return pluginDO;
         }).orElse(null);
     }
@@ -211,7 +244,8 @@ public final class PluginDO extends BaseDO {
                 && Objects.equals(config, pluginDO.config)
                 && Objects.equals(enabled, pluginDO.enabled)
                 && Objects.equals(role, pluginDO.role)
-                && Objects.equals(sort, pluginDO.sort);
+                && Objects.equals(sort, pluginDO.sort)
+                && Arrays.equals(pluginJar, pluginDO.pluginJar);
     }
 
     @Override
@@ -237,6 +271,8 @@ public final class PluginDO extends BaseDO {
 
         private Integer sort;
 
+        private byte[] pluginJar;
+
         private PluginDOBuilder() {
         }
 
@@ -328,6 +364,19 @@ public final class PluginDO extends BaseDO {
             return this;
         }
 
+        /**
+         * pluginJar.
+         *
+         * @param pluginJar  the  pluginJar.
+         * @return PluginDOBuilder.
+         */
+        public PluginDOBuilder pluginJar(final byte[] pluginJar) {
+            this.pluginJar = pluginJar;
+            return this;
+        }
+
+
+
         /**
          * build method.
          *
@@ -343,6 +392,7 @@ public final class PluginDO extends BaseDO {
             pluginDO.setEnabled(enabled);
             pluginDO.setRole(role);
             pluginDO.setSort(sort);
+            pluginDO.setPluginJar(pluginJar);
             return pluginDO;
         }
     }
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/PluginServiceImpl.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/PluginServiceImpl.java
index bd52c2ea2..0a2c2d3eb 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/PluginServiceImpl.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/PluginServiceImpl.java
@@ -39,19 +39,30 @@ import org.apache.shenyu.admin.utils.SessionUtil;
 import org.apache.shenyu.admin.utils.ShenyuResultMessage;
 import org.apache.shenyu.common.constant.AdminConstants;
 import org.apache.shenyu.common.dto.PluginData;
+import org.apache.shenyu.common.exception.ShenyuException;
+import org.apache.shenyu.common.utils.JarDependencyUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
- * Implementation of the {@link org.apache.shenyu.admin.service.PluginService}.
+ * Implementation of the {@link PluginService}.
  */
 @Service
 public class PluginServiceImpl implements PluginService {
+
+    /**
+     * logger.
+     */
+    private static final Logger LOG = 
LoggerFactory.getLogger(PluginServiceImpl.class);
     
     private final PluginMapper pluginMapper;
     
@@ -211,6 +222,9 @@ public class PluginServiceImpl implements PluginService {
      */
     private String create(final PluginDTO pluginDTO) {
         Assert.isNull(pluginMapper.nameExisted(pluginDTO.getName()), 
AdminConstants.PLUGIN_NAME_IS_EXIST);
+        if (!Objects.isNull(pluginDTO.getFile())) {
+            Assert.isTrue(checkFile(pluginDTO.getFile()), 
AdminConstants.PLUGIN_JAR_IS_NOT_RIGHT);
+        }
         PluginDO pluginDO = PluginDO.buildPluginDO(pluginDTO);
         if (pluginMapper.insertSelective(pluginDO) > 0) {
             // publish create event. init plugin data
@@ -218,7 +232,8 @@ public class PluginServiceImpl implements PluginService {
         }
         return ShenyuResultMessage.CREATE_SUCCESS;
     }
-    
+
+
     /**
      * update plugin.<br>
      *
@@ -227,6 +242,9 @@ public class PluginServiceImpl implements PluginService {
      */
     private String update(final PluginDTO pluginDTO) {
         Assert.isNull(pluginMapper.nameExistedExclude(pluginDTO.getName(), 
Collections.singletonList(pluginDTO.getId())), 
AdminConstants.PLUGIN_NAME_IS_EXIST);
+        if (!Objects.isNull(pluginDTO.getFile())) {
+            Assert.isTrue(checkFile(pluginDTO.getFile()), 
AdminConstants.PLUGIN_JAR_IS_NOT_RIGHT);
+        }
         final PluginDO before = pluginMapper.selectById(pluginDTO.getId());
         PluginDO pluginDO = PluginDO.buildPluginDO(pluginDTO);
         if (pluginMapper.updateSelective(pluginDO) > 0) {
@@ -235,4 +253,19 @@ public class PluginServiceImpl implements PluginService {
         }
         return ShenyuResultMessage.UPDATE_SUCCESS;
     }
+
+    /**
+     * check jar.
+     * @param file file
+     * @return true is right
+     */
+    private boolean checkFile(final MultipartFile file) {
+        try {
+            Set<String> dependencyTree = 
JarDependencyUtils.getDependencyTree(file.getBytes());
+            return 
dependencyTree.contains(AdminConstants.PLUGIN_ABSTRACR_PATH) || 
dependencyTree.contains(AdminConstants.PLUGIN_INTERFACE_PATH);
+        } catch (Exception e) {
+            LOG.error("check plugin jar error:{}", e.getMessage());
+            throw new ShenyuException(e);
+        }
+    }
 }
diff --git a/shenyu-admin/src/main/resources/mappers/plugin-sqlmap.xml 
b/shenyu-admin/src/main/resources/mappers/plugin-sqlmap.xml
index ceb32dbfa..73068a4f3 100644
--- a/shenyu-admin/src/main/resources/mappers/plugin-sqlmap.xml
+++ b/shenyu-admin/src/main/resources/mappers/plugin-sqlmap.xml
@@ -234,7 +234,8 @@
                     config,
                     role,
                     sort,
-                    enabled)
+                    enabled,
+                    plugin_jar)
              VALUES (#{id, jdbcType=VARCHAR},
                     #{dateCreated, jdbcType=TIMESTAMP},
                     #{dateUpdated, jdbcType=TIMESTAMP},
@@ -242,7 +243,8 @@
                     #{config, jdbcType=VARCHAR},
                     #{role, jdbcType=VARCHAR},
                     #{sort, jdbcType=INTEGER},
-                    #{enabled, jdbcType=TINYINT})
+                    #{enabled, jdbcType=TINYINT},
+                    #{pluginJar, jdbcType=BLOB})
     </insert>
 
     <insert id="insertSelective" 
parameterType="org.apache.shenyu.admin.model.entity.PluginDO">
@@ -270,6 +272,9 @@
             <if test="enabled != null">
                 enabled,
             </if>
+            <if test="pluginJar != null">
+                plugin_jar,
+            </if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             #{id, jdbcType=VARCHAR},
@@ -294,6 +299,9 @@
             <if test="enabled != null">
                 #{enabled, jdbcType=TINYINT},
             </if>
+            <if test="pluginJar != null">
+                #{pluginJar, jdbcType=BLOB},
+            </if>
         </trim>
     </insert>
 
diff --git a/shenyu-admin/src/main/resources/sql-script/h2/schema.sql 
b/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
index 985cbcb36..84c024835 100755
--- a/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
+++ b/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
@@ -37,6 +37,7 @@ CREATE TABLE IF NOT EXISTS `plugin` (
   `enabled` tinyint(4) NOT NULL DEFAULT '0' COMMENT 'whether to open (0, not 
open, 1 open)',
   `date_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'create 
time',
   `date_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE 
CURRENT_TIMESTAMP COMMENT 'update time',
+  `plugin_jar` mediumblob  DEFAULT NULL COMMENT 'plugin jar',
   PRIMARY KEY (`id`)
 );
 
diff --git 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/PluginControllerTest.java
 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/PluginControllerTest.java
index ec55dc169..9b9673d93 100644
--- 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/PluginControllerTest.java
+++ 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/PluginControllerTest.java
@@ -34,6 +34,7 @@ import org.apache.shenyu.common.constant.AdminConstants;
 import org.apache.shenyu.common.enums.DataEventTypeEnum;
 import org.apache.shenyu.common.utils.DateUtils;
 import org.apache.shenyu.common.utils.GsonUtils;
+import org.hamcrest.Matchers;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -44,6 +45,7 @@ import org.mockito.junit.jupiter.MockitoSettings;
 import org.mockito.quality.Strictness;
 import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
@@ -136,17 +138,23 @@ public final class PluginControllerTest {
     
     @Test
     public void testCreatePlugin() throws Exception {
+        MockMultipartFile file = new MockMultipartFile("file", "test.jar", 
MediaType.TEXT_PLAIN_VALUE, "This is a test file.".getBytes());
         PluginDTO pluginDTO = new PluginDTO();
-        pluginDTO.setName("test");
+        pluginDTO.setName("test1");
         pluginDTO.setEnabled(true);
         pluginDTO.setRole("1");
         pluginDTO.setSort(100);
+        pluginDTO.setFile(file);
         
when(SpringBeanUtils.getInstance().getBean(PluginMapper.class)).thenReturn(pluginMapper);
-        
+        when(pluginMapper.existed(pluginDTO.getId())).thenReturn(false);
         
given(this.pluginService.createOrUpdate(pluginDTO)).willReturn(ShenyuResultMessage.CREATE_SUCCESS);
-        this.mockMvc.perform(MockMvcRequestBuilders.post("/plugin/")
-                .contentType(MediaType.APPLICATION_JSON)
-                .content(GsonUtils.getInstance().toJson(pluginDTO)))
+
+        this.mockMvc.perform(MockMvcRequestBuilders.multipart("/plugin")
+                        .file(file)
+                        .param("name", pluginDTO.getName())
+                        .param("enabled", pluginDTO.getEnabled() + "")
+                        .param("role", pluginDTO.getRole())
+                        .param("sort", pluginDTO.getSort() + ""))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$.message", 
is(ShenyuResultMessage.CREATE_SUCCESS)))
                 .andReturn();
@@ -154,21 +162,29 @@ public final class PluginControllerTest {
         pluginDTO.setId("123");
         when(pluginMapper.existed(pluginDTO.getId())).thenReturn(true);
         
given(this.pluginService.createOrUpdate(pluginDTO)).willReturn(ShenyuResultMessage.UPDATE_SUCCESS);
-        this.mockMvc.perform(MockMvcRequestBuilders.post("/plugin/")
-                .contentType(MediaType.APPLICATION_JSON)
-                .content(GsonUtils.getInstance().toJson(pluginDTO)))
+        this.mockMvc.perform(MockMvcRequestBuilders.multipart("/plugin")
+                        .file(file)
+                        .param("id", pluginDTO.getId())
+                        .param("name", pluginDTO.getName())
+                        .param("enabled", pluginDTO.getEnabled() + "")
+                        .param("role", pluginDTO.getRole())
+                        .param("sort", pluginDTO.getSort() + ""))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$.message", 
is(ShenyuResultMessage.UPDATE_SUCCESS)))
                 .andReturn();
+
         // update fail
         when(pluginMapper.existed(pluginDTO.getId())).thenReturn(false);
-        this.mockMvc.perform(MockMvcRequestBuilders.post("/plugin/")
-                .contentType(MediaType.APPLICATION_JSON)
-                .content(GsonUtils.getInstance().toJson(pluginDTO)))
+        this.mockMvc.perform(MockMvcRequestBuilders.multipart("/plugin")
+                        .file(file)
+                        .param("id", pluginDTO.getId())
+                        .param("name", pluginDTO.getName())
+                        .param("enabled", pluginDTO.getEnabled() + "")
+                        .param("role", pluginDTO.getRole())
+                        .param("sort", pluginDTO.getSort() + ""))
                 .andExpect(status().isOk())
-                .andExpect(jsonPath("$.message", is("Request error! invalid 
argument [id: the plugin is not exited]")))
+                .andExpect(jsonPath("$.message", Matchers.containsString("The 
system is busy, please try again later")))
                 .andReturn();
-        
     }
     
     @Test
@@ -183,23 +199,31 @@ public final class PluginControllerTest {
         when(pluginMapper.existed(pluginDTO.getId())).thenReturn(true);
         
given(this.pluginService.createOrUpdate(pluginDTO)).willReturn(ShenyuResultMessage.UPDATE_SUCCESS);
         this.mockMvc.perform(MockMvcRequestBuilders.put("/plugin/{id}", 
pluginDTO.getId())
-                .contentType(MediaType.APPLICATION_JSON)
-                .content(GsonUtils.getInstance().toJson(pluginDTO)))
+                        
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
+                        .param("name", pluginDTO.getName())
+                        .param("enabled", 
String.valueOf(pluginDTO.getEnabled()))
+                        .param("role", pluginDTO.getRole())
+                        .param("sort", String.valueOf(pluginDTO.getSort())))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$.message", 
is(ShenyuResultMessage.UPDATE_SUCCESS)))
                 .andReturn();
         when(pluginMapper.existed(pluginDTO.getId())).thenReturn(null);
         this.mockMvc.perform(MockMvcRequestBuilders.put("/plugin/{id}", 
pluginDTO.getId())
-                .contentType(MediaType.APPLICATION_JSON)
-                .content(GsonUtils.getInstance().toJson(pluginDTO)))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.message", is("Request error! invalid 
argument [id: the plugin is not exited]")))
+                        .contentType(MediaType.MULTIPART_FORM_DATA_VALUE)
+                        .param("name", pluginDTO.getName())
+                        .param("enabled", 
String.valueOf(pluginDTO.getEnabled()))
+                        .param("role", pluginDTO.getRole())
+                        .param("sort", String.valueOf(pluginDTO.getSort())))
+                .andExpect(jsonPath("$.message", is("The system is busy, 
please try again later")))
                 .andReturn();
         when(pluginMapper.existed(pluginDTO.getId())).thenReturn(true);
         
given(this.pluginService.createOrUpdate(pluginDTO)).willReturn(ShenyuResultMessage.CREATE_SUCCESS);
         this.mockMvc.perform(MockMvcRequestBuilders.put("/plugin/{id}", 
pluginDTO.getId())
-                .contentType(MediaType.APPLICATION_JSON)
-                .content(GsonUtils.getInstance().toJson(pluginDTO)))
+                        
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
+                        .param("name", pluginDTO.getName())
+                        .param("enabled", 
String.valueOf(pluginDTO.getEnabled()))
+                        .param("role", pluginDTO.getRole())
+                        .param("sort", String.valueOf(pluginDTO.getSort())))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$.message", 
is(ShenyuResultMessage.CREATE_SUCCESS)))
                 .andReturn();
diff --git a/shenyu-common/pom.xml b/shenyu-common/pom.xml
index bfe2b570b..d860e682b 100644
--- a/shenyu-common/pom.xml
+++ b/shenyu-common/pom.xml
@@ -68,5 +68,10 @@
             <groupId>commons-codec</groupId>
             <artifactId>commons-codec</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>org.ow2.asm</groupId>
+            <artifactId>asm-tree</artifactId>
+        </dependency>
     </dependencies>
 </project>
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/AdminConstants.java
 
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/AdminConstants.java
index 74ee4f5a6..9de092d5f 100644
--- 
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/AdminConstants.java
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/AdminConstants.java
@@ -264,4 +264,11 @@ public final class AdminConstants {
 
     public static final String TAG_ROOT_PARENT_ID = "0";
 
+    public static final String PLUGIN_JAR_IS_NOT_RIGHT = "The plugin jar is 
not right!";
+
+    public static final String PLUGIN_INTERFACE_PATH = 
"org.apache.shenyu.plugin.api.ShenyuPlugin";
+
+    public static final String PLUGIN_ABSTRACR_PATH = 
"org.apache.shenyu.plugin.base.AbstractShenyuPlugin";
+
 }
+
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/PluginData.java 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/PluginData.java
index b717e7b79..e8df01404 100644
--- a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/PluginData.java
+++ b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/PluginData.java
@@ -17,6 +17,7 @@
 
 package org.apache.shenyu.common.dto;
 
+import java.util.Arrays;
 import java.util.Objects;
 
 /**
@@ -35,9 +36,11 @@ public class PluginData {
     private String role;
 
     private Boolean enabled;
-    
+
     private Integer sort;
 
+    private byte[] pluginJar;
+
     /**
      * no args constructor.
      */
@@ -53,17 +56,18 @@ public class PluginData {
      * @param role    role
      * @param enabled enabled
      */
-    public PluginData(final String id, final String name, final String config, 
final String role, final Boolean enabled) {
+    public PluginData(final String id, final String name, final String config, 
final String role, final Boolean enabled, final byte[] pluginJar) {
         this.id = id;
         this.name = name;
         this.config = config;
         this.role = role;
         this.enabled = enabled;
+        this.pluginJar = pluginJar;
     }
-    
+
     /**
      * all args constructor.
-     * 
+     *
      * @param id id
      * @param name name
      * @param config config
@@ -72,13 +76,14 @@ public class PluginData {
      * @param sort sort
      */
     public PluginData(final String id, final String name, final String config, 
final String role, final Boolean enabled,
-                      final Integer sort) {
+                      final Integer sort, final byte[] pluginJar) {
         this.id = id;
         this.name = name;
         this.config = config;
         this.role = role;
         this.enabled = enabled;
         this.sort = sort;
+        this.pluginJar = pluginJar;
     }
 
     /**
@@ -93,6 +98,7 @@ public class PluginData {
         this.role = builder.role;
         this.enabled = builder.enabled;
         this.sort = builder.sort;
+        this.pluginJar = builder.pluginJar;
     }
 
     /**
@@ -185,6 +191,22 @@ public class PluginData {
         return enabled;
     }
 
+    /**
+     * get pluginJar.
+     * @return pluginJar
+     */
+    public byte[] getPluginJar() {
+        return pluginJar;
+    }
+
+    /**
+     * set pluginJar.
+     * @param pluginJar pluginJar
+     */
+    public void setPluginJar(final byte[] pluginJar) {
+        this.pluginJar = pluginJar;
+    }
+
     /**
      * get sort.
      *
@@ -197,7 +219,7 @@ public class PluginData {
 
     /**
      * set sort.
-     * 
+     *
      * @param sort sort value
      */
     public void setSort(final Integer sort) {
@@ -234,20 +256,13 @@ public class PluginData {
     @Override
     public String toString() {
         return "PluginData{"
-                + "id='"
-                + id
-                + '\''
-                + ", name='"
-                + name
-                + '\''
-                + ", config='"
-                + config
-                + '\''
-                + ", role='"
-                + role
-                + '\''
-                + ", enabled="
-                + enabled
+                + "id='" + id + '\''
+                + ", name='" + name + '\''
+                + ", config='" + config + '\''
+                + ", role='" + role + '\''
+                + ", enabled=" + enabled
+                + ", sort=" + sort
+                + ", pluginJar=" + Arrays.toString(pluginJar)
                 + '}';
     }
 
@@ -286,6 +301,12 @@ public class PluginData {
          */
         private Integer sort;
 
+        /**
+         * sort.
+         */
+        private byte[] pluginJar;
+
+
         /**
          * no args constructor.
          */
@@ -366,5 +387,17 @@ public class PluginData {
             this.sort = sort;
             return this;
         }
+
+
+        /**
+         * build pluginJar.
+         *
+         * @param  pluginJar pluginJar
+         * @return this
+         */
+        public Builder pluginJar(final byte[] pluginJar) {
+            this.pluginJar = pluginJar;
+            return this;
+        }
     }
 }
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/utils/JarDependencyUtils.java
 
b/shenyu-common/src/main/java/org/apache/shenyu/common/utils/JarDependencyUtils.java
new file mode 100644
index 000000000..3e3f0cea4
--- /dev/null
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/utils/JarDependencyUtils.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.common.utils;
+
+import org.apache.shenyu.common.exception.ShenyuException;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.FieldNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+/**
+ * Jar package dependency tools.
+ */
+public class JarDependencyUtils {
+
+    /**
+     * logger.
+     */
+    private static final Logger LOG = 
LoggerFactory.getLogger(JarDependencyUtils.class);
+
+    /**
+     * Obtain the dependency tree of the jar package file at compile time.
+     *
+     * @param jarBytes Byte array of jar file
+     * @return dependency tree
+     */
+    public static Set<String> getDependencyTree(final byte[] jarBytes) {
+        Set<String> dependencies = new HashSet<>();
+        try (InputStream inputStream = new ByteArrayInputStream(jarBytes);
+             ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
+            ZipEntry entry;
+            while ((entry = zipInputStream.getNextEntry()) != null) {
+                if (entry.getName().endsWith(".class")) {
+                    ClassNode classNode = new ClassNode(Opcodes.ASM7);
+                    ClassReader classReader = new ClassReader(zipInputStream);
+                    classReader.accept(classNode, 0);
+                    addDependencies(classNode.superName, dependencies);
+                    for (String interfaceName : classNode.interfaces) {
+                        addDependencies(interfaceName, dependencies);
+                    }
+                    for (FieldNode fieldNode : classNode.fields) {
+                        
addDependencies(Type.getType(fieldNode.desc).getClassName(), dependencies);
+                    }
+                    for (MethodNode methodNode : classNode.methods) {
+                        
addDependencies(Type.getReturnType(methodNode.desc).getClassName(), 
dependencies);
+                        for (Type argumentType : 
Type.getArgumentTypes(methodNode.desc)) {
+                            addDependencies(argumentType.getClassName(), 
dependencies);
+                        }
+                    }
+                }
+            }
+            return dependencies;
+
+        } catch (Exception e) {
+            LOG.error("get dependency tree error", e);
+            throw new ShenyuException(e);
+        }
+    }
+
+    /**
+     * Add dependencies.
+     * @param typeName type name
+     * @param dependencies dependencies
+     */
+    private static void addDependencies(final String typeName, final 
Set<String> dependencies) {
+        if (!typeName.startsWith("java") && !typeName.startsWith("javax")) {
+            dependencies.add(typeName.replace("/", "."));
+        }
+    }
+}
diff --git a/shenyu-dist/shenyu-admin-dist/src/main/release-docs/LICENSE 
b/shenyu-dist/shenyu-admin-dist/src/main/release-docs/LICENSE
index db91a7058..f2a508b7f 100644
--- a/shenyu-dist/shenyu-admin-dist/src/main/release-docs/LICENSE
+++ b/shenyu-dist/shenyu-admin-dist/src/main/release-docs/LICENSE
@@ -477,6 +477,7 @@ The text of each license is also included at 
licenses/LICENSE-[project].txt.
 
     qs 6.5.0: https://github.com/ljharb/qs, BSD 3-Clause
     react-intl-universal 2.4.2: 
https://github.com/alibaba/react-intl-universal, BSD 3-Clause
+    asm-tree 9.3: https://asm.ow2.io/, BSD 3-Clause
 
 ========================================================================
 ISC licenses
diff --git 
a/shenyu-integrated-test/shenyu-integrated-test-http/src/test/java/org/apache/shenyu/integrated/test/http/combination/MqttPluginTest.java
 
b/shenyu-integrated-test/shenyu-integrated-test-http/src/test/java/org/apache/shenyu/integrated/test/http/combination/MqttPluginTest.java
index 1fac23cce..847411c97 100644
--- 
a/shenyu-integrated-test/shenyu-integrated-test-http/src/test/java/org/apache/shenyu/integrated/test/http/combination/MqttPluginTest.java
+++ 
b/shenyu-integrated-test/shenyu-integrated-test-http/src/test/java/org/apache/shenyu/integrated/test/http/combination/MqttPluginTest.java
@@ -43,7 +43,7 @@ public final class MqttPluginTest extends 
AbstractPluginDataInit {
                 + "  \"isEncryptPassword\": false,"
                 + "  \"encryptMode\": \"\","
                 + "  \"leakDetectorLevel\": \"DISABLED\""
-                + "}", "0", true);
+                + "}", "0", true, null);
         mqttPluginDataHandler.handlerPlugin(enablePluginData);
         Thread.sleep(3000);
         assertTrue(isPortUsing());
diff --git 
a/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/handler/BrpcPluginDataHandlerTest.java
 
b/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/handler/BrpcPluginDataHandlerTest.java
index 4c880064c..5ffcaa10f 100644
--- 
a/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/handler/BrpcPluginDataHandlerTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/handler/BrpcPluginDataHandlerTest.java
@@ -39,7 +39,7 @@ public final class BrpcPluginDataHandlerTest {
     
     @Test
     public void testHandlerPlugin() {
-        final PluginData pluginData = new PluginData("id", "name", "config", 
"0", false);
+        final PluginData pluginData = new PluginData("id", "name", "config", 
"0", false, null);
         brpcPluginDataHandlerUnderTest.handlerPlugin(pluginData);
         assertTrue(pluginData.getName().endsWith("name"));
     }
diff --git 
a/shenyu-plugin/shenyu-plugin-casdoor/src/test/java/org/apache/shenyu/plugin/casdoor/CasdoorPluginTest.java
 
b/shenyu-plugin/shenyu-plugin-casdoor/src/test/java/org/apache/shenyu/plugin/casdoor/CasdoorPluginTest.java
index b3a3f3d00..ddc266ad5 100644
--- 
a/shenyu-plugin/shenyu-plugin-casdoor/src/test/java/org/apache/shenyu/plugin/casdoor/CasdoorPluginTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-casdoor/src/test/java/org/apache/shenyu/plugin/casdoor/CasdoorPluginTest.java
@@ -87,7 +87,7 @@ public class CasdoorPluginTest {
 
     @Test
     void doExecute() {
-        final PluginData pluginData = new PluginData("pluginId", "pluginName", 
"{\"organization-name\":\"test\",\"application-name\":\"app-test\",\"endpoint\":\"http://localhost:8000\",\"client_secrect\":\"a4209d412a33a842b7a9c05a3446e623cbb7262d\",\"client_id\":\"6e3a84154e73d1fb156a\",\"certificate\":\"-----BEGIN
 CERTIFICATE-----\\n\"}", "0", false);
+        final PluginData pluginData = new PluginData("pluginId", "pluginName", 
"{\"organization-name\":\"test\",\"application-name\":\"app-test\",\"endpoint\":\"http://localhost:8000\",\"client_secrect\":\"a4209d412a33a842b7a9c05a3446e623cbb7262d\",\"client_id\":\"6e3a84154e73d1fb156a\",\"certificate\":\"-----BEGIN
 CERTIFICATE-----\\n\"}", "0", false, null);
         casdoorPluginDateHandlerTest.handlerPlugin(pluginData);
         try {
             CasdoorAuthService casdoorAuthService = 
Singleton.INST.get(CasdoorAuthService.class);
diff --git 
a/shenyu-plugin/shenyu-plugin-casdoor/src/test/java/org/apache/shenyu/plugin/casdoor/handle/CasdoorPluginDateHandlerTest.java
 
b/shenyu-plugin/shenyu-plugin-casdoor/src/test/java/org/apache/shenyu/plugin/casdoor/handle/CasdoorPluginDateHandlerTest.java
index 7347f944c..a8df355fc 100644
--- 
a/shenyu-plugin/shenyu-plugin-casdoor/src/test/java/org/apache/shenyu/plugin/casdoor/handle/CasdoorPluginDateHandlerTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-casdoor/src/test/java/org/apache/shenyu/plugin/casdoor/handle/CasdoorPluginDateHandlerTest.java
@@ -37,7 +37,7 @@ class CasdoorPluginDateHandlerTest {
 
     @Test
     public void handlerPlugin() {
-        final PluginData pluginData = new PluginData("pluginId", "pluginName", 
"{\"organization-name\":\"test\",\"application-name\":\"app-test\",\"endpoint\":\"http://localhost:8000\",\"client_secrect\":\"a4209d412a33a842b7a9c05a3446e623cbb7262d\",\"client_id\":\"6e3a84154e73d1fb156a\",\"certificate\":\"-----BEGIN
 CERTIFICATE-----\\n\"}", "0", false);
+        final PluginData pluginData = new PluginData("pluginId", "pluginName", 
"{\"organization-name\":\"test\",\"application-name\":\"app-test\",\"endpoint\":\"http://localhost:8000\",\"client_secrect\":\"a4209d412a33a842b7a9c05a3446e623cbb7262d\",\"client_id\":\"6e3a84154e73d1fb156a\",\"certificate\":\"-----BEGIN
 CERTIFICATE-----\\n\"}", "0", false, null);
         casdoorPluginDateHandlerTest.handlerPlugin(pluginData);
         CasdoorAuthService casdoorAuthService = 
Singleton.INST.get(CasdoorAuthService.class);
         String redirect = "http://localhost:9195/http/hi";;
diff --git 
a/shenyu-plugin/shenyu-plugin-dubbo/shenyu-plugin-alibaba-dubbo/src/test/java/org/apache/shenyu/plugin/alibaba/dubbo/handler/AlibabaDubboPluginDataTest.java
 
b/shenyu-plugin/shenyu-plugin-dubbo/shenyu-plugin-alibaba-dubbo/src/test/java/org/apache/shenyu/plugin/alibaba/dubbo/handler/AlibabaDubboPluginDataTest.java
index a683e9248..b4a8b8122 100644
--- 
a/shenyu-plugin/shenyu-plugin-dubbo/shenyu-plugin-alibaba-dubbo/src/test/java/org/apache/shenyu/plugin/alibaba/dubbo/handler/AlibabaDubboPluginDataTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-dubbo/shenyu-plugin-alibaba-dubbo/src/test/java/org/apache/shenyu/plugin/alibaba/dubbo/handler/AlibabaDubboPluginDataTest.java
@@ -61,14 +61,14 @@ public final class AlibabaDubboPluginDataTest {
 
     @Test
     public void testPluginEnable() {
-        PluginData pluginData = new PluginData("", "", registryConfig, "1", 
true);
+        PluginData pluginData = new PluginData("", "", registryConfig, "1", 
true, null);
         alibabaDubboPluginDataHandler.handlerPlugin(pluginData);
         
assertEquals(Singleton.INST.get(DubboRegisterConfig.class).getRegister(), 
"127.0.0.1:2181");
     }
 
     @Test
     public void testPluginDisable() {
-        PluginData pluginData = new PluginData("", "", registryConfig, "1", 
false);
+        PluginData pluginData = new PluginData("", "", registryConfig, "1", 
false, null);
         alibabaDubboPluginDataHandler.handlerPlugin(pluginData);
         assertNull(Singleton.INST.get(DubboRegisterConfig.class));
     }
diff --git 
a/shenyu-plugin/shenyu-plugin-jwt/src/test/java/org/apache/shenyu/plugin/jwt/JwtPluginTest.java
 
b/shenyu-plugin/shenyu-plugin-jwt/src/test/java/org/apache/shenyu/plugin/jwt/JwtPluginTest.java
index 3bcdb76a3..910657d6b 100644
--- 
a/shenyu-plugin/shenyu-plugin-jwt/src/test/java/org/apache/shenyu/plugin/jwt/JwtPluginTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-jwt/src/test/java/org/apache/shenyu/plugin/jwt/JwtPluginTest.java
@@ -139,7 +139,7 @@ public final class JwtPluginTest {
         when(context.getBean(ShenyuResult.class)).thenReturn(new 
DefaultShenyuResult());
         SpringBeanUtils springBeanUtils = SpringBeanUtils.getInstance();
         springBeanUtils.setApplicationContext(context);
-        PluginData pluginData = new PluginData("pluginId", "pluginName", 
"{\"secretKey\":\"shenyu-test-shenyu-test-shenyu-test\"}", "0", false);
+        PluginData pluginData = new PluginData("pluginId", "pluginName", 
"{\"secretKey\":\"shenyu-test-shenyu-test-shenyu-test\"}", "0", false, null);
         JwtPluginDataHandler jwtPluginDataHandler = new JwtPluginDataHandler();
         jwtPluginDataHandler.handlerPlugin(pluginData);
     }
diff --git 
a/shenyu-plugin/shenyu-plugin-jwt/src/test/java/org/apache/shenyu/plugin/jwt/handle/JwtPluginDataHandlerTest.java
 
b/shenyu-plugin/shenyu-plugin-jwt/src/test/java/org/apache/shenyu/plugin/jwt/handle/JwtPluginDataHandlerTest.java
index 8c761bf07..1cba39090 100644
--- 
a/shenyu-plugin/shenyu-plugin-jwt/src/test/java/org/apache/shenyu/plugin/jwt/handle/JwtPluginDataHandlerTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-jwt/src/test/java/org/apache/shenyu/plugin/jwt/handle/JwtPluginDataHandlerTest.java
@@ -45,7 +45,7 @@ public final class JwtPluginDataHandlerTest {
 
     @Test
     public void testHandlerPlugin() {
-        final PluginData pluginData = new PluginData("pluginId", "pluginName", 
"{\"secretKey\":\"shenyu\"}", "0", false);
+        final PluginData pluginData = new PluginData("pluginId", "pluginName", 
"{\"secretKey\":\"shenyu\"}", "0", false, null);
         jwtPluginDataHandlerUnderTest.handlerPlugin(pluginData);
         JwtConfig jwtConfig = Singleton.INST.get(JwtConfig.class);
         Map<String, String> map = 
GsonUtils.getInstance().toObjectMap(pluginData.getConfig(), String.class);
diff --git 
a/shenyu-plugin/shenyu-plugin-mqtt/src/test/java/org/apache/shenyu/plugin/mqtt/handler/MqttPluginDataHandlerTest.java
 
b/shenyu-plugin/shenyu-plugin-mqtt/src/test/java/org/apache/shenyu/plugin/mqtt/handler/MqttPluginDataHandlerTest.java
index 2fecf5b8a..1e66b443e 100644
--- 
a/shenyu-plugin/shenyu-plugin-mqtt/src/test/java/org/apache/shenyu/plugin/mqtt/handler/MqttPluginDataHandlerTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-mqtt/src/test/java/org/apache/shenyu/plugin/mqtt/handler/MqttPluginDataHandlerTest.java
@@ -53,7 +53,7 @@ public class MqttPluginDataHandlerTest {
                 + "  \"isEncryptPassword\": false,"
                 + "  \"encryptMode\": \"\","
                 + "  \"leakDetectorLevel\": \"DISABLED\""
-                + "}", "0", true);
+                + "}", "0", true, null);
         mqttPluginDataHandlerUnderTest.handlerPlugin(enablePluginData);
         assertTrue(isPortUsing());
         final PluginData disablePluginData = new PluginData("pluginId", 
"pluginName", "{\n"
@@ -66,7 +66,7 @@ public class MqttPluginDataHandlerTest {
                 + "  \"isEncryptPassword\": false,"
                 + "  \"encryptMode\": \"\","
                 + "  \"leakDetectorLevel\": \"DISABLED\""
-                + "}", "0", false);
+                + "}", "0", false, null);
         mqttPluginDataHandlerUnderTest.handlerPlugin(disablePluginData);
 
         Awaitility.await()
diff --git 
a/shenyu-plugin/shenyu-plugin-sofa/src/test/java/org/apache/shenyu/plugin/sofa/handler/SofaPluginDataHandlerTest.java
 
b/shenyu-plugin/shenyu-plugin-sofa/src/test/java/org/apache/shenyu/plugin/sofa/handler/SofaPluginDataHandlerTest.java
index 850c67489..17b9a9647 100644
--- 
a/shenyu-plugin/shenyu-plugin-sofa/src/test/java/org/apache/shenyu/plugin/sofa/handler/SofaPluginDataHandlerTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-sofa/src/test/java/org/apache/shenyu/plugin/sofa/handler/SofaPluginDataHandlerTest.java
@@ -49,14 +49,14 @@ public final class SofaPluginDataHandlerTest {
 
     @Test
     public void testPluginEnable() {
-        PluginData pluginData = new PluginData("", "", registryConfig, "1", 
true);
+        PluginData pluginData = new PluginData("", "", registryConfig, "1", 
true, null);
         sofaPluginDataHandler.handlerPlugin(pluginData);
         assertEquals("127.0.0.1:2181", 
Singleton.INST.get(SofaRegisterConfig.class).getRegister());
     }
 
     @Test
     public void testPluginDisable() {
-        PluginData pluginData = new PluginData("", "", registryConfig, "1", 
false);
+        PluginData pluginData = new PluginData("", "", registryConfig, "1", 
false, null);
         sofaPluginDataHandler.handlerPlugin(pluginData);
         assertNull(Singleton.INST.get(SofaRegisterConfig.class));
     }
diff --git 
a/shenyu-plugin/shenyu-plugin-tars/src/test/java/org/apache/shenyu/plugin/tars/handler/TarsPluginDataHandlerTest.java
 
b/shenyu-plugin/shenyu-plugin-tars/src/test/java/org/apache/shenyu/plugin/tars/handler/TarsPluginDataHandlerTest.java
index 7d61fa37d..a9791f1ea 100644
--- 
a/shenyu-plugin/shenyu-plugin-tars/src/test/java/org/apache/shenyu/plugin/tars/handler/TarsPluginDataHandlerTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-tars/src/test/java/org/apache/shenyu/plugin/tars/handler/TarsPluginDataHandlerTest.java
@@ -45,7 +45,7 @@ public final class TarsPluginDataHandlerTest {
     
     @Test
     public void testHandlerPlugin() {
-        final PluginData pluginData = new PluginData("id", "name", 
"{\"threadpool\":\"cached\",\"corethreads\":1,\"threads\":2,\"queues\":3}", 
"0", true);
+        final PluginData pluginData = new PluginData("id", "name", 
"{\"threadpool\":\"cached\",\"corethreads\":1,\"threads\":2,\"queues\":3}", 
"0", true, null);
         tarsPluginDataHandlerUnderTest.handlerPlugin(pluginData);
         assertTrue(pluginData.getName().endsWith("name"));
         TarsRegisterConfig config = 
Singleton.INST.get(TarsRegisterConfig.class);
diff --git 
a/shenyu-plugin/shenyu-plugin-waf/src/test/java/org/apache/shenyu/plugin/waf/WafPluginTest.java
 
b/shenyu-plugin/shenyu-plugin-waf/src/test/java/org/apache/shenyu/plugin/waf/WafPluginTest.java
index cf28e1a9e..3bb68dbc7 100644
--- 
a/shenyu-plugin/shenyu-plugin-waf/src/test/java/org/apache/shenyu/plugin/waf/WafPluginTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-waf/src/test/java/org/apache/shenyu/plugin/waf/WafPluginTest.java
@@ -65,7 +65,7 @@ public final class WafPluginTest {
         springBeanUtils.setApplicationContext(context);
 
         final PluginData pluginData =
-                new PluginData("pluginId", "pluginName", 
"{\"model\":\"mix\"}", "0", false);
+                new PluginData("pluginId", "pluginName", 
"{\"model\":\"mix\"}", "0", false, null);
         WafPluginDataHandler wafPluginDataHandler = new WafPluginDataHandler();
         wafPluginDataHandler.handlerPlugin(pluginData);
 
@@ -92,7 +92,7 @@ public final class WafPluginTest {
     @Test
     public void testWafPluginBlackWafModel() {
         final PluginData pluginData =
-                new PluginData("pluginId", "pluginName", 
"{\"model\":\"black\"}", "0", false);
+                new PluginData("pluginId", "pluginName", 
"{\"model\":\"black\"}", "0", false, null);
         WafPluginDataHandler wafPluginDataHandler = new WafPluginDataHandler();
         wafPluginDataHandler.handlerPlugin(pluginData);
         Mono<Void> execute = wafPluginUnderTest.doExecute(exchange, chain, 
null, null);
diff --git 
a/shenyu-plugin/shenyu-plugin-waf/src/test/java/org/apache/shenyu/plugin/waf/handler/WafPluginDataHandlerTest.java
 
b/shenyu-plugin/shenyu-plugin-waf/src/test/java/org/apache/shenyu/plugin/waf/handler/WafPluginDataHandlerTest.java
index 01fb6c4c6..c801f623f 100644
--- 
a/shenyu-plugin/shenyu-plugin-waf/src/test/java/org/apache/shenyu/plugin/waf/handler/WafPluginDataHandlerTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-waf/src/test/java/org/apache/shenyu/plugin/waf/handler/WafPluginDataHandlerTest.java
@@ -45,7 +45,7 @@ public final class WafPluginDataHandlerTest {
 
     @Test
     public void testHandlerPlugin() {
-        final PluginData pluginData = new PluginData("pluginId", "pluginName", 
"{}", "0", false);
+        final PluginData pluginData = new PluginData("pluginId", "pluginName", 
"{}", "0", false, null);
         wafPluginDataHandlerUnderTest.handlerPlugin(pluginData);
         WafConfig wafConfig = Singleton.INST.get(WafConfig.class);
         assertEquals(GsonUtils.getInstance().toJson(wafConfig), 
pluginData.getConfig());
diff --git 
a/shenyu-web/src/test/java/org/apache/shenyu/web/controller/LocalPluginControllerTest.java
 
b/shenyu-web/src/test/java/org/apache/shenyu/web/controller/LocalPluginControllerTest.java
index c684371e4..fbddc5c14 100644
--- 
a/shenyu-web/src/test/java/org/apache/shenyu/web/controller/LocalPluginControllerTest.java
+++ 
b/shenyu-web/src/test/java/org/apache/shenyu/web/controller/LocalPluginControllerTest.java
@@ -167,7 +167,7 @@ public final class LocalPluginControllerTest {
     public void testDeleteAll() throws Exception {
         final String[] testPluginName = {"testDeleteAllPluginName", 
"testDeleteAllPluginName2"};
         Arrays.stream(testPluginName).map(s ->
-                new PluginData("id", s, null, null, null))
+                new PluginData("id", s, null, null, null, null))
                 .forEach(subscriber::onSubscribe);
         Arrays.stream(testPluginName)
                 .forEach(s -> 
assertThat(baseDataCache.obtainPluginData(s)).isNotNull());

Reply via email to