diff --git a/jcommon/docean-plugin/docean-plugin-redisSession/pom.xml b/jcommon/docean-plugin/docean-plugin-redisSession/pom.xml
new file mode 100644
index 000000000..00202a3e3
--- /dev/null
+++ b/jcommon/docean-plugin/docean-plugin-redisSession/pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+ run.mone
+ docean-plugin
+ 1.6.0-jdk21-SNAPSHOT
+
+
+ docean-plugin-redisSession
+
+
+ 21
+ 21
+ UTF-8
+
+
+
+
+ run.mone
+ docean
+ 1.6.1-jdk21-SNAPSHOT
+
+
+ run.mone
+ docean-plugin-redis
+ 1.6.0-jdk21-SNAPSHOT
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/jcommon/docean-plugin/docean-plugin-redisSession/src/main/java/run/mone/docean/plugin/redissession/RedisSessionPlugin.java b/jcommon/docean-plugin/docean-plugin-redisSession/src/main/java/run/mone/docean/plugin/redissession/RedisSessionPlugin.java
new file mode 100644
index 000000000..00af04be8
--- /dev/null
+++ b/jcommon/docean-plugin/docean-plugin-redisSession/src/main/java/run/mone/docean/plugin/redissession/RedisSessionPlugin.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2020 Xiaomi
+ *
+ * Licensed 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 run.mone.docean.plugin.redissession;
+
+import com.xiaomi.youpin.docean.Ioc;
+import com.xiaomi.youpin.docean.anno.DOceanPlugin;
+import com.xiaomi.youpin.docean.plugin.IPlugin;
+import com.xiaomi.youpin.docean.plugin.redis.Redis;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Set;
+
+/**
+ * @author shanwb
+ * @date 2024-09-03
+ */
+@DOceanPlugin(order = 101)
+@Slf4j
+public class RedisSessionPlugin implements IPlugin {
+
+
+ @Override
+ public void init(Set extends Class>> classSet, Ioc ioc) {
+ Redis redis = ioc.getBean(Redis.class);
+ if (null == redis) {
+ log.error("redis can not be empty");
+ }
+ RedisSessionStore redisSessionStore = new RedisSessionStore(redis);
+ ioc.putBean("ClusterSessionStore", redisSessionStore);
+ }
+
+}
diff --git a/jcommon/docean-plugin/docean-plugin-redisSession/src/main/java/run/mone/docean/plugin/redissession/RedisSessionStore.java b/jcommon/docean-plugin/docean-plugin-redisSession/src/main/java/run/mone/docean/plugin/redissession/RedisSessionStore.java
new file mode 100644
index 000000000..aa2884024
--- /dev/null
+++ b/jcommon/docean-plugin/docean-plugin-redisSession/src/main/java/run/mone/docean/plugin/redissession/RedisSessionStore.java
@@ -0,0 +1,100 @@
+package run.mone.docean.plugin.redissession;
+
+import com.google.gson.Gson;
+import com.xiaomi.youpin.docean.mvc.session.DefaultHttpSession;
+import com.xiaomi.youpin.docean.mvc.session.HttpSession;
+import com.xiaomi.youpin.docean.mvc.session.ISessionStore;
+import com.xiaomi.youpin.docean.plugin.redis.Redis;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author shanwb
+ * @date 2024-09-03
+ */
+@Slf4j
+public class RedisSessionStore implements ISessionStore {
+
+ private static final String SESSION_PREFIX = "DOCEAN_SESSION_";
+
+ private static final int SESSION_EXPIRE_SECONDS = 3600; // 默认60分钟过期
+
+ private final static Gson gson = new Gson();
+
+ private Redis redis;
+
+ public RedisSessionStore(Redis redis) {
+ this.redis = redis;
+ }
+
+ @Override
+ public void put(String sessionId, HttpSession session) {
+ try {
+ String key = SESSION_PREFIX + sessionId;
+ String value = gson.toJson(session);
+ redis.set(key, value, SESSION_EXPIRE_SECONDS);
+ } catch (Exception e) {
+ log.error("Error putting session to redis", e);
+ }
+ }
+
+ @Override
+ public void remove(String sessionId) {
+ try {
+ String key = SESSION_PREFIX + sessionId;
+ redis.del(key);
+ } catch (Exception e) {
+ log.error("Error removing session from redis", e);
+ }
+ }
+
+ @Override
+ public List sessionIdList() {
+ return new ArrayList<>();
+ }
+
+ @Override
+ public HttpSession get(String sessionId) {
+ try {
+ String key = SESSION_PREFIX + sessionId;
+ String value = redis.get(key);
+ if (value == null) {
+ return null;
+ }
+ return gson.fromJson(value, DefaultHttpSession.class);
+ } catch (Exception e) {
+ log.error("Error getting session from redis", e);
+ return null;
+ }
+ }
+
+ @Override
+ public HttpSession getAndRefresh(String sessionId) {
+ try {
+ String key = SESSION_PREFIX + sessionId;
+ String value = redis.get(key);
+ if (value == null) {
+ return null;
+ }
+ DefaultHttpSession session = gson.fromJson(value, DefaultHttpSession.class);
+ redis.expire(key, SESSION_EXPIRE_SECONDS);
+ return session;
+ } catch (Exception e) {
+ log.error("Error getting session from redis", e);
+ return null;
+ }
+ }
+
+ @Override
+ public boolean containsKey(String sessionId) {
+ try {
+ String key = SESSION_PREFIX + sessionId;
+ return redis.exists(key);
+ } catch (Exception e) {
+ log.error("Error checking session existence in redis", e);
+ return false;
+ }
+ }
+}
diff --git a/jcommon/docean-plugin/pom.xml b/jcommon/docean-plugin/pom.xml
index da7636cce..5f23cd892 100644
--- a/jcommon/docean-plugin/pom.xml
+++ b/jcommon/docean-plugin/pom.xml
@@ -55,6 +55,7 @@
docean-plugin-es-antlr4
docean-plugin-storage
docean-plugin-junit
+ docean-plugin-redisSession
diff --git a/jcommon/docean/README.md b/jcommon/docean/README.md
index 3919b1f98..6246febd6 100644
--- a/jcommon/docean/README.md
+++ b/jcommon/docean/README.md
@@ -15,4 +15,20 @@
processing, bean initialization, and loading into the container.
The plugin package has added extended support for some commonly used dependencies in projects, such as nacos, dubbo,
mybatis, and so on.
-* rate limited or exceeded quota
\ No newline at end of file
+* rate limited or exceeded quota
+
+#Feature
+
+## session用法
+### 单机session使用
+需要在ioc中加入一个bean[LocalSessionStore.java](src/main/java/com/xiaomi/youpin/docean/mvc/session/impl/LocalSessionStore.java)
+ioc init时,添加扫描路径"com.xiaomi.youpin.docean.mvc.session"
+
+### 分布式事务
+1.工程中引入两个plugin:[docean-plugin-redis](../docean-plugin/docean-plugin-redis)、[docean-plugin-redisSession](../docean-plugin/docean-plugin-redisSession)
+2.添加配置,开启分布式配置:ioc.putBean("$cluster-session", "true")
+
+
+
+
+
diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/Mvc.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/Mvc.java
index 0a73ec97f..9ded97ac9 100644
--- a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/Mvc.java
+++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/Mvc.java
@@ -81,17 +81,19 @@ private Mvc(Ioc ioc) {
}
private void setConfig(Ioc ioc) {
- this.mvcConfig.setAllowCross(Boolean.valueOf(ioc.getBean(MvcConst.ALLOW_CROSS_DOMAIN, MvcConst.FALSE)));
- this.mvcConfig.setDownload(Boolean.valueOf(ioc.getBean(MvcConst.MVC_DOWNLOAD, MvcConst.FALSE)));
- this.mvcConfig.setUseCglib(Boolean.valueOf(ioc.getBean(MvcConst.CGLIB, MvcConst.TRUE)));
+ this.mvcConfig.setAllowCross(Boolean.parseBoolean(ioc.getBean(MvcConst.ALLOW_CROSS_DOMAIN, MvcConst.FALSE)));
+ this.mvcConfig.setDownload(Boolean.parseBoolean(ioc.getBean(MvcConst.MVC_DOWNLOAD, MvcConst.FALSE)));
+ this.mvcConfig.setUseCglib(Boolean.parseBoolean(ioc.getBean(MvcConst.CGLIB, MvcConst.TRUE)));
- this.mvcConfig.setOpenStaticFile(Boolean.valueOf(ioc.getBean(MvcConst.OPEN_STATIC_FILE, MvcConst.FALSE)));
+ this.mvcConfig.setOpenStaticFile(Boolean.parseBoolean(ioc.getBean(MvcConst.OPEN_STATIC_FILE, MvcConst.FALSE)));
this.mvcConfig.setStaticFilePath(ioc.getBean(MvcConst.STATIC_FILE_PATH, MvcConst.EMPTY));
- this.mvcConfig.setResponseOriginalValue(Boolean.valueOf(ioc.getBean(MvcConst.RESPONSE_ORIGINAL_VALUE, MvcConst.FALSE)));
+ this.mvcConfig.setResponseOriginalValue(Boolean.parseBoolean(ioc.getBean(MvcConst.RESPONSE_ORIGINAL_VALUE, MvcConst.FALSE)));
this.mvcConfig.setPoolSize(Integer.valueOf(ioc.getBean(MvcConst.MVC_POOL_SIZE, String.valueOf(MvcConst.DEFAULT_MVC_POOL_SIZE))));
- this.mvcConfig.setVirtualThread(Boolean.valueOf(ioc.getBean(MvcConst.VIRTUAL_THREAD, MvcConst.TRUE)));
+ this.mvcConfig.setVirtualThread(Boolean.parseBoolean(ioc.getBean(MvcConst.VIRTUAL_THREAD, MvcConst.TRUE)));
this.mvcConfig.setResponseOriginalPath(ioc.getBean(MvcConst.RESPONSE_ORIGINAL_PATH, ""));
+ this.mvcConfig.setClusterSession(Boolean.parseBoolean(ioc.getBean(MvcConst.CLUSTER_SESSION, MvcConst.FALSE)));
+
ioc.publishEvent(new Event(EventType.mvcBegin, this.mvcConfig));
}
diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/bo/MvcConfig.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/bo/MvcConfig.java
index 89b9741bc..eece34154 100644
--- a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/bo/MvcConfig.java
+++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/bo/MvcConfig.java
@@ -47,4 +47,6 @@ public class MvcConfig implements Serializable {
*/
private String responseOriginalPath;
+ private boolean clusterSession;
+
}
diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcContext.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcContext.java
index a05a23d17..9e048ab5c 100644
--- a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcContext.java
+++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcContext.java
@@ -70,6 +70,11 @@ public class MvcContext {
*/
private boolean allowCross;
+ /**
+ * cluster session
+ */
+ private boolean clusterSession;
+
public HttpSession session() {
if (null == session) {
this.session = HttpSessionManager.getSession(this);
diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcRunnable.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcRunnable.java
index 70242831e..5ef9219c6 100644
--- a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcRunnable.java
+++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcRunnable.java
@@ -69,6 +69,7 @@ public MvcRunnable(Mvc mvc, HttpServerConfig config, ChannelHandlerContext ctx,
this.context.setVirtualThread(mvc.getMvcConfig().isVirtualThread());
this.context.setPath(path);
this.context.setAllowCross(mvc.getMvcConfig().isAllowCross());
+ this.context.setClusterSession(mvc.getMvcConfig().isClusterSession());
this.request.setMethod(method);
this.request.setPath(path);
this.request.setBody(body);
diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/common/MvcConst.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/common/MvcConst.java
index dd565822c..2c19debbe 100644
--- a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/common/MvcConst.java
+++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/common/MvcConst.java
@@ -32,6 +32,8 @@ public abstract class MvcConst {
public static final String RESPONSE_ORIGINAL_PATH = "$response-original-path";
+ public static final String CLUSTER_SESSION = "$cluster-session";
+
public static final int DEFAULT_MVC_POOL_SIZE = 200;
public static ScopedValue MVC_CONTEXT = ScopedValue.newInstance();
diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/HttpSessionManager.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/HttpSessionManager.java
index 2c8758044..759908350 100644
--- a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/HttpSessionManager.java
+++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/HttpSessionManager.java
@@ -16,7 +16,7 @@
package com.xiaomi.youpin.docean.mvc.session;
-import com.xiaomi.youpin.docean.common.Safe;
+import com.xiaomi.youpin.docean.Ioc;
import com.xiaomi.youpin.docean.mvc.MvcContext;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
@@ -26,49 +26,42 @@
import io.netty.handler.codec.http.cookie.ServerCookieEncoder;
import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
/**
* @author goodjava@qq.com
*/
public class HttpSessionManager {
+ private static ISessionStore getSessionStoreService(MvcContext mvcContext) {
+ boolean clusterSession = false;
+ if (null != mvcContext) {
+ clusterSession = mvcContext.isClusterSession();
+ }
- private static final Map SESSION_MAP = new ConcurrentHashMap<>();
-
-
- static {
- Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
- Safe.run(() -> {
- long now = System.currentTimeMillis();
- List ids = SESSION_MAP.values().stream().filter(it -> {
- DefaultHttpSession hs = (DefaultHttpSession) it;
- if (now - hs.getUpdateTime() > TimeUnit.MINUTES.toMillis(60)) {
- return true;
- }
- return false;
- }).map(it -> it.getId()).collect(Collectors.toList());
- ids.forEach(id -> SESSION_MAP.remove(id));
- }, e -> {
- });
- }, 10, 5, TimeUnit.SECONDS);
+ String beanName = clusterSession ? "ClusterSessionStore" : "SessionStore";
+ return (ISessionStore) Ioc.ins().getBean(beanName);
}
+ @Deprecated
public static String createSession() {
+ return createSession(null);
+ }
+
+ public static String createSession(MvcContext mvcContext) {
HttpSession session = new DefaultHttpSession();
String sessionId = session.getId();
- SESSION_MAP.put(sessionId, session);
+ ISessionStore sessionStoreService = getSessionStoreService(mvcContext);
+ sessionStoreService.put(sessionId, session);
+
return sessionId;
}
public static boolean isExists(String sessionId) {
- if (SESSION_MAP.containsKey(sessionId)) {
- HttpSession session = SESSION_MAP.get(sessionId);
+ ISessionStore sessionStoreService = getSessionStoreService(null);
+ if (sessionStoreService.containsKey(sessionId)) {
+ HttpSession session = sessionStoreService.get(sessionId);
if (session.getId() == null) {
- SESSION_MAP.remove(sessionId);
+ sessionStoreService.remove(sessionId);
return false;
}
return true;
@@ -78,32 +71,28 @@ public static boolean isExists(String sessionId) {
}
public static void invalidate(String sessionId) {
- SESSION_MAP.remove(sessionId);
+ ISessionStore sessionStoreService = getSessionStoreService(null);
+ sessionStoreService.remove(sessionId);
}
+ @Deprecated
public static HttpSession getSession(String sessionId) {
- return SESSION_MAP.compute(sessionId, (k, v) -> {
- if (null != v) {
- if (v instanceof DefaultHttpSession dhs) {
- dhs.setUpdateTime(System.currentTimeMillis());
- }
- }
- return v;
- });
+ return getSessionStoreService(null).get(sessionId);
}
public static HttpSession getSession(MvcContext context) {
String sid = getSessionId(context.getHeaders());
+ ISessionStore sessionStoreService = getSessionStoreService(context);
if (sid.equals("")) {
- String session = createSession();
- context.setSessionId(session);
- return getSession(session);
+ String sessionId = createSession(context);
+ context.setSessionId(sessionId);
+ return sessionStoreService.getAndRefresh(sessionId);
} else {
return Optional.ofNullable(getSession(sid)).orElseGet(() -> {
- String session = createSession();
- context.setSessionId(session);
- return getSession(session);
+ String sessionId = createSession(context);
+ context.setSessionId(sessionId);
+ return sessionStoreService.getAndRefresh(sessionId);
});
}
@@ -120,7 +109,7 @@ public static void setSessionId(MvcContext context, boolean exists, FullHttpResp
}
if (exists == false) {
- Cookie cookie = new DefaultCookie(HttpSession.SESSIONID, HttpSessionManager.createSession());
+ Cookie cookie = new DefaultCookie(HttpSession.SESSIONID, HttpSessionManager.createSession(context));
cookie.setPath("/");
String encodeCookie = ServerCookieEncoder.STRICT.encode(cookie);
response.headers().set(HttpHeaderNames.SET_COOKIE, encodeCookie);
diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/ISessionStore.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/ISessionStore.java
new file mode 100644
index 000000000..37ca14631
--- /dev/null
+++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/ISessionStore.java
@@ -0,0 +1,23 @@
+package com.xiaomi.youpin.docean.mvc.session;
+
+import java.util.List;
+
+/**
+ * @author shanwb
+ * @date 2024-09-03
+ */
+public interface ISessionStore {
+
+ void put(String sessionId, HttpSession session);
+
+ void remove(String sessionId);
+
+ List sessionIdList();
+
+ HttpSession get(String sessionId);
+
+ HttpSession getAndRefresh(String sessionId);
+
+ boolean containsKey(String sessionId);
+
+}
diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/impl/LocalSessionStore.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/impl/LocalSessionStore.java
new file mode 100644
index 000000000..583e84e6a
--- /dev/null
+++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/impl/LocalSessionStore.java
@@ -0,0 +1,78 @@
+package com.xiaomi.youpin.docean.mvc.session.impl;
+
+import com.xiaomi.youpin.docean.anno.Component;
+import com.xiaomi.youpin.docean.common.Safe;
+import com.xiaomi.youpin.docean.mvc.session.DefaultHttpSession;
+import com.xiaomi.youpin.docean.mvc.session.HttpSession;
+import com.xiaomi.youpin.docean.mvc.session.ISessionStore;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author shanwb
+ * @date 2024-09-03
+ */
+@Component(name = "SessionStore")
+public class LocalSessionStore implements ISessionStore {
+
+ private static final Map SESSION_MAP = new ConcurrentHashMap<>();
+
+ static {
+ Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
+ Safe.run(() -> {
+ long now = System.currentTimeMillis();
+ List ids = SESSION_MAP.values().stream().filter(it -> {
+ DefaultHttpSession hs = (DefaultHttpSession) it;
+ if (now - hs.getUpdateTime() > TimeUnit.MINUTES.toMillis(60)) {
+ return true;
+ }
+ return false;
+ }).map(HttpSession::getId).toList();
+ ids.forEach(SESSION_MAP::remove);
+ }, e -> {
+ });
+ }, 10, 5, TimeUnit.SECONDS);
+ }
+
+ @Override
+ public void put(String sessionId, HttpSession session) {
+ SESSION_MAP.put(sessionId, session);
+ }
+
+ @Override
+ public void remove(String sessionId) {
+ SESSION_MAP.remove(sessionId);
+ }
+
+ @Override
+ public List sessionIdList() {
+ return new ArrayList<>(SESSION_MAP.keySet());
+ }
+
+ @Override
+ public HttpSession get(String sessionId) {
+ return SESSION_MAP.get(sessionId);
+ }
+
+ @Override
+ public HttpSession getAndRefresh(String sessionId) {
+ return SESSION_MAP.compute(sessionId, (k, v) -> {
+ if (null != v) {
+ if (v instanceof DefaultHttpSession dhs) {
+ dhs.setUpdateTime(System.currentTimeMillis());
+ }
+ }
+ return v;
+ });
+ }
+
+ @Override
+ public boolean containsKey(String sessionId) {
+ return SESSION_MAP.containsKey(sessionId);
+ }
+}
diff --git a/jcommon/health/pom.xml b/jcommon/health/pom.xml
index af6c9da68..b6acecc7b 100644
--- a/jcommon/health/pom.xml
+++ b/jcommon/health/pom.xml
@@ -35,7 +35,7 @@
run.mone
aop
- 1.6.0-jdk21-SNAPSHOT
+ 1.6.1-jdk21-SNAPSHOT
diff --git a/jcommon/mistarter/pom.xml b/jcommon/mistarter/pom.xml
index 55d4f8994..51be0f31b 100644
--- a/jcommon/mistarter/pom.xml
+++ b/jcommon/mistarter/pom.xml
@@ -13,7 +13,7 @@
run.mone
aop
- 1.6.0-jdk21-SNAPSHOT
+ 1.6.1-jdk21-SNAPSHOT
org.springframework.boot
diff --git a/jcommon/pom.xml b/jcommon/pom.xml
index 317b7d665..024f44702 100644
--- a/jcommon/pom.xml
+++ b/jcommon/pom.xml
@@ -119,7 +119,7 @@
~/
8
8
- 1.6.0-jdk21-SNAPSHOT
+ 1.6.1-jdk21-SNAPSHOT
diff --git a/jcommon/schedule/pom.xml b/jcommon/schedule/pom.xml
index 48756b12d..e2e51e75b 100644
--- a/jcommon/schedule/pom.xml
+++ b/jcommon/schedule/pom.xml
@@ -13,13 +13,13 @@
run.mone
feishu
- 1.6.0-jdk21-SNAPSHOT
+ 1.6.1-jdk21-SNAPSHOT
compile
run.mone
common
- 1.7.1-SNAPSHOT
+ 1.6.1-jdk21-SNAPSHOT
run.mone