diff --git a/distribution/proxy/src/main/release-docs/LICENSE b/distribution/proxy/src/main/release-docs/LICENSE
index 3afa524a8fc4ca..3ec175e8aed761 100644
--- a/distribution/proxy/src/main/release-docs/LICENSE
+++ b/distribution/proxy/src/main/release-docs/LICENSE
@@ -258,11 +258,13 @@ The text of each license is the standard Apache 2.0 license.
httpcore5-h2 5.1.3: https://hc.apache.org/httpcomponents-core-5.1.x, Apache 2.0
httpcore5 5.1.3: https://hc.apache.org/httpcomponents-core-5.1.x, Apache 2.0
j2objc-annotations 1.3 https://github.com/google/j2objc/, Apache 2.0
- jackson-annotations 2.14.0: http://github.com/FasterXML/jackson, Apache 2.0
- jackson-core 2.14.0: http://github.com/FasterXML/jackson, Apache 2.0
- jackson-databind 2.14.0: http://github.com/FasterXML/jackson, Apache 2.0
- jackson-dataformat-yaml 2.14.0: http://github.com/FasterXML/jackson, Apache 2.0
- jackson-datatype-jsr310 2.14.0: http://github.com/FasterXML/jackson, Apache 2.0
+ jackson-annotations 2.16.0: http://github.com/FasterXML/jackson, Apache 2.0
+ jackson-core 2.16.0: http://github.com/FasterXML/jackson, Apache 2.0
+ jackson-databind 2.16.0: http://github.com/FasterXML/jackson, Apache 2.0
+ jackson-dataformat-xml 2.16.0: https://github.com/FasterXML/jackson-dataformat-xml, Apache 2.0
+ jackson-dataformat-yaml 2.16.0: http://github.com/FasterXML/jackson, Apache 2.0
+ jackson-datatype-jdk8 2.16.0: http://github.com/FasterXML/jackson-modules-java8, Apache 2.0
+ jackson-datatype-jsr310 2.16.0: http://github.com/FasterXML/jackson, Apache 2.0
jcl-over-slf4j 1.7.36: https://github.com/qos-ch/slf4j, Apache 2.0
jetcd-api 0.7.6: https://github.com/etcd-io/jetcd, Apache 2.0
jetcd-common 0.7.6: https://github.com/etcd-io/jetcd, Apache 2.0
@@ -336,17 +338,6 @@ The text of each license is also included at licenses/LICENSE-[project].txt.
jts-io-common 1.19.0: https://github.com/locationtech/jts, EDL 1.0
jts-core 1.19.0: https://github.com/locationtech/jts, EDL 1.0
-========================================================================
-EDL licenses
-========================================================================
-
-The following components are provided under the EDL License. See project link for details.
-The text of each license is also included at licenses/LICENSE-[project].txt.
-
- jakarta.activation-api 1.2.2: https://github.com/jakartaee/jaf-api, EDL 1.0
- jakarta.xml.bind-api 2.3.3: https://github.com/jakartaee/jaxb-api, EDL 1.0
- jaxb-runtime 2.3.9 https://eclipse-ee4j.github.io/jaxb-ri/, EDL 1.0
-
========================================================================
EPL licenses
========================================================================
diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/spring-boot/_index.cn.md b/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/spring-boot/_index.cn.md
index 36a4ef886708c6..88175b1a8578e1 100644
--- a/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/spring-boot/_index.cn.md
+++ b/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/spring-boot/_index.cn.md
@@ -35,16 +35,15 @@ spring.datasource.url=jdbc:shardingsphere:classpath:xxx.yaml
直接使用该数据源;或者将 ShardingSphereDataSource 配置在 JPA、Hibernate、MyBatis 等 ORM 框架中配合使用。
-## 针对 Spring Boot OSS 3 的特殊处理
+## 针对 Spring Boot OSS 3 的处理
Spring Boot OSS 3 对 Jakarta EE 和 Java 17 进行了 “大爆炸” 升级,涉及大量复杂情况。
-对于正在使用 Java EE 8 API 及其实现的 ShardingSphere JDBC 而言,如果用户希望在 Spring Boot OSS 3 等基于 Jakarta EE 9+ API 的 Web
-Framework 上使用 ShardingSphere JDBC,则需要引入 Java EE 8 的 JAXB 的实现。
-
-这在 Maven 的 `pom.xml` 体现为如下内容。你也可以使用其他的 JAXB API 的实现。此配置同样适用于其他基于 Jakarta EE 的 Web Framework,如
+ShardingSphere 的 XA 分布式事务尚未在 Spring Boot OSS 3 上就绪,此限制同样适用于其他基于 Jakarta EE 9+ 的 Web Framework,如
Quarkus 3,Micronaut Framework 4 和 Helidon 3。
+用户仅需要配置如下。
+
```xml
@@ -53,17 +52,10 @@ Quarkus 3,Micronaut Framework 4 和 Helidon 3。
shardingsphere-jdbc-core
${shardingsphere.version}
-
- org.glassfish.jaxb
- jaxb-runtime
- 2.3.9
-
```
-此外,ShardingSphere 的 XA 分布式事务尚未在 Spring Boot OSS 3 上就绪。
-
## 针对低版本的 Spring Boot OSS 2 的特殊处理
ShardingSphere 的所有特性均可在 Spring Boot OSS 2 上使用,但低版本的 Spring Boot OSS 可能需要手动指定 SnakeYAML 的版本为 2.2 。
diff --git a/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/spring-boot/_index.en.md b/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/spring-boot/_index.en.md
index cf7be453d13d8c..f2a502fa3ac5df 100644
--- a/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/spring-boot/_index.en.md
+++ b/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/spring-boot/_index.en.md
@@ -35,16 +35,14 @@ The YAML configuration file in 'spring.datasource.url' currently support in two
Use this data source directly; or configure ShardingSphereDataSource to be used in conjunction with ORM frameworks such as JPA, Hibernate, and MyBatis.
-## Special handling for Spring Boot OSS 3
+## Handling for Spring Boot OSS 3
Spring Boot OSS 3 has made a "big bang" upgrade to Jakarta EE and Java 17, with all complications involved.
-For ShardingSphere JDBC that is using the Java EE 8 API and its implementation, if you want to use ShardingSphere JDBC
-on a Jakarta EE 9+ API-based web framework such as Spring Boot OSS 3, you need to introduce a JAXB implementation of
-Java EE 8.
+ShardingSphere's XA distributed transactions are not yet ready on Spring Boot OSS 3. This limitation also applies to other
+Jakarta EE 9+ based Web Frameworks, such as Quarkus 3, Micronaut Framework 4 and Helidon 3.
-This is reflected in Maven's `pom.xml` as follows. You can also use other JAXB API implementations. This configuration
-also applies to other Jakarta EE-based Web Frameworks, such as Quarkus 3, Micronaut Framework 4 and Helidon 3.
+Users only need to configure as follows.
```xml
@@ -54,17 +52,10 @@ also applies to other Jakarta EE-based Web Frameworks, such as Quarkus 3, Micron
shardingsphere-jdbc-core
${shardingsphere.version}
-
- org.glassfish.jaxb
- jaxb-runtime
- 2.3.9
-
```
-In addition, ShardingSphere's XA distributed transactions are not yet ready on Spring Boot OSS 3.
-
## Special handling for earlier versions of Spring Boot OSS 2
All features of ShardingSphere are available on Spring Boot OSS 2, but earlier versions of Spring Boot OSS may require
diff --git a/docs/document/content/user-manual/shardingsphere-proxy/startup/dependencies-download/add_Narayana_dependency.cn.md b/docs/document/content/user-manual/shardingsphere-proxy/startup/dependencies-download/add_Narayana_dependency.cn.md
index b348f33662970d..24aa04948d8cdc 100644
--- a/docs/document/content/user-manual/shardingsphere-proxy/startup/dependencies-download/add_Narayana_dependency.cn.md
+++ b/docs/document/content/user-manual/shardingsphere-proxy/startup/dependencies-download/add_Narayana_dependency.cn.md
@@ -11,10 +11,6 @@ weight = 2
- [arjuna-5.12.4.Final.jar](https://repo1.maven.org/maven2/org/jboss/narayana/arjunacore/arjuna/5.12.4.Final/arjuna-5.12.4.Final.jar)
- [common-5.12.4.Final.jar](https://repo1.maven.org/maven2/org/jboss/narayana/common/5.12.4.Final/common-5.12.4.Final.jar)
-- [istack-commons-runtime-3.0.12.jar](https://repo1.maven.org/maven2/com/sun/istack/istack-commons-runtime/3.0.12/istack-commons-runtime-3.0.12.jar)
-- [jakarta.activation-api-1.2.2.jar](https://repo1.maven.org/maven2/jakarta/activation/jakarta.activation-api/1.2.2/jakarta.activation-api-1.2.2.jar)
-- [jakarta.xml.bind-api-2.3.3.jar](https://repo1.maven.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api/2.3.3/jakarta.xml.bind-api-2.3.3.jar)
-- [jaxb-runtime-2.3.9.jar](https://repo1.maven.org/maven2/org/glassfish/jaxb/jaxb-runtime/2.3.9/jaxb-runtime-2.3.9.jar)
- [jboss-connector-api_1.7_spec-1.0.0.Final.jar](https://repo1.maven.org/maven2/org/jboss/spec/javax/resource/jboss-connector-api_1.7_spec/1.0.0.Final/jboss-connector-api_1.7_spec-1.0.0.Final.jar)
- [jboss-logging-3.2.1.Final.jar](https://repo1.maven.org/maven2/org/jboss/logging/jboss-logging/3.2.1.Final/jboss-logging-3.2.1.Final.jar)
- [jboss-transaction-api_1.2_spec-1.0.0.Alpha3.jar](https://repo1.maven.org/maven2/org/jboss/spec/javax/transaction/jboss-transaction-api_1.2_spec/1.0.0.Alpha3/jboss-transaction-api_1.2_spec-1.0.0.Alpha3.jar)
@@ -22,6 +18,5 @@ weight = 2
- [jta-5.12.4.Final.jar](https://repo1.maven.org/maven2/org/jboss/narayana/jta/jta/5.12.4.Final/jta-5.12.4.Final.jar)
- [narayana-jts-integration-5.12.4.Final.jar](https://repo1.maven.org/maven2/org/jboss/narayana/jts/narayana-jts-integration/5.12.4.Final/narayana-jts-integration-5.12.4.Final.jar)
- [shardingsphere-transaction-xa-narayana.jar](https://mvnrepository.com/artifact/org.apache.shardingsphere/shardingsphere-transaction-xa-narayana)
-- [txw2-2.3.9.jar](https://repo1.maven.org/maven2/org/glassfish/jaxb/txw2/2.3.9/txw2-2.3.9.jar)
请根据 `proxy` 版本下载对应 `shardingsphere-transaction-xa-narayana.jar` 文件。
diff --git a/docs/document/content/user-manual/shardingsphere-proxy/startup/dependencies-download/add_Narayana_dependency.en.md b/docs/document/content/user-manual/shardingsphere-proxy/startup/dependencies-download/add_Narayana_dependency.en.md
index 8f357796fa6235..64aed2321f429c 100644
--- a/docs/document/content/user-manual/shardingsphere-proxy/startup/dependencies-download/add_Narayana_dependency.en.md
+++ b/docs/document/content/user-manual/shardingsphere-proxy/startup/dependencies-download/add_Narayana_dependency.en.md
@@ -11,10 +11,6 @@ Adding Narayana dependencies requires downloading the following jar files and ad
- [arjuna-5.12.4.Final.jar](https://repo1.maven.org/maven2/org/jboss/narayana/arjunacore/arjuna/5.12.4.Final/arjuna-5.12.4.Final.jar)
- [common-5.12.4.Final.jar](https://repo1.maven.org/maven2/org/jboss/narayana/common/5.12.4.Final/common-5.12.4.Final.jar)
-- [istack-commons-runtime-3.0.12.jar](https://repo1.maven.org/maven2/com/sun/istack/istack-commons-runtime/3.0.12/istack-commons-runtime-3.0.12.jar)
-- [jakarta.activation-api-1.2.2.jar](https://repo1.maven.org/maven2/jakarta/activation/jakarta.activation-api/1.2.2/jakarta.activation-api-1.2.2.jar)
-- [jakarta.xml.bind-api-2.3.3.jar](https://repo1.maven.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api/2.3.3/jakarta.xml.bind-api-2.3.3.jar)
-- [jaxb-runtime-2.3.9.jar](https://repo1.maven.org/maven2/org/glassfish/jaxb/jaxb-runtime/2.3.9/jaxb-runtime-2.3.9.jar)
- [jboss-connector-api_1.7_spec-1.0.0.Final.jar](https://repo1.maven.org/maven2/org/jboss/spec/javax/resource/jboss-connector-api_1.7_spec/1.0.0.Final/jboss-connector-api_1.7_spec-1.0.0.Final.jar)
- [jboss-logging-3.2.1.Final.jar](https://repo1.maven.org/maven2/org/jboss/logging/jboss-logging/3.2.1.Final/jboss-logging-3.2.1.Final.jar)
- [jboss-transaction-api_1.2_spec-1.0.0.Alpha3.jar](https://repo1.maven.org/maven2/org/jboss/spec/javax/transaction/jboss-transaction-api_1.2_spec/1.0.0.Alpha3/jboss-transaction-api_1.2_spec-1.0.0.Alpha3.jar)
@@ -22,6 +18,5 @@ Adding Narayana dependencies requires downloading the following jar files and ad
- [jta-5.12.4.Final.jar](https://repo1.maven.org/maven2/org/jboss/narayana/jta/jta/5.12.4.Final/jta-5.12.4.Final.jar)
- [narayana-jts-integration-5.12.4.Final.jar](https://repo1.maven.org/maven2/org/jboss/narayana/jts/narayana-jts-integration/5.12.4.Final/narayana-jts-integration-5.12.4.Final.jar)
- [shardingsphere-transaction-xa-narayana.jar](https://mvnrepository.com/artifact/org.apache.shardingsphere/shardingsphere-transaction-xa-narayana)
-- [txw2-2.3.9.jar](https://repo1.maven.org/maven2/org/glassfish/jaxb/txw2/2.3.9/txw2-2.3.9.jar)
Please download the corresponding `shardingsphere-transaction-xa-narayana.jar` file according to the `proxy` version.
diff --git a/infra/util/pom.xml b/infra/util/pom.xml
index cfa62de778df27..78a15331b4c176 100644
--- a/infra/util/pom.xml
+++ b/infra/util/pom.xml
@@ -44,7 +44,10 @@
com.fasterxml.jackson.datatype
jackson-datatype-jsr310
- ${jackson.version}
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jdk8
diff --git a/kernel/transaction/type/xa/provider/narayana/pom.xml b/kernel/transaction/type/xa/provider/narayana/pom.xml
index e4c885b93ada81..0a9ab30d458198 100644
--- a/kernel/transaction/type/xa/provider/narayana/pom.xml
+++ b/kernel/transaction/type/xa/provider/narayana/pom.xml
@@ -57,18 +57,5 @@
${jboss-logging.version}
provided
-
-
- jakarta.xml.bind
- jakarta.xml.bind-api
-
-
- org.glassfish.jaxb
- jaxb-runtime
-
-
- jakarta.activation
- jakarta.activation-api
-
diff --git a/mode/type/standalone/repository/provider/jdbc/pom.xml b/mode/type/standalone/repository/provider/jdbc/pom.xml
index e3f6186772baf5..c1574048988970 100644
--- a/mode/type/standalone/repository/provider/jdbc/pom.xml
+++ b/mode/type/standalone/repository/provider/jdbc/pom.xml
@@ -41,16 +41,8 @@
- jakarta.xml.bind
- jakarta.xml.bind-api
-
-
- org.glassfish.jaxb
- jaxb-runtime
-
-
- jakarta.activation
- jakarta.activation-api
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-xml
com.zaxxer
diff --git a/mode/type/standalone/repository/provider/jdbc/src/main/java/org/apache/shardingsphere/mode/repository/standalone/jdbc/sql/JDBCRepositorySQL.java b/mode/type/standalone/repository/provider/jdbc/src/main/java/org/apache/shardingsphere/mode/repository/standalone/jdbc/sql/JDBCRepositorySQL.java
index d4369adf9b10a1..06a934555d4144 100644
--- a/mode/type/standalone/repository/provider/jdbc/src/main/java/org/apache/shardingsphere/mode/repository/standalone/jdbc/sql/JDBCRepositorySQL.java
+++ b/mode/type/standalone/repository/provider/jdbc/src/main/java/org/apache/shardingsphere/mode/repository/standalone/jdbc/sql/JDBCRepositorySQL.java
@@ -17,43 +17,41 @@
package org.apache.shardingsphere.mode.repository.standalone.jdbc.sql;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Getter;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-
/**
* JDBC repository SQL.
*/
-@XmlRootElement(name = "sql")
+@JacksonXmlRootElement(localName = "sql")
@Getter
public final class JDBCRepositorySQL {
- @XmlAttribute(required = true)
+ @JacksonXmlProperty(isAttribute = true)
private String type;
- @XmlAttribute(name = "driver-class-name", required = true)
+ @JacksonXmlProperty(localName = "driver-class-name", isAttribute = true)
private String driverClassName;
- @XmlAttribute(name = "default")
+ @JacksonXmlProperty(localName = "default", isAttribute = true)
private boolean isDefault;
- @XmlElement(name = "create-table", required = true)
+ @JacksonXmlProperty(localName = "create-table")
private String createTableSQL;
- @XmlElement(name = "select-by-key", required = true)
+ @JacksonXmlProperty(localName = "select-by-key")
private String selectByKeySQL;
- @XmlElement(name = "select-by-parent", required = true)
+ @JacksonXmlProperty(localName = "select-by-parent")
private String selectByParentKeySQL;
- @XmlElement(name = "insert", required = true)
+ @JacksonXmlProperty(localName = "insert")
private String insertSQL;
- @XmlElement(name = "update", required = true)
+ @JacksonXmlProperty(localName = "update")
private String updateSQL;
- @XmlElement(name = "delete", required = true)
+ @JacksonXmlProperty(localName = "delete")
private String deleteSQL;
}
diff --git a/mode/type/standalone/repository/provider/jdbc/src/main/java/org/apache/shardingsphere/mode/repository/standalone/jdbc/sql/JDBCRepositorySQLLoader.java b/mode/type/standalone/repository/provider/jdbc/src/main/java/org/apache/shardingsphere/mode/repository/standalone/jdbc/sql/JDBCRepositorySQLLoader.java
index 2d7ea1cb9a7d49..ca3f145e3c1837 100644
--- a/mode/type/standalone/repository/provider/jdbc/src/main/java/org/apache/shardingsphere/mode/repository/standalone/jdbc/sql/JDBCRepositorySQLLoader.java
+++ b/mode/type/standalone/repository/provider/jdbc/src/main/java/org/apache/shardingsphere/mode/repository/standalone/jdbc/sql/JDBCRepositorySQLLoader.java
@@ -17,12 +17,12 @@
package org.apache.shardingsphere.mode.repository.standalone.jdbc.sql;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
@@ -58,13 +58,15 @@ public final class JDBCRepositorySQLLoader {
private static final Collection JAR_URL_PROTOCOLS = new HashSet<>(Arrays.asList("jar", "war", "zip", "wsjar", "vfszip"));
+ private static final ObjectMapper XML_MAPPER = new XmlMapper();
+
/**
* Load JDBC repository SQL.
*
* @param type type of JDBC repository SQL
* @return loaded JDBC repository SQL
*/
- @SneakyThrows({JAXBException.class, IOException.class, URISyntaxException.class})
+ @SneakyThrows({IOException.class, URISyntaxException.class})
public static JDBCRepositorySQL load(final String type) {
Enumeration resources = Thread.currentThread().getContextClassLoader().getResources(ROOT_DIRECTORY);
if (null == resources) {
@@ -126,11 +128,11 @@ private static JDBCRepositorySQL loadFromDirectoryInNativeImage(final URL url, f
final JDBCRepositorySQL[] result = new JDBCRepositorySQL[1];
Files.walkFileTree(Paths.get(url.toURI()), new SimpleFileVisitor() {
- @SneakyThrows(JAXBException.class)
@Override
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attributes) throws IOException {
if (file.toString().endsWith(FILE_EXTENSION)) {
- JDBCRepositorySQL provider = (JDBCRepositorySQL) JAXBContext.newInstance(JDBCRepositorySQL.class).createUnmarshaller().unmarshal(Files.newInputStream(file.toAbsolutePath()));
+ InputStream inputStream = Files.newInputStream(file.toAbsolutePath());
+ JDBCRepositorySQL provider = XML_MAPPER.readValue(inputStream, JDBCRepositorySQL.class);
if (provider.isDefault()) {
result[0] = provider;
}
@@ -149,11 +151,11 @@ private static JDBCRepositorySQL loadFromDirectoryLegacy(final URL url, final St
final JDBCRepositorySQL[] result = new JDBCRepositorySQL[1];
Files.walkFileTree(Paths.get(url.toURI()), new SimpleFileVisitor() {
- @SneakyThrows(JAXBException.class)
@Override
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attributes) throws IOException {
if (file.toString().endsWith(FILE_EXTENSION)) {
- JDBCRepositorySQL provider = (JDBCRepositorySQL) JAXBContext.newInstance(JDBCRepositorySQL.class).createUnmarshaller().unmarshal(Files.newInputStream(file.toFile().toPath()));
+ InputStream inputStream = Files.newInputStream(file.toFile().toPath());
+ JDBCRepositorySQL provider = XML_MAPPER.readValue(inputStream, JDBCRepositorySQL.class);
if (provider.isDefault()) {
result[0] = provider;
}
@@ -168,7 +170,7 @@ public FileVisitResult visitFile(final Path file, final BasicFileAttributes attr
return result[0];
}
- private static JDBCRepositorySQL loadFromJar(final URL url, final String type) throws JAXBException, IOException {
+ private static JDBCRepositorySQL loadFromJar(final URL url, final String type) throws IOException {
JDBCRepositorySQL result = null;
try (JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile()) {
Enumeration entries = jar.entries();
@@ -178,7 +180,7 @@ private static JDBCRepositorySQL loadFromJar(final URL url, final String type) t
continue;
}
final InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(name);
- JDBCRepositorySQL provider = (JDBCRepositorySQL) JAXBContext.newInstance(JDBCRepositorySQL.class).createUnmarshaller().unmarshal(inputStream);
+ JDBCRepositorySQL provider = XML_MAPPER.readValue(inputStream, JDBCRepositorySQL.class);
if (provider.isDefault()) {
result = provider;
}
diff --git a/pom.xml b/pom.xml
index beba730a3d706f..1ab85e0ac2d72c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -78,7 +78,7 @@
4.10.1
2.2
2.10.1
- 2.14.0
+ 2.16.0
2.8.0
2.4.10
2.4.9