From 2441c92adadf6ae53b761d83d3817b9b47802163 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 7 Apr 2026 10:24:34 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8DAI=20SPI=20classloader?= =?UTF-8?q?=E6=89=BE=E4=B8=8D=E5=88=B0=E5=AE=9E=E7=8E=B0=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=88issue#4241@Github=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java | 6 ++---- .../src/main/java/cn/hutool/ai/core/AIConfigRegistry.java | 6 ++---- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01e73fbc03..3a6812c173 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,13 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.45(2026-03-20) +# 5.8.45(2026-04-07) ### 🐣新特性 * 【core 】 `AnnotationUtil`新增两级缓存架构,提升高频注解解析性能(pr#1434@Gitee) ### 🐞Bug修复 * 【db 】 修复`Page`和`PageResult`首页调用问题(issue#IH7A18@Gitee) +* 【ai 】 修复AI SPI classloader找不到实现问题(issue#4241@Github) ------------------------------------------------------------------------------------------------------------- # 5.8.44(2026-03-11) diff --git a/hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java b/hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java index 23cb874037..1f8d27a2da 100644 --- a/hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java +++ b/hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java @@ -22,7 +22,6 @@ import cn.hutool.ai.core.AIServiceProvider; import cn.hutool.core.util.ServiceLoaderUtil; import java.util.Map; -import java.util.ServiceLoader; import java.util.concurrent.ConcurrentHashMap; /** @@ -37,9 +36,8 @@ public class AIServiceFactory { // 加载所有 AIModelProvider 实现类 static { - final ServiceLoader loader = ServiceLoaderUtil.load(AIServiceProvider.class); - for (final AIServiceProvider provider : loader) { - providers.put(provider.getServiceName().toLowerCase(), provider); + for (final AIServiceProvider provider : ServiceLoaderUtil.load(AIServiceProvider.class, AIServiceProvider.class.getClassLoader())) { + providers.putIfAbsent(provider.getServiceName().toLowerCase(), provider); } } diff --git a/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigRegistry.java b/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigRegistry.java index 6166440495..5bca57b856 100644 --- a/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigRegistry.java +++ b/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigRegistry.java @@ -19,7 +19,6 @@ package cn.hutool.ai.core; import cn.hutool.core.util.ServiceLoaderUtil; import java.util.Map; -import java.util.ServiceLoader; import java.util.concurrent.ConcurrentHashMap; /** @@ -34,9 +33,8 @@ public class AIConfigRegistry { // 加载所有 AIConfig 实现类 static { - final ServiceLoader loader = ServiceLoaderUtil.load(AIConfig.class); - for (final AIConfig config : loader) { - configClasses.put(config.getModelName().toLowerCase(), config.getClass()); + for (final AIConfig config : ServiceLoaderUtil.load(AIConfig.class, AIConfig.class.getClassLoader())) { + configClasses.putIfAbsent(config.getModelName().toLowerCase(), config.getClass()); } } From 49858088d36107851575196c1acd89a3f1c764f2 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 7 Apr 2026 10:49:36 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8DAI=20SPI=20classloader?= =?UTF-8?q?=E6=89=BE=E4=B8=8D=E5=88=B0=E5=AE=9E=E7=8E=B0=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=88issue#4241@Github=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java | 4 ++++ .../src/main/java/cn/hutool/ai/core/AIConfigRegistry.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java b/hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java index 1f8d27a2da..928bf27204 100644 --- a/hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java +++ b/hutool-ai/src/main/java/cn/hutool/ai/AIServiceFactory.java @@ -36,6 +36,10 @@ public class AIServiceFactory { // 加载所有 AIModelProvider 实现类 static { + for (final AIServiceProvider provider : ServiceLoaderUtil.load(AIServiceProvider.class)) { + providers.putIfAbsent(provider.getServiceName().toLowerCase(), provider); + } + // issue#4241@github,多线程和Spring环境下可能导致SPI文件找不到问题 for (final AIServiceProvider provider : ServiceLoaderUtil.load(AIServiceProvider.class, AIServiceProvider.class.getClassLoader())) { providers.putIfAbsent(provider.getServiceName().toLowerCase(), provider); } diff --git a/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigRegistry.java b/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigRegistry.java index 5bca57b856..d6070bda0b 100644 --- a/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigRegistry.java +++ b/hutool-ai/src/main/java/cn/hutool/ai/core/AIConfigRegistry.java @@ -33,6 +33,10 @@ public class AIConfigRegistry { // 加载所有 AIConfig 实现类 static { + for (final AIConfig config : ServiceLoaderUtil.load(AIConfig.class)) { + configClasses.putIfAbsent(config.getModelName().toLowerCase(), config.getClass()); + } + // issue#4241@github,多线程和Spring环境下可能导致SPI文件找不到问题 for (final AIConfig config : ServiceLoaderUtil.load(AIConfig.class, AIConfig.class.getClassLoader())) { configClasses.putIfAbsent(config.getModelName().toLowerCase(), config.getClass()); } From 9505fdab708dc417331544b0d444831132341947 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 9 May 2026 10:31:25 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D`ExpressionEngine`?= =?UTF-8?q?=E4=B8=ADSpELEngine=E3=80=81MVEL=E7=99=BD=E5=90=8D=E5=8D=95?= =?UTF-8?q?=E6=97=A0=E6=95=88=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 5 +- .../core/io/ValidateObjectInputStream.java | 9 +- .../java/cn/hutool/core/util/JNDIUtil.java | 87 ++++++++++++++++++- .../expression/engine/mvel/MvelEngine.java | 12 +++ .../expression/engine/rhino/RhinoEngine.java | 12 +++ .../expression/engine/spel/SpELEngine.java | 21 ++++- 6 files changed, 131 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a6812c173..9eaea475ba 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,16 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.45(2026-04-07) +# 5.8.45(2026-05-09) ### 🐣新特性 * 【core 】 `AnnotationUtil`新增两级缓存架构,提升高频注解解析性能(pr#1434@Gitee) ### 🐞Bug修复 * 【db 】 修复`Page`和`PageResult`首页调用问题(issue#IH7A18@Gitee) * 【ai 】 修复AI SPI classloader找不到实现问题(issue#4241@Github) +* 【extra 】 修复`ExpressionEngine`中SpELEngine、MVEL白名单无效问题(issue#4249@Github) +* 【core 】 修复`JNDIUtil`远程加载漏洞(issue#4249@Github) +* 【core 】 修复`ValidateObjectInputStream`白名单规则问题(issue#4249@Github) ------------------------------------------------------------------------------------------------------------- # 5.8.44(2026-03-11) diff --git a/hutool-core/src/main/java/cn/hutool/core/io/ValidateObjectInputStream.java b/hutool-core/src/main/java/cn/hutool/core/io/ValidateObjectInputStream.java index e643895077..3d9408e155 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/ValidateObjectInputStream.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/ValidateObjectInputStream.java @@ -85,14 +85,7 @@ public class ValidateObjectInputStream extends ObjectInputStream { } } - if(CollUtil.isEmpty(this.whiteClassSet)){ - return; - } - if(className.startsWith("java.")){ - // java中的类默认在白名单中 - return; - } - if(this.whiteClassSet.contains(className)){ + if(CollUtil.isEmpty(this.whiteClassSet) || this.whiteClassSet.contains(className)){ return; } diff --git a/hutool-core/src/main/java/cn/hutool/core/util/JNDIUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/JNDIUtil.java index 3484be1b93..7a0813baa3 100755 --- a/hutool-core/src/main/java/cn/hutool/core/util/JNDIUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/JNDIUtil.java @@ -8,7 +8,9 @@ import javax.naming.InitialContext; import javax.naming.NamingException; import javax.naming.directory.Attributes; import javax.naming.directory.InitialDirContext; +import java.util.Arrays; import java.util.Hashtable; +import java.util.List; import java.util.Map; /** @@ -20,15 +22,20 @@ import java.util.Map; * 见:https://blog.csdn.net/u010430304/article/details/54601302 *

* - * @author loolY + * @author looly * @since 5.7.7 */ public class JNDIUtil { /** * 创建{@link InitialDirContext} + * 建议在应用启动时设置系统属性(禁用远程 codebase 加载) + *
{@code
+	 *   System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "false");
+	 *   System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "false");
+	 * }
* - * @param environment 环境参数,{@code null}表示无参数 + * @param environment 环境参数,如@{code java.naming.factory.initial}和{@code java.naming.provider.url},{@code null}表示无参数 * @return {@link InitialDirContext} */ public static InitialDirContext createInitialDirContext(Map environment) { @@ -36,6 +43,10 @@ public class JNDIUtil { if (MapUtil.isEmpty(environment)) { return new InitialDirContext(); } + + // issue#4249 修复JNDI注入漏洞 + validateEnvironment(environment); + return new InitialDirContext(Convert.convert(Hashtable.class, environment)); } catch (NamingException e) { throw new UtilException(e); @@ -43,9 +54,14 @@ public class JNDIUtil { } /** - * 创建{@link InitialContext} + * 创建{@link InitialContext}
+ * 建议在应用启动时设置系统属性(禁用远程 codebase 加载) + *
{@code
+	 *   System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "false");
+	 *   System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "false");
+	 * }
* - * @param environment 环境参数,{@code null}表示无参数 + * @param environment 环境参数,如@{code java.naming.factory.initial}和{@code java.naming.provider.url},{@code null}表示无参数 * @return {@link InitialContext} */ public static InitialContext createInitialContext(Map environment) { @@ -53,6 +69,10 @@ public class JNDIUtil { if (MapUtil.isEmpty(environment)) { return new InitialContext(); } + + // issue#4249 修复JNDI注入漏洞 + validateEnvironment(environment); + return new InitialContext(Convert.convert(Hashtable.class, environment)); } catch (NamingException e) { throw new UtilException(e); @@ -74,4 +94,63 @@ public class JNDIUtil { throw new UtilException(e); } } + + private static final List SAFE_PROTOCOLS = Arrays.asList( + "java:", + "dns:" + ); + + /** + * 验证并过滤environment中的危险属性 + * + * @param environment 原始环境参数 + * @return 过滤后的环境参数 + */ + private static Map validateEnvironment(Map environment) { + if (MapUtil.isNotEmpty(environment)) { + // 检查 PROVIDER_URL + String providerUrl = environment.get("java.naming.provider.url"); + if (StrUtil.isNotBlank(providerUrl) && !isSafeProtocol(providerUrl)) { + throw new UtilException("JNDI protocol not allowed: " + providerUrl); + } + + // 检查 INITIAL_CONTEXT_FACTORY + String factory = environment.get("java.naming.factory.initial"); + if (StrUtil.isNotBlank(factory)) { + // 只允许安全的工厂类 + if (!factory.startsWith("com.sun.jndi.dns.") && + !factory.startsWith("com.sun.jndi.ldap.") && + !factory.startsWith("com.sun.jndi.rmi.")) { + throw new UtilException("JNDI factory not allowed: " + factory); + } + } + } + + return environment; + } + + /** + * 检查URL是否在协议白名单内 + * + * @param url 要检查的URL + * @param allowedProtocols 允许的协议列表,{@code null}或空表示使用默认安全协议 + * @return 是否安全 + */ + private static boolean isSafeProtocol(String url, String... allowedProtocols) { + if (StrUtil.isBlank(url)) { + return false; + } + + List protocols = (allowedProtocols != null && allowedProtocols.length > 0) + ? Arrays.asList(allowedProtocols) + : SAFE_PROTOCOLS; + + String lowerUrl = url.toLowerCase(); + for (String protocol : protocols) { + if (lowerUrl.startsWith(protocol.toLowerCase())) { + return true; + } + } + return false; + } } diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/mvel/MvelEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/mvel/MvelEngine.java index b580418818..ae85d47666 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/mvel/MvelEngine.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/mvel/MvelEngine.java @@ -1,6 +1,8 @@ package cn.hutool.extra.expression.engine.mvel; +import cn.hutool.core.collection.CollUtil; import cn.hutool.extra.expression.ExpressionEngine; +import cn.hutool.extra.expression.ExpressionException; import org.mvel2.MVEL; import java.util.Collection; @@ -27,6 +29,16 @@ public class MvelEngine implements ExpressionEngine { @Override public Object eval(String expression, Map context, Collection> allowClassSet) { + + // issue#4249 检查context的value类型是否在白名单中,不在则抛出异常 + if(CollUtil.isNotEmpty(allowClassSet)){ + context.values().forEach(value -> { + if(!allowClassSet.contains(value.getClass())){ + throw new ExpressionException("Value type [{}] is not in allowClassSet [{}]", value.getClass(), allowClassSet); + } + }); + } + return MVEL.eval(expression, context); } diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/rhino/RhinoEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/rhino/RhinoEngine.java index 7e2d406cb6..8adfa4a296 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/rhino/RhinoEngine.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/rhino/RhinoEngine.java @@ -1,7 +1,9 @@ package cn.hutool.extra.expression.engine.rhino; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.extra.expression.ExpressionEngine; +import cn.hutool.extra.expression.ExpressionException; import org.mozilla.javascript.Context; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; @@ -24,6 +26,16 @@ public class RhinoEngine implements ExpressionEngine { @Override public Object eval(String expression, Map context, Collection> allowClassSet) { + + // issue#4249 检查context的value类型是否在白名单中,不在则抛出异常 + if(CollUtil.isNotEmpty(allowClassSet)){ + context.values().forEach(value -> { + if(!allowClassSet.contains(value.getClass())){ + throw new ExpressionException("Value type [{}] is not in allowClassSet [{}]", value.getClass(), allowClassSet); + } + }); + } + final Context ctx = Context.enter(); final Scriptable scope = ctx.initStandardObjects(); if (MapUtil.isNotEmpty(context)) { diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/spel/SpELEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/spel/SpELEngine.java index 06c647dc61..8c7766701e 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/spel/SpELEngine.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/spel/SpELEngine.java @@ -1,10 +1,12 @@ package cn.hutool.extra.expression.engine.spel; +import cn.hutool.core.collection.CollUtil; import cn.hutool.extra.expression.ExpressionEngine; +import cn.hutool.extra.expression.ExpressionException; import org.springframework.expression.EvaluationContext; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; +import org.springframework.expression.spel.support.SimpleEvaluationContext; import java.util.Collection; import java.util.Map; @@ -29,7 +31,22 @@ public class SpELEngine implements ExpressionEngine { @Override public Object eval(String expression, Map context, Collection> allowClassSet) { - final EvaluationContext evaluationContext = new StandardEvaluationContext(); + // final EvaluationContext evaluationContext = new StandardEvaluationContext(); + + // issue#4249 检查context的value类型是否在白名单中,不在则抛出异常 + if(CollUtil.isNotEmpty(allowClassSet)){ + context.values().forEach(value -> { + if(!allowClassSet.contains(value.getClass())){ + throw new ExpressionException("Value type [{}] is not in allowClassSet [{}]", value.getClass(), allowClassSet); + } + }); + } + + EvaluationContext evaluationContext = SimpleEvaluationContext + .forReadOnlyDataBinding() + .withInstanceMethods() // 仅允许调用白名单类的实例方法 + .build(); + context.forEach(evaluationContext::setVariable); return parser.parseExpression(expression).getValue(evaluationContext); } From 076f5096df9e264245cf383c0a2ac130ec3a8ad5 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 9 May 2026 10:50:50 +0800 Subject: [PATCH 04/11] update thymeleaf --- hutool-extra/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index 1b9da409db..fcacebbe27 100755 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -24,7 +24,7 @@ 1.4.2 2.3.32 5.1.3 - 3.1.2.RELEASE + 3.1.5.RELEASE 1.6.2 0.1.55 0.38.0 From cc6df6990bfd2597300cd0a7ca6b0152eec450f0 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 9 May 2026 10:52:03 +0800 Subject: [PATCH 05/11] update postgre --- hutool-db/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml index 4c51456538..a626ceb9df 100755 --- a/hutool-db/pom.xml +++ b/hutool-db/pom.xml @@ -145,7 +145,7 @@ org.postgresql postgresql - 42.7.3 + 42.7.11 test From 6d8dd9729222712a444eb6a2b45ae50e5bba43c4 Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 14 May 2026 16:29:23 +0800 Subject: [PATCH 06/11] =?UTF-8?q?`RegexPool.PLATE=5FNUMBER`=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E7=B2=A4AP=E5=8F=B7=E6=AE=B5=E6=94=AF=E6=8C=81?= =?UTF-8?q?=EF=BC=88issue#IJNDJR@Gitee=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- .../src/main/java/cn/hutool/core/lang/RegexPool.java | 2 +- .../src/test/java/cn/hutool/core/lang/ValidatorTest.java | 9 +++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9eaea475ba..e1ce02d0da 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,10 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.45(2026-05-09) +# 5.8.45(2026-05-14) ### 🐣新特性 * 【core 】 `AnnotationUtil`新增两级缓存架构,提升高频注解解析性能(pr#1434@Gitee) +* 【core 】 `RegexPool.PLATE_NUMBER`新增粤AP号段支持(issue#IJNDJR@Gitee) ### 🐞Bug修复 * 【db 】 修复`Page`和`PageResult`首页调用问题(issue#IH7A18@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/RegexPool.java b/hutool-core/src/main/java/cn/hutool/core/lang/RegexPool.java index e209b8a16d..d9c8ea147e 100755 --- a/hutool-core/src/main/java/cn/hutool/core/lang/RegexPool.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/RegexPool.java @@ -145,7 +145,7 @@ public interface RegexPool { */ String PLATE_NUMBER = //https://gitee.com/chinabugotech/hutool/issues/I1B77H?from=project-issue - "^(([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z](([0-9]{5}[ABCDEFGHJK])|([ABCDEFGHJK]([A-HJ-NP-Z0-9])[0-9]{4})))|" + + "^(([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z](([0-9]{5}[ABCDEFGHJK])|([ABCDEFGHJKP]([A-HJ-NP-Z0-9])[0-9]{4})))|" + //https://gitee.com/chinabugotech/hutool/issues/I1BJHE?from=project-issue "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领]\\d{3}\\d{1,3}[领])|" + "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳使领]))$"; diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/ValidatorTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/ValidatorTest.java index c09cb77df5..125a46591b 100755 --- a/hutool-core/src/test/java/cn/hutool/core/lang/ValidatorTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/ValidatorTest.java @@ -167,6 +167,15 @@ public class ValidatorTest { assertTrue(Validator.isPlateNumber("闽20401领")); //issue#3979 assertTrue(Validator.isPlateNumber("沪AE22075")); + + // issue#IJNDJR + assertTrue(Validator.isPlateNumber("粤AP00000")); + assertTrue(Validator.isPlateNumber("粤AP00001")); + assertTrue(Validator.isPlateNumber("粤AP10000")); + assertTrue(Validator.isPlateNumber("粤AP20000")); + assertTrue(Validator.isPlateNumber("粤AP30000")); + assertTrue(Validator.isPlateNumber("粤AP40000")); + assertTrue(Validator.isPlateNumber("粤AP50000")); } @Test From eaecb109cfa374b7275cd31fed8883ef5336200e Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 14 May 2026 22:30:38 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D`VersionUtil`=E6=AF=94?= =?UTF-8?q?=E5=AF=B9null=E6=97=B6=E7=BB=93=E6=9E=9C=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=88issue#IJNFQZ@Gitee=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../src/main/java/cn/hutool/core/util/VersionUtil.java | 5 ++++- .../src/test/java/cn/hutool/core/util/VersionUtilTest.java | 7 +++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1ce02d0da..b9073bd72c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * 【extra 】 修复`ExpressionEngine`中SpELEngine、MVEL白名单无效问题(issue#4249@Github) * 【core 】 修复`JNDIUtil`远程加载漏洞(issue#4249@Github) * 【core 】 修复`ValidateObjectInputStream`白名单规则问题(issue#4249@Github) +* 【core 】 修复`VersionUtil`比对null时结果异常问题(issue#IJNFQZ@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.44(2026-03-11) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/VersionUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/VersionUtil.java index aa666c97d3..706483f0da 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/VersionUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/VersionUtil.java @@ -142,7 +142,7 @@ public class VersionUtil { throw new UtilException("非法的版本分隔符:" + versionsDelimiter); } - if (StrUtil.isBlank(versionEl) || StrUtil.isBlank(currentVersion)) { + if (StrUtil.isBlank(versionEl)) { return false; } String trimmedVersion = StrUtil.trim(currentVersion); @@ -158,6 +158,9 @@ public class VersionUtil { if (matcher.find()) { String op = matcher.group(); String ver = StrUtil.removePrefix(el, op); + if("null".equalsIgnoreCase( ver)){ + ver = null; + } switch (op) { case ">=": case "≥": diff --git a/hutool-core/src/test/java/cn/hutool/core/util/VersionUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/VersionUtilTest.java index e89abd046b..f5a7a640a8 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/VersionUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/VersionUtilTest.java @@ -1,6 +1,7 @@ package cn.hutool.core.util; import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.comparator.VersionComparator; import cn.hutool.core.exceptions.UtilException; import org.junit.jupiter.api.Test; @@ -104,4 +105,10 @@ class VersionUtilTest { assertTrue(VersionUtil.matchEl("999.999.999", "-")); } + @Test + void issueIJNFQZTest(){ + assertEquals(1, VersionComparator.INSTANCE.compare("1.0", null)); + assertEquals(1, StrUtil.compareVersion("1.0", null)); + assertTrue(VersionUtil.isGreaterThan("1.0", null)); + } } From 64fc614618759b62bb0db27e7c9fa585a7afe2a8 Mon Sep 17 00:00:00 2001 From: Faerytale <12410707@mail.sustech.edu.cn> Date: Tue, 19 May 2026 02:15:39 +0800 Subject: [PATCH 08/11] =?UTF-8?q?fix:=20BeanConverter=E5=92=8CMapConverter?= =?UTF-8?q?=E5=AF=B9=E6=BA=90Bean=E4=BD=BF=E7=94=A8isReadableBean=E6=9B=BF?= =?UTF-8?q?=E4=BB=A3isBean?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修了 #4245 的问题。当 List 里的元素类用了 @Setter(AccessLevel.PROTECTED) 只有 protected setter 的时候,BeanUtil.copyProperties 会抛 ConvertException: Unsupported source type,但实际上这个类有 public getter, 作为源对象完全可以被读取。 原因是 BeanConverter 和 MapConverter 在处理源对象时用 isBean() 做检查, 但 isBean() 看的是有没有 public setter,这是判断"能不能写"的标准, 而源对象需要的是"能不能读"。BeanUtil 里其实已经有 isReadableBean() 方法 (检查 public getter),正好适合这个场景,换过来就行。两个转换器各改了一行, 另外补了两个单测覆盖这种情况。 --- .../core/convert/impl/BeanConverter.java | 2 +- .../core/convert/impl/MapConverter.java | 2 +- .../cn/hutool/core/bean/BeanUtilTest.java | 81 +++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/BeanConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/BeanConverter.java index 42abb70f6c..7cfd124ef2 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/BeanConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/BeanConverter.java @@ -79,7 +79,7 @@ public class BeanConverter extends AbstractConverter { if(value instanceof Map || value instanceof ValueProvider || - BeanUtil.isBean(value.getClass())) { + BeanUtil.isReadableBean(value.getClass())) { if(value instanceof Map && this.beanClass.isInterface()) { // 将Map动态代理为Bean return MapProxy.create((Map)value).toProxyBean(this.beanClass); diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java index f01a46c049..6f0f3375c8 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java @@ -73,7 +73,7 @@ public class MapConverter extends AbstractConverter> { map = MapUtil.createMap(mapClass); } convertMapToMap((Map) value, map); - } else if (BeanUtil.isBean(value.getClass())) { + } else if (BeanUtil.isReadableBean(value.getClass())) { if(value.getClass().getName().equals("cn.hutool.json.JSONArray")){ // issue#3795 增加JSONArray转Map错误检查 throw new UnsupportedOperationException(StrUtil.format("Unsupported {} to Map.", value.getClass().getName())); diff --git a/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java index c52d6c18e8..751874fa3f 100755 --- a/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java @@ -974,4 +974,85 @@ public class BeanUtilTest { final boolean bean = BeanUtil.isBean(Dict.class); assertFalse(bean); } + + // ============ Test for GitHub issue #4245 ============ + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class Order4245 { + private Long orderId; + private String orderNo; + private List orderItemList; + } + + @Getter + @Setter(AccessLevel.PROTECTED) + @AllArgsConstructor(access = AccessLevel.PROTECTED) + @NoArgsConstructor + public static class OrderItem4245 { + private Long itemId; + private String productName; + private Integer quantity; + } + + @Data + public static class OrderDto4245 { + private Long orderId; + private String orderNo; + private List orderItemList; + } + + @Data + public static class OrderItemDto4245 { + private Long itemId; + private String productName; + private Integer quantity; + } + + /** + * GitHub issue#4245: BeanUtil.copyProperties throws ConvertException + * when source list element has protected setters. + * + *

Root cause: BeanConverter used isBean() (which checks for public setters) + * on the SOURCE object instead of isReadableBean() (which checks for public getters). + * A source bean only needs to be readable, not writable.

+ */ + @Test + public void issue4245Test() { + final Order4245 order = new Order4245( + 1L, + "01", + new ArrayList<>() + ); + order.getOrderItemList().add( + new OrderItem4245(1L, "aa", 1) + ); + + // This should not throw ConvertException + final OrderDto4245 dto = BeanUtil.copyProperties(order, OrderDto4245.class); + + assertNotNull(dto); + assertEquals(order.getOrderId(), dto.getOrderId()); + assertEquals(order.getOrderNo(), dto.getOrderNo()); + assertNotNull(dto.getOrderItemList()); + assertEquals(1, dto.getOrderItemList().size()); + assertEquals(Long.valueOf(1L), dto.getOrderItemList().get(0).getItemId()); + assertEquals("aa", dto.getOrderItemList().get(0).getProductName()); + assertEquals(Integer.valueOf(1), dto.getOrderItemList().get(0).getQuantity()); + } + + /** + * Test map conversion with protected setter bean + */ + @Test + public void issue4245MapConvertTest() { + final OrderItem4245 item = new OrderItem4245(1L, "aa", 1); + // Should not throw UnsupportedOperationException + final Map map = BeanUtil.beanToMap(item); + assertNotNull(map); + assertEquals(1L, map.get("itemId")); + assertEquals("aa", map.get("productName")); + assertEquals(1, map.get("quantity")); + } } From 079a8136d67c39f1c472df10cf32d04967ff5ccc Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 19 May 2026 21:42:54 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D`BeanConverter`?= =?UTF-8?q?=E5=92=8C`MapConverter`=E6=BA=90Bean=E5=88=A4=E6=96=AD=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=88pr#4252@Github=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9073bd72c..951e4f87e6 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.45(2026-05-14) +# 5.8.45(2026-05-19) ### 🐣新特性 * 【core 】 `AnnotationUtil`新增两级缓存架构,提升高频注解解析性能(pr#1434@Gitee) * 【core 】 `RegexPool.PLATE_NUMBER`新增粤AP号段支持(issue#IJNDJR@Gitee) @@ -13,6 +13,7 @@ * 【core 】 修复`JNDIUtil`远程加载漏洞(issue#4249@Github) * 【core 】 修复`ValidateObjectInputStream`白名单规则问题(issue#4249@Github) * 【core 】 修复`VersionUtil`比对null时结果异常问题(issue#IJNFQZ@Gitee) +* 【core 】 修复`BeanConverter`和`MapConverter`源Bean判断问题(pr#4252@Github) ------------------------------------------------------------------------------------------------------------- # 5.8.44(2026-03-11) From 84561772e14e84583869e69cfd1089a57d69da37 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 25 May 2026 15:52:18 +0800 Subject: [PATCH 10/11] prepare 5.8.46 --- CHANGELOG.md | 7 ++++++- README-EN.md | 6 +++--- README.md | 6 +++--- bin/version.txt | 2 +- docs/js/version.js | 2 +- hutool-ai/pom.xml | 2 +- hutool-all/pom.xml | 2 +- hutool-aop/pom.xml | 2 +- hutool-bloomFilter/pom.xml | 2 +- hutool-bom/pom.xml | 2 +- hutool-cache/pom.xml | 2 +- hutool-captcha/pom.xml | 2 +- hutool-core/pom.xml | 2 +- hutool-cron/pom.xml | 2 +- hutool-crypto/pom.xml | 2 +- hutool-db/pom.xml | 2 +- hutool-dfa/pom.xml | 2 +- hutool-extra/pom.xml | 2 +- hutool-http/pom.xml | 2 +- hutool-json/pom.xml | 2 +- hutool-jwt/pom.xml | 2 +- hutool-log/pom.xml | 2 +- hutool-poi/pom.xml | 2 +- hutool-script/pom.xml | 2 +- hutool-setting/pom.xml | 2 +- hutool-socket/pom.xml | 2 +- hutool-system/pom.xml | 2 +- pom.xml | 2 +- 28 files changed, 37 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 951e4f87e6..837246d0ae 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.45(2026-05-19) +# 5.8.46(2026-05-25) ### 🐣新特性 * 【core 】 `AnnotationUtil`新增两级缓存架构,提升高频注解解析性能(pr#1434@Gitee) * 【core 】 `RegexPool.PLATE_NUMBER`新增粤AP号段支持(issue#IJNDJR@Gitee) @@ -15,6 +15,11 @@ * 【core 】 修复`VersionUtil`比对null时结果异常问题(issue#IJNFQZ@Gitee) * 【core 】 修复`BeanConverter`和`MapConverter`源Bean判断问题(pr#4252@Github) +# 5.8.45(2026-05-19) +### 🐣新特性 +* 此版本发布出现问题,跳过! +### 🐞Bug修复 + ------------------------------------------------------------------------------------------------------------- # 5.8.44(2026-03-11) ### 🐣新特性 diff --git a/README-EN.md b/README-EN.md index 8724b132c7..e402d0248c 100755 --- a/README-EN.md +++ b/README-EN.md @@ -135,18 +135,18 @@ Each module can be introduced individually, or all modules can be introduced by cn.hutool hutool-all - 5.8.45 + 5.8.46 ``` ### 🍐Gradle ``` -implementation 'cn.hutool:hutool-all:5.8.45' +implementation 'cn.hutool:hutool-all:5.8.46' ``` ## 📥Download -- [Maven Repo](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.45/) +- [Maven Repo](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.46/) > 🔔️note: > Hutool 5.x supports JDK8+ and is not tested on Android platforms, and cannot guarantee that all tool classes or tool methods are available. diff --git a/README.md b/README.md index 3c3718bef3..d61597e2ae 100755 --- a/README.md +++ b/README.md @@ -125,20 +125,20 @@ Hutool = Hu + tool,是原公司项目底层代码剥离后的开源库,“Hu cn.hutool hutool-all - 5.8.45 + 5.8.46 ``` ### 🍐Gradle ``` -implementation 'cn.hutool:hutool-all:5.8.45' +implementation 'cn.hutool:hutool-all:5.8.46' ``` ### 📥下载jar 点击以下链接,下载`hutool-all-X.X.X.jar`即可: -- [Maven中央库](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.45/) +- [Maven中央库](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.46/) > 🔔️注意 > Hutool 5.x支持JDK8+,对Android平台没有测试,不能保证所有工具类或工具方法可用。 diff --git a/bin/version.txt b/bin/version.txt index 308d84bdbe..d09e11b30c 100755 --- a/bin/version.txt +++ b/bin/version.txt @@ -1 +1 @@ -5.8.45 +5.8.46 diff --git a/docs/js/version.js b/docs/js/version.js index 1db7f384e1..25746828a4 100755 --- a/docs/js/version.js +++ b/docs/js/version.js @@ -1 +1 @@ -var version = '5.8.45' \ No newline at end of file +var version = '5.8.46' \ No newline at end of file diff --git a/hutool-ai/pom.xml b/hutool-ai/pom.xml index 713f409a19..6b799c4446 100644 --- a/hutool-ai/pom.xml +++ b/hutool-ai/pom.xml @@ -6,7 +6,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-ai diff --git a/hutool-all/pom.xml b/hutool-all/pom.xml index f2cbe71991..35e87e43f5 100755 --- a/hutool-all/pom.xml +++ b/hutool-all/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-all diff --git a/hutool-aop/pom.xml b/hutool-aop/pom.xml index 51fb03579f..00e003bbac 100755 --- a/hutool-aop/pom.xml +++ b/hutool-aop/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-aop diff --git a/hutool-bloomFilter/pom.xml b/hutool-bloomFilter/pom.xml index fd35a7cc47..59e0ca5b3a 100755 --- a/hutool-bloomFilter/pom.xml +++ b/hutool-bloomFilter/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-bloomFilter diff --git a/hutool-bom/pom.xml b/hutool-bom/pom.xml index e002601ca6..e850d848c3 100755 --- a/hutool-bom/pom.xml +++ b/hutool-bom/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-bom diff --git a/hutool-cache/pom.xml b/hutool-cache/pom.xml index 01f4f613ac..1063003a69 100755 --- a/hutool-cache/pom.xml +++ b/hutool-cache/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-cache diff --git a/hutool-captcha/pom.xml b/hutool-captcha/pom.xml index 6e0195759c..d61ef67f3f 100755 --- a/hutool-captcha/pom.xml +++ b/hutool-captcha/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-captcha diff --git a/hutool-core/pom.xml b/hutool-core/pom.xml index 560da2a5ba..3ed56bd146 100755 --- a/hutool-core/pom.xml +++ b/hutool-core/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-core diff --git a/hutool-cron/pom.xml b/hutool-cron/pom.xml index 0028d316f5..2090849bf9 100755 --- a/hutool-cron/pom.xml +++ b/hutool-cron/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-cron diff --git a/hutool-crypto/pom.xml b/hutool-crypto/pom.xml index 3d7e460cf5..f39f49ce30 100755 --- a/hutool-crypto/pom.xml +++ b/hutool-crypto/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-crypto diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml index a626ceb9df..f0796cf64a 100755 --- a/hutool-db/pom.xml +++ b/hutool-db/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-db diff --git a/hutool-dfa/pom.xml b/hutool-dfa/pom.xml index 3af442c945..38125ddf20 100755 --- a/hutool-dfa/pom.xml +++ b/hutool-dfa/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-dfa diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index fcacebbe27..a707e42047 100755 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-extra diff --git a/hutool-http/pom.xml b/hutool-http/pom.xml index 61fb3a345d..651ee51d81 100755 --- a/hutool-http/pom.xml +++ b/hutool-http/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-http diff --git a/hutool-json/pom.xml b/hutool-json/pom.xml index a44ea04947..91cc5df6f2 100755 --- a/hutool-json/pom.xml +++ b/hutool-json/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-json diff --git a/hutool-jwt/pom.xml b/hutool-jwt/pom.xml index 9ec059aa2c..204825179a 100755 --- a/hutool-jwt/pom.xml +++ b/hutool-jwt/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-jwt diff --git a/hutool-log/pom.xml b/hutool-log/pom.xml index 2b66a523c1..676163a44f 100755 --- a/hutool-log/pom.xml +++ b/hutool-log/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-log diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml index 5d8148f875..156e1af4d7 100755 --- a/hutool-poi/pom.xml +++ b/hutool-poi/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-poi diff --git a/hutool-script/pom.xml b/hutool-script/pom.xml index eb187629ee..1d6b2b62d5 100755 --- a/hutool-script/pom.xml +++ b/hutool-script/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-script diff --git a/hutool-setting/pom.xml b/hutool-setting/pom.xml index 6a1ef3af8e..e51122794a 100755 --- a/hutool-setting/pom.xml +++ b/hutool-setting/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-setting diff --git a/hutool-socket/pom.xml b/hutool-socket/pom.xml index 26836e028b..9d11ffca39 100755 --- a/hutool-socket/pom.xml +++ b/hutool-socket/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-socket diff --git a/hutool-system/pom.xml b/hutool-system/pom.xml index 96abf37103..618491e79b 100755 --- a/hutool-system/pom.xml +++ b/hutool-system/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool-system diff --git a/pom.xml b/pom.xml index f91a6704dd..57815db934 100755 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 5.8.45-SNAPSHOT + 5.8.46-SNAPSHOT hutool Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。 https://github.com/chinabugotech/hutool From 80ef0ba2a218ac9010da067ac1924faaba8335d5 Mon Sep 17 00:00:00 2001 From: chinabugotech Date: Mon, 25 May 2026 16:53:38 +0800 Subject: [PATCH 11/11] release 5.8.46 --- hutool-ai/pom.xml | 2 +- hutool-all/pom.xml | 2 +- hutool-aop/pom.xml | 2 +- hutool-bloomFilter/pom.xml | 2 +- hutool-bom/pom.xml | 2 +- hutool-cache/pom.xml | 2 +- hutool-captcha/pom.xml | 2 +- hutool-core/pom.xml | 2 +- hutool-cron/pom.xml | 2 +- hutool-crypto/pom.xml | 2 +- hutool-db/pom.xml | 2 +- hutool-dfa/pom.xml | 2 +- hutool-extra/pom.xml | 2 +- hutool-http/pom.xml | 2 +- hutool-json/pom.xml | 2 +- hutool-jwt/pom.xml | 2 +- hutool-log/pom.xml | 2 +- hutool-poi/pom.xml | 2 +- hutool-script/pom.xml | 2 +- hutool-setting/pom.xml | 2 +- hutool-socket/pom.xml | 2 +- hutool-system/pom.xml | 2 +- pom.xml | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/hutool-ai/pom.xml b/hutool-ai/pom.xml index 6b799c4446..adf6ac2f32 100644 --- a/hutool-ai/pom.xml +++ b/hutool-ai/pom.xml @@ -6,7 +6,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-ai diff --git a/hutool-all/pom.xml b/hutool-all/pom.xml index 35e87e43f5..38b290a97e 100755 --- a/hutool-all/pom.xml +++ b/hutool-all/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-all diff --git a/hutool-aop/pom.xml b/hutool-aop/pom.xml index 00e003bbac..1fb998dee6 100755 --- a/hutool-aop/pom.xml +++ b/hutool-aop/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-aop diff --git a/hutool-bloomFilter/pom.xml b/hutool-bloomFilter/pom.xml index 59e0ca5b3a..7acdda3975 100755 --- a/hutool-bloomFilter/pom.xml +++ b/hutool-bloomFilter/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-bloomFilter diff --git a/hutool-bom/pom.xml b/hutool-bom/pom.xml index e850d848c3..491c712e3d 100755 --- a/hutool-bom/pom.xml +++ b/hutool-bom/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-bom diff --git a/hutool-cache/pom.xml b/hutool-cache/pom.xml index 1063003a69..defaa54a17 100755 --- a/hutool-cache/pom.xml +++ b/hutool-cache/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-cache diff --git a/hutool-captcha/pom.xml b/hutool-captcha/pom.xml index d61ef67f3f..2eabb09e14 100755 --- a/hutool-captcha/pom.xml +++ b/hutool-captcha/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-captcha diff --git a/hutool-core/pom.xml b/hutool-core/pom.xml index 3ed56bd146..546cfe641c 100755 --- a/hutool-core/pom.xml +++ b/hutool-core/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-core diff --git a/hutool-cron/pom.xml b/hutool-cron/pom.xml index 2090849bf9..ddbbbf1483 100755 --- a/hutool-cron/pom.xml +++ b/hutool-cron/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-cron diff --git a/hutool-crypto/pom.xml b/hutool-crypto/pom.xml index f39f49ce30..dee72ba366 100755 --- a/hutool-crypto/pom.xml +++ b/hutool-crypto/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-crypto diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml index f0796cf64a..de81d8e900 100755 --- a/hutool-db/pom.xml +++ b/hutool-db/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-db diff --git a/hutool-dfa/pom.xml b/hutool-dfa/pom.xml index 38125ddf20..47169504c8 100755 --- a/hutool-dfa/pom.xml +++ b/hutool-dfa/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-dfa diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index a707e42047..272f9f20ce 100755 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-extra diff --git a/hutool-http/pom.xml b/hutool-http/pom.xml index 651ee51d81..ae5f8d00ba 100755 --- a/hutool-http/pom.xml +++ b/hutool-http/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-http diff --git a/hutool-json/pom.xml b/hutool-json/pom.xml index 91cc5df6f2..9b32cf2f07 100755 --- a/hutool-json/pom.xml +++ b/hutool-json/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-json diff --git a/hutool-jwt/pom.xml b/hutool-jwt/pom.xml index 204825179a..bd20f8c406 100755 --- a/hutool-jwt/pom.xml +++ b/hutool-jwt/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-jwt diff --git a/hutool-log/pom.xml b/hutool-log/pom.xml index 676163a44f..40a9ddafbd 100755 --- a/hutool-log/pom.xml +++ b/hutool-log/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-log diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml index 156e1af4d7..4fc6533e6e 100755 --- a/hutool-poi/pom.xml +++ b/hutool-poi/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-poi diff --git a/hutool-script/pom.xml b/hutool-script/pom.xml index 1d6b2b62d5..8cd2f0e9c6 100755 --- a/hutool-script/pom.xml +++ b/hutool-script/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-script diff --git a/hutool-setting/pom.xml b/hutool-setting/pom.xml index e51122794a..2f34f65826 100755 --- a/hutool-setting/pom.xml +++ b/hutool-setting/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-setting diff --git a/hutool-socket/pom.xml b/hutool-socket/pom.xml index 9d11ffca39..0baf650648 100755 --- a/hutool-socket/pom.xml +++ b/hutool-socket/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-socket diff --git a/hutool-system/pom.xml b/hutool-system/pom.xml index 618491e79b..720d98c4fa 100755 --- a/hutool-system/pom.xml +++ b/hutool-system/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool-system diff --git a/pom.xml b/pom.xml index 57815db934..691c37ef38 100755 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 5.8.46-SNAPSHOT + 5.8.46 hutool Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。 https://github.com/chinabugotech/hutool