You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@seatunnel.apache.org by ga...@apache.org on 2022/01/08 06:15:26 UTC

[incubator-seatunnel] branch dev updated: [SeaTunnel #904] [config] improve the config module by shade plugin (#906)

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

gaoyingju pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-seatunnel.git


The following commit(s) were added to refs/heads/dev by this push:
     new 7655ff8  [SeaTunnel #904] [config] improve the config module by shade plugin (#906)
7655ff8 is described below

commit 7655ff8a5f95000074891a7a123e6fd382c5a39d
Author: leo65535 <le...@163.com>
AuthorDate: Sat Jan 8 14:15:20 2022 +0800

    [SeaTunnel #904] [config] improve the config module by shade plugin (#906)
---
 pom.xml                                            |   21 +-
 .../java/org/apache/seatunnel/plugin/Plugin.java   |    2 +-
 .../apache/seatunnel/flink/FlinkEnvironment.java   |    2 +-
 .../seatunnel/flink/batch/FlinkBatchExecution.java |    2 +-
 .../flink/stream/FlinkStreamExecution.java         |    2 +-
 .../seatunnel/flink/util/EnvironmentUtil.java      |    2 +-
 .../apache/seatunnel/flink/util/SchemaUtil.java    |    4 +-
 .../org/apache/seatunnel/spark/BaseSparkSink.scala |    2 +-
 .../apache/seatunnel/spark/BaseSparkSource.scala   |    2 +-
 .../seatunnel/spark/BaseSparkTransform.scala       |    2 +-
 .../apache/seatunnel/spark/SparkEnvironment.scala  |    2 +-
 .../spark/batch/SparkBatchExecution.scala          |    2 +-
 .../spark/stream/SparkStreamingExecution.scala     |    2 +-
 .../StructuredStreamingExecution.scala             |    2 +-
 .../apache/seatunnel/common/PropertiesUtil.java    |    2 +-
 .../seatunnel/common/config/CheckConfigUtil.java   |    2 +-
 .../common/config/TypesafeConfigUtils.java         |    6 +-
 seatunnel-config/HOCON.md                          | 1625 --------------------
 seatunnel-config/README.md                         |  930 -----------
 seatunnel-config/pom.xml                           |   88 ++
 .../typesafe}/config/ConfigParseOptions.java       |   42 +-
 .../typesafe}/config/impl/ConfigNodePath.java      |   10 +-
 .../typesafe}/config/impl/ConfigParser.java        |   94 +-
 .../typesafe}/config/impl/PathParser.java          |   50 +-
 .../java/org/apache/seatunnel/config/Config.java   | 1016 ------------
 .../apache/seatunnel/config/ConfigBeanFactory.java |   62 -
 .../apache/seatunnel/config/ConfigException.java   |  436 ------
 .../org/apache/seatunnel/config/ConfigFactory.java | 1016 ------------
 .../seatunnel/config/ConfigIncludeContext.java     |   67 -
 .../apache/seatunnel/config/ConfigIncluder.java    |   62 -
 .../seatunnel/config/ConfigIncluderClasspath.java  |   37 -
 .../seatunnel/config/ConfigIncluderFile.java       |   39 -
 .../apache/seatunnel/config/ConfigIncluderURL.java |   39 -
 .../org/apache/seatunnel/config/ConfigList.java    |   61 -
 .../seatunnel/config/ConfigLoadingStrategy.java    |   37 -
 .../apache/seatunnel/config/ConfigMemorySize.java  |   79 -
 .../apache/seatunnel/config/ConfigMergeable.java   |   85 -
 .../org/apache/seatunnel/config/ConfigObject.java  |  143 --
 .../org/apache/seatunnel/config/ConfigOrigin.java  |  129 --
 .../seatunnel/config/ConfigOriginFactory.java      |   81 -
 .../apache/seatunnel/config/ConfigParseable.java   |   59 -
 .../seatunnel/config/ConfigRenderOptions.java      |  197 ---
 .../seatunnel/config/ConfigResolveOptions.java     |  188 ---
 .../apache/seatunnel/config/ConfigResolver.java    |   56 -
 .../org/apache/seatunnel/config/ConfigSyntax.java  |   49 -
 .../org/apache/seatunnel/config/ConfigUtil.java    |   92 --
 .../org/apache/seatunnel/config/ConfigValue.java   |  133 --
 .../seatunnel/config/ConfigValueFactory.java       |  165 --
 .../apache/seatunnel/config/ConfigValueType.java   |   26 -
 .../config/DefaultConfigLoadingStrategy.java       |   82 -
 .../java/org/apache/seatunnel/config/Optional.java |   31 -
 .../seatunnel/config/impl/AbstractConfigNode.java  |   46 -
 .../config/impl/AbstractConfigNodeValue.java       |   25 -
 .../config/impl/AbstractConfigObject.java          |  233 ---
 .../seatunnel/config/impl/AbstractConfigValue.java |  425 -----
 .../seatunnel/config/impl/ConfigBeanImpl.java      |  342 ----
 .../seatunnel/config/impl/ConfigBoolean.java       |   61 -
 .../seatunnel/config/impl/ConfigConcatenation.java |  311 ----
 .../seatunnel/config/impl/ConfigDelayedMerge.java  |  376 -----
 .../config/impl/ConfigDelayedMergeObject.java      |  342 ----
 .../config/impl/ConfigDocumentParser.java          |  719 ---------
 .../apache/seatunnel/config/impl/ConfigDouble.java |   75 -
 .../apache/seatunnel/config/impl/ConfigImpl.java   |  489 ------
 .../seatunnel/config/impl/ConfigImplUtil.java      |  260 ----
 .../seatunnel/config/impl/ConfigIncludeKind.java   |   22 -
 .../apache/seatunnel/config/impl/ConfigInt.java    |   75 -
 .../apache/seatunnel/config/impl/ConfigLong.java   |   75 -
 .../seatunnel/config/impl/ConfigNodeArray.java     |   31 -
 .../config/impl/ConfigNodeComplexValue.java        |   67 -
 .../config/impl/ConfigNodeConcatenation.java       |   31 -
 .../seatunnel/config/impl/ConfigNodeField.java     |   92 --
 .../seatunnel/config/impl/ConfigNodeInclude.java   |   63 -
 .../seatunnel/config/impl/ConfigNodeObject.java    |  305 ----
 .../seatunnel/config/impl/ConfigNodeRoot.java      |   85 -
 .../config/impl/ConfigNodeSimpleValue.java         |   56 -
 .../config/impl/ConfigNodeSingleToken.java         |   38 -
 .../apache/seatunnel/config/impl/ConfigNull.java   |   71 -
 .../apache/seatunnel/config/impl/ConfigNumber.java |  121 --
 .../seatunnel/config/impl/ConfigReference.java     |  185 ---
 .../apache/seatunnel/config/impl/ConfigString.java |  108 --
 .../apache/seatunnel/config/impl/Container.java    |   41 -
 .../seatunnel/config/impl/DefaultTransformer.java  |  145 --
 .../apache/seatunnel/config/impl/FromMapMode.java  |   22 -
 .../apache/seatunnel/config/impl/FullIncluder.java |   28 -
 .../org/apache/seatunnel/config/impl/MemoKey.java  |   61 -
 .../seatunnel/config/impl/MergeableValue.java      |   26 -
 .../apache/seatunnel/config/impl/OriginType.java   |   26 -
 .../apache/seatunnel/config/impl/Parseable.java    |  933 -----------
 .../org/apache/seatunnel/config/impl/Path.java     |  250 ---
 .../apache/seatunnel/config/impl/PathBuilder.java  |   75 -
 .../seatunnel/config/impl/PropertiesParser.java    |  225 ---
 .../config/impl/ReplaceableMergeStack.java         |   31 -
 .../seatunnel/config/impl/ResolveContext.java      |  273 ----
 .../apache/seatunnel/config/impl/ResolveMemos.java |   52 -
 .../seatunnel/config/impl/ResolveResult.java       |   61 -
 .../seatunnel/config/impl/ResolveSource.java       |  363 -----
 .../seatunnel/config/impl/ResolveStatus.java       |   41 -
 .../config/impl/SerializedConfigValue.java         |  556 -------
 .../apache/seatunnel/config/impl/SimpleConfig.java | 1174 --------------
 .../config/impl/SimpleConfigDocument.java          |   86 --
 .../seatunnel/config/impl/SimpleConfigList.java    |  477 ------
 .../seatunnel/config/impl/SimpleConfigObject.java  |  695 ---------
 .../seatunnel/config/impl/SimpleConfigOrigin.java  |  602 --------
 .../config/impl/SimpleIncludeContext.java          |   66 -
 .../seatunnel/config/impl/SimpleIncluder.java      |  310 ----
 .../config/impl/SubstitutionExpression.java        |   65 -
 .../org/apache/seatunnel/config/impl/Token.java    |  102 --
 .../apache/seatunnel/config/impl/TokenType.java    |   38 -
 .../apache/seatunnel/config/impl/Tokenizer.java    |  703 ---------
 .../org/apache/seatunnel/config/impl/Tokens.java   |  526 -------
 .../apache/seatunnel/config/impl/Unmergeable.java  |   30 -
 .../org/apache/seatunnel/config/impl/package.html  |   43 -
 .../java/org/apache/seatunnel/config/package.html  |   87 --
 .../seatunnel/config/parser/ConfigDocument.java    |  101 --
 .../config/parser/ConfigDocumentFactory.java       |  104 --
 .../apache/seatunnel/config/parser/ConfigNode.java |   49 -
 .../org/apache/seatunnel/config/CompleteTest.java  |   47 +
 .../org/apache/seatunnel/config/CompleteTests.java |   51 -
 .../apache/seatunnel/config/ConfigFactoryTest.java |   69 +
 .../seatunnel/config/beanconfig/ArraysConfig.java  |  156 --
 .../config/beanconfig/BooleansConfig.java          |   75 -
 .../seatunnel/config/beanconfig/BytesConfig.java   |   51 -
 .../DifferentFieldNameFromAccessorsConfig.java     |   40 -
 .../config/beanconfig/DurationsConfig.java         |   50 -
 .../seatunnel/config/beanconfig/EnumsConfig.java   |   83 -
 .../config/beanconfig/NotABeanFieldConfig.java     |   35 -
 .../seatunnel/config/beanconfig/NumbersConfig.java |   76 -
 .../seatunnel/config/beanconfig/ObjectsConfig.java |   83 -
 .../config/beanconfig/PreferCamelNamesConfig.java  |   40 -
 .../seatunnel/config/beanconfig/SetsConfig.java    |  156 --
 .../seatunnel/config/beanconfig/StringsConfig.java |   61 -
 .../config/beanconfig/TestBeanConfig.java          |   31 -
 .../beanconfig/UnsupportedListElementConfig.java   |   33 -
 .../config/beanconfig/UnsupportedMapKeyConfig.java |   33 -
 .../beanconfig/UnsupportedMapValueConfig.java      |   33 -
 .../config/beanconfig/ValidationBeanConfig.java    |   61 -
 .../seatunnel/config/beanconfig/ValuesConfig.java  |   85 -
 .../apache/seatunnel/config/utils/FileUtils.java}  |   26 +-
 seatunnel-config/src/test/resources/a_1.conf       |   16 -
 seatunnel-config/src/test/resources/b_2.conf       |   16 -
 seatunnel-config/src/test/resources/bom.conf       |   16 -
 seatunnel-config/src/test/resources/cycle.conf     |   16 -
 .../src/test/resources/equiv01/comments.conf       |   60 -
 .../src/test/resources/equiv01/equals.conf         |   56 -
 .../src/test/resources/equiv01/no-commas.conf      |   70 -
 .../src/test/resources/equiv01/no-root-braces.conf |   55 -
 .../src/test/resources/equiv01/no-whitespace.json  |    1 -
 .../src/test/resources/equiv01/omit-colons.conf    |   59 -
 .../src/test/resources/equiv01/original.json       |   41 -
 .../src/test/resources/equiv01/path-keys.conf      |   44 -
 .../test/resources/equiv01/properties-style.conf   |   52 -
 .../src/test/resources/equiv01/substitutions.conf  |   56 -
 .../src/test/resources/equiv01/unquoted.conf       |   56 -
 .../src/test/resources/equiv02/original.json       |   17 -
 .../src/test/resources/equiv02/path-keys.conf      |   24 -
 .../src/test/resources/equiv03/includes.conf       |   22 -
 .../src/test/resources/equiv03/letters/a.conf      |   21 -
 .../src/test/resources/equiv03/letters/b.json      |    3 -
 .../src/test/resources/equiv03/letters/c.conf      |   17 -
 .../test/resources/equiv03/letters/c.properties    |   15 -
 .../test/resources/equiv03/letters/numbers/1.conf  |   16 -
 .../resources/equiv03/letters/numbers/2.properties |   15 -
 .../src/test/resources/equiv03/original.json       |   15 -
 .../src/test/resources/equiv03/root/foo.conf       |   16 -
 .../resources/equiv04/missing-substitutions.conf   |   19 -
 .../src/test/resources/equiv04/original.json       |    3 -
 .../src/test/resources/equiv05/original.json       |   16 -
 .../src/test/resources/equiv05/triple-quotes.conf  |   35 -
 .../config.conf}                                   |   57 +-
 .../src/test/resources/file-include.conf           |   20 -
 .../src/test/resources/include-from-list.conf      |   20 -
 .../src/test/resources/onclasspath.conf            |   17 -
 .../seatunnel/config/beanconfig/beanconfig01.conf  |  146 --
 .../src/test/resources/seatunnel/variables.conf    |    6 +-
 .../src/test/resources/subdir/bar-file.conf        |   16 -
 .../src/test/resources/subdir/bar.conf             |   16 -
 .../src/test/resources/subdir/baz.conf             |   16 -
 .../src/test/resources/subdir/foo.conf             |   20 -
 seatunnel-config/src/test/resources/test01.conf    |  109 --
 seatunnel-config/src/test/resources/test01.json    |    4 -
 .../src/test/resources/test01.properties           |   18 -
 seatunnel-config/src/test/resources/test02.conf    |   28 -
 .../src/test/resources/test03-included.conf        |   24 -
 seatunnel-config/src/test/resources/test03.conf    |   51 -
 seatunnel-config/src/test/resources/test04.conf    |  320 ----
 seatunnel-config/src/test/resources/test05.conf    |  169 --
 seatunnel-config/src/test/resources/test06.conf    |   29 -
 seatunnel-config/src/test/resources/test07.conf    |   19 -
 seatunnel-config/src/test/resources/test08.conf    |   21 -
 seatunnel-config/src/test/resources/test09.conf    |   32 -
 seatunnel-config/src/test/resources/test10.conf    |   26 -
 seatunnel-config/src/test/resources/test11.conf    |   22 -
 .../src/test/resources/validate-invalid.conf       |   45 -
 .../src/test/resources/validate-reference.conf     |   47 -
 .../apache/seatunnel/flink/sink/ConsoleSink.java   |    2 +-
 .../org/apache/seatunnel/flink/sink/DorisSink.java |    2 +-
 .../apache/seatunnel/flink/source/DruidSource.java |    2 +-
 .../apache/seatunnel/flink/sink/Elasticsearch.java |    4 +-
 .../flink/sink/ElasticsearchOutputFormat.java      |    2 +-
 .../seatunnel/flink/source/FakeSourceStream.java   |    2 +-
 .../org/apache/seatunnel/flink/sink/FileSink.java  |    2 +-
 .../apache/seatunnel/flink/source/FileSource.java  |    2 +-
 .../org/apache/seatunnel/flink/sink/JdbcSink.java  |    2 +-
 .../apache/seatunnel/flink/source/JdbcSource.java  |    2 +-
 .../apache/seatunnel/flink/sink/KafkaTable.java    |    2 +-
 .../seatunnel/flink/source/KafkaTableStream.java   |    2 +-
 .../seatunnel/flink/source/SocketStream.java       |    2 +-
 .../apache/seatunnel/spark/sink/Clickhouse.scala   |    2 +-
 .../org/apache/seatunnel/spark/sink/Console.scala  |    2 +-
 .../seatunnel/spark/sink/Elasticsearch.scala       |    2 +-
 .../apache/seatunnel/spark/source/FakeStream.scala |    2 +-
 .../apache/seatunnel/spark/sink/FileSinkBase.scala |    2 +-
 .../org/apache/seatunnel/spark/sink/Hbase.scala    |    2 +-
 .../org/apache/seatunnel/spark/sink/Hudi.scala     |    2 +-
 .../org/apache/seatunnel/spark/sink/Jdbc.scala     |    2 +-
 .../org/apache/seatunnel/spark/sink/Kafka.scala    |    2 +-
 .../seatunnel/spark/source/KafkaStream.scala       |    2 +-
 .../seatunnel/spark/source/SocketStream.scala      |    2 +-
 .../org/apache/seatunnel/config/ConfigBuilder.java |    4 +
 .../apache/seatunnel/config/ExposeSparkConf.java   |    5 +
 .../flink/transform/DataStreamToTable.java         |    2 +-
 .../apache/seatunnel/flink/transform/Split.java    |    2 +-
 .../org/apache/seatunnel/flink/transform/Sql.java  |    2 +-
 .../flink/transform/TableToDataStream.java         |    2 +-
 .../apache/seatunnel/spark/transform/Json.scala    |    2 +-
 .../apache/seatunnel/spark/transform/Split.scala   |    2 +-
 tools/checkstyle/checkStyle.xml                    |    5 +-
 227 files changed, 446 insertions(+), 24132 deletions(-)

diff --git a/pom.xml b/pom.xml
index 9ccf8be..c36284b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,7 +88,6 @@
         <maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
         <scala-maven-plugin.version>3.3.1</scala-maven-plugin.version>
         <maven-compiler-plugin.version>2.0.2</maven-compiler-plugin.version>
-        <maven-shade-plugin.version>2.4.3</maven-shade-plugin.version>
         <maven-pmd-plugin.version>3.8</maven-pmd-plugin.version>
         <spoiwo.version>1.8.0</spoiwo.version>
         <play-mailer.version>7.0.2</play-mailer.version>
@@ -117,6 +116,9 @@
         <jcommander.version>1.81</jcommander.version>
         <junit.version>4.13.2</junit.version>
         <calcite-druid.version>1.29.0</calcite-druid.version>
+        <config.version>1.3.3</config.version>
+        <maven-shade-plugin.version>3.2.4</maven-shade-plugin.version>
+        <maven-helper-plugin.version>3.2.0</maven-helper-plugin.version>
     </properties>
 
     <dependencyManagement>
@@ -408,6 +410,11 @@
                 <artifactId>calcite-druid</artifactId>
                 <version>${calcite-druid.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.typesafe</groupId>
+                <artifactId>config</artifactId>
+                <version>${config.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
@@ -737,6 +744,18 @@
                     </executions>
                 </plugin>
                 <!-- maven deploy (End) -->
+
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-shade-plugin</artifactId>
+                    <version>${maven-shade-plugin.version}</version>
+                </plugin>
+
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>build-helper-maven-plugin</artifactId>
+                    <version>${maven-helper-plugin.version}</version>
+                </plugin>
             </plugins>
         </pluginManagement>
 
diff --git a/seatunnel-apis/seatunnel-api-base/src/main/java/org/apache/seatunnel/plugin/Plugin.java b/seatunnel-apis/seatunnel-api-base/src/main/java/org/apache/seatunnel/plugin/Plugin.java
index d30af51..ac4d5e0 100644
--- a/seatunnel-apis/seatunnel-api-base/src/main/java/org/apache/seatunnel/plugin/Plugin.java
+++ b/seatunnel-apis/seatunnel-api-base/src/main/java/org/apache/seatunnel/plugin/Plugin.java
@@ -17,7 +17,7 @@
 
 package org.apache.seatunnel.plugin;
 
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
 import org.apache.seatunnel.common.config.CheckResult;
 
 import java.io.Serializable;
diff --git a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/FlinkEnvironment.java b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/FlinkEnvironment.java
index 22dec68..428b0b7 100644
--- a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/FlinkEnvironment.java
+++ b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/FlinkEnvironment.java
@@ -17,7 +17,7 @@
 
 package org.apache.seatunnel.flink;
 
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
 import org.apache.seatunnel.env.RuntimeEnv;
 import org.apache.seatunnel.flink.util.ConfigKeyName;
 import org.apache.seatunnel.flink.util.EnvironmentUtil;
diff --git a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/batch/FlinkBatchExecution.java b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/batch/FlinkBatchExecution.java
index a6faa08..18bb8cd 100644
--- a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/batch/FlinkBatchExecution.java
+++ b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/batch/FlinkBatchExecution.java
@@ -17,7 +17,7 @@
 
 package org.apache.seatunnel.flink.batch;
 
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
 import org.apache.seatunnel.env.Execution;
 import org.apache.seatunnel.flink.FlinkEnvironment;
 import org.apache.seatunnel.flink.util.TableUtil;
diff --git a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/stream/FlinkStreamExecution.java b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/stream/FlinkStreamExecution.java
index f91b76d..ee5a361 100644
--- a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/stream/FlinkStreamExecution.java
+++ b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/stream/FlinkStreamExecution.java
@@ -17,7 +17,7 @@
 
 package org.apache.seatunnel.flink.stream;
 
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
 import org.apache.seatunnel.env.Execution;
 import org.apache.seatunnel.flink.FlinkEnvironment;
 import org.apache.seatunnel.flink.util.TableUtil;
diff --git a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/EnvironmentUtil.java b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/EnvironmentUtil.java
index 6e515ed..9e21b0f 100644
--- a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/EnvironmentUtil.java
+++ b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/EnvironmentUtil.java
@@ -17,7 +17,7 @@
 
 package org.apache.seatunnel.flink.util;
 
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
 import org.apache.seatunnel.common.config.CheckResult;
 import org.apache.flink.api.common.ExecutionConfig;
 import org.apache.flink.api.common.restartstrategy.RestartStrategies;
diff --git a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/SchemaUtil.java b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/SchemaUtil.java
index 9a71834..1b8cb4b 100644
--- a/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/SchemaUtil.java
+++ b/seatunnel-apis/seatunnel-api-flink/src/main/java/org/apache/seatunnel/flink/util/SchemaUtil.java
@@ -19,8 +19,8 @@ package org.apache.seatunnel.flink.util;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import org.apache.seatunnel.config.Config;
-import org.apache.seatunnel.config.ConfigValue;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.ConfigValue;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.flink.api.common.typeinfo.TypeInformation;
 import org.apache.flink.api.java.typeutils.ObjectArrayTypeInfo;
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSink.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSink.scala
index aef5e05..fc8cf17 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSink.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSink.scala
@@ -17,7 +17,7 @@
 package org.apache.seatunnel.spark
 
 import org.apache.seatunnel.apis.BaseSink
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
 import org.apache.spark.sql.{Dataset, Row}
 
 trait BaseSparkSink[OUT] extends BaseSink[SparkEnvironment] {
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSource.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSource.scala
index 71877ca..0b6afa5 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSource.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkSource.scala
@@ -17,7 +17,7 @@
 package org.apache.seatunnel.spark
 
 import org.apache.seatunnel.apis.BaseSource
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
 
 trait BaseSparkSource[Data] extends BaseSource[SparkEnvironment] {
 
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkTransform.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkTransform.scala
index ca904b1..d964d93 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkTransform.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/BaseSparkTransform.scala
@@ -18,7 +18,7 @@ package org.apache.seatunnel.spark
 
 import org.apache.spark.sql.{Dataset, Row}
 import org.apache.seatunnel.apis.BaseTransform
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
 
 trait BaseSparkTransform extends BaseTransform[SparkEnvironment] {
 
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/SparkEnvironment.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/SparkEnvironment.scala
index 9e92146..cb0b57f 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/SparkEnvironment.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/SparkEnvironment.scala
@@ -17,7 +17,7 @@
 package org.apache.seatunnel.spark
 
 import org.apache.seatunnel.common.config.CheckResult
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
 import org.apache.seatunnel.env.RuntimeEnv
 import org.apache.spark.SparkConf
 import org.apache.spark.sql.SparkSession
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/batch/SparkBatchExecution.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/batch/SparkBatchExecution.scala
index 285855f..9ed16fc 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/batch/SparkBatchExecution.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/batch/SparkBatchExecution.scala
@@ -17,7 +17,7 @@
 package org.apache.seatunnel.spark.batch
 
 import org.apache.seatunnel.common.config.{CheckResult, ConfigRuntimeException}
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
 import org.apache.seatunnel.env.Execution
 import org.apache.seatunnel.spark.{BaseSparkSink, BaseSparkSource, BaseSparkTransform, SparkEnvironment}
 import org.apache.spark.sql.{Dataset, Row}
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/stream/SparkStreamingExecution.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/stream/SparkStreamingExecution.scala
index 56b3a63..0c4e9b2 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/stream/SparkStreamingExecution.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/stream/SparkStreamingExecution.scala
@@ -17,7 +17,7 @@
 package org.apache.seatunnel.spark.stream
 
 import org.apache.seatunnel.common.config.CheckResult
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
 import org.apache.seatunnel.env.Execution
 import org.apache.seatunnel.spark.batch.SparkBatchExecution
 import org.apache.seatunnel.spark.{BaseSparkSink, BaseSparkSource, BaseSparkTransform, SparkEnvironment}
diff --git a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/structuredstream/StructuredStreamingExecution.scala b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/structuredstream/StructuredStreamingExecution.scala
index 3f8a488..6505d81 100644
--- a/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/structuredstream/StructuredStreamingExecution.scala
+++ b/seatunnel-apis/seatunnel-api-spark/src/main/scala/org/apache/seatunnel/spark/structuredstream/StructuredStreamingExecution.scala
@@ -17,7 +17,7 @@
 package org.apache.seatunnel.spark.structuredstream
 
 import org.apache.seatunnel.common.config.CheckResult
-import org.apache.seatunnel.config.{Config, ConfigFactory}
+import org.apache.seatunnel.shade.com.typesafe.config.{Config, ConfigFactory}
 import org.apache.seatunnel.env.Execution
 import org.apache.seatunnel.spark.{BaseSparkTransform, SparkEnvironment}
 
diff --git a/seatunnel-common/src/main/java/org/apache/seatunnel/common/PropertiesUtil.java b/seatunnel-common/src/main/java/org/apache/seatunnel/common/PropertiesUtil.java
index 764d152..25b242e 100644
--- a/seatunnel-common/src/main/java/org/apache/seatunnel/common/PropertiesUtil.java
+++ b/seatunnel-common/src/main/java/org/apache/seatunnel/common/PropertiesUtil.java
@@ -17,7 +17,7 @@
 
 package org.apache.seatunnel.common;
 
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
 
 import java.util.Properties;
 
diff --git a/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/CheckConfigUtil.java b/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/CheckConfigUtil.java
index 4b39f5c..1ce9605 100644
--- a/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/CheckConfigUtil.java
+++ b/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/CheckConfigUtil.java
@@ -17,7 +17,7 @@
 
 package org.apache.seatunnel.common.config;
 
-import org.apache.seatunnel.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
 
 public class CheckConfigUtil {
 
diff --git a/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/TypesafeConfigUtils.java b/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/TypesafeConfigUtils.java
index 722a32f..0fe1216 100644
--- a/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/TypesafeConfigUtils.java
+++ b/seatunnel-common/src/main/java/org/apache/seatunnel/common/config/TypesafeConfigUtils.java
@@ -17,9 +17,9 @@
 
 package org.apache.seatunnel.common.config;
 
-import org.apache.seatunnel.config.Config;
-import org.apache.seatunnel.config.ConfigFactory;
-import org.apache.seatunnel.config.ConfigValue;
+import org.apache.seatunnel.shade.com.typesafe.config.Config;
+import org.apache.seatunnel.shade.com.typesafe.config.ConfigFactory;
+import org.apache.seatunnel.shade.com.typesafe.config.ConfigValue;
 
 import java.util.LinkedHashMap;
 import java.util.Map;
diff --git a/seatunnel-config/HOCON.md b/seatunnel-config/HOCON.md
deleted file mode 100644
index 6e0818c..0000000
--- a/seatunnel-config/HOCON.md
+++ /dev/null
@@ -1,1625 +0,0 @@
-<!-- START doctoc generated TOC please keep comment here to allow auto update -->
-<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
-**Table of Contents**  *generated with [DocToc](https://github.com/thlorenz/doctoc)*
-
-- [HOCON (Human-Optimized Config Object Notation)](#hocon-human-optimized-config-object-notation)
-  - [Goals / Background](#goals--background)
-  - [Definitions](#definitions)
-  - [Syntax](#syntax)
-    - [Unchanged from JSON](#unchanged-from-json)
-    - [Comments](#comments)
-    - [Omit root braces](#omit-root-braces)
-    - [Key-value separator](#key-value-separator)
-    - [Commas](#commas)
-    - [Whitespace](#whitespace)
-    - [Duplicate keys and object merging](#duplicate-keys-and-object-merging)
-    - [Unquoted strings](#unquoted-strings)
-    - [Multi-line strings](#multi-line-strings)
-    - [Value concatenation](#value-concatenation)
-      - [String value concatenation](#string-value-concatenation)
-      - [Array and object concatenation](#array-and-object-concatenation)
-      - [Note: Concatenation with whitespace and substitutions](#note-concatenation-with-whitespace-and-substitutions)
-      - [Note: Arrays without commas or newlines](#note-arrays-without-commas-or-newlines)
-    - [Path expressions](#path-expressions)
-    - [Paths as keys](#paths-as-keys)
-    - [Substitutions](#substitutions)
-      - [Self-Referential Substitutions](#self-referential-substitutions)
-      - [The `+=` field separator](#the--field-separator)
-      - [Examples of Self-Referential Substitutions](#examples-of-self-referential-substitutions)
-    - [Includes](#includes)
-      - [Include syntax](#include-syntax)
-      - [Include semantics: merging](#include-semantics-merging)
-      - [Include semantics: substitution](#include-semantics-substitution)
-      - [Include semantics: missing files and required files](#include-semantics-missing-files-and-required-files)
-      - [Include semantics: file formats and extensions](#include-semantics-file-formats-and-extensions)
-      - [Include semantics: locating resources](#include-semantics-locating-resources)
-    - [Conversion of numerically-indexed objects to arrays](#conversion-of-numerically-indexed-objects-to-arrays)
-  - [MIME Type](#mime-type)
-  - [API Recommendations](#api-recommendations)
-    - [Automatic type conversions](#automatic-type-conversions)
-    - [Units format](#units-format)
-    - [Duration format](#duration-format)
-    - [Size in bytes format](#size-in-bytes-format)
-    - [Config object merging and file merging](#config-object-merging-and-file-merging)
-    - [Java properties mapping](#java-properties-mapping)
-    - [Conventional configuration files for JVM apps](#conventional-configuration-files-for-jvm-apps)
-    - [Conventional override by system properties](#conventional-override-by-system-properties)
-    - [Substitution fallback to environment variables](#substitution-fallback-to-environment-variables)
-    - [hyphen-separated vs. camelCase](#hyphen-separated-vs-camelcase)
-  - [Note on Java properties similarity](#note-on-java-properties-similarity)
-  - [Note on Windows and case sensitivity of environment variables](#note-on-windows-and-case-sensitivity-of-environment-variables)
-
-<!-- END doctoc generated TOC please keep comment here to allow auto update -->
-
-# HOCON (Human-Optimized Config Object Notation)
-
-This is an informal spec, but hopefully it's clear.
-
-## Goals / Background
-
-The primary goal is: keep the semantics (tree structure; set of
-types; encoding/escaping) from JSON, but make it more convenient
-as a human-editable config file format.
-
-The following features are desirable, to support human usage:
-
- - less noisy / less pedantic syntax
- - ability to refer to another part of the configuration (set a value to
-   another value)
- - import/include another configuration file into the current file
- - a mapping to a flat properties list such as Java's system properties
- - ability to get values from environment variables
- - ability to write comments
-
-Implementation-wise, the format should have these properties:
-
- - a JSON superset, that is, all valid JSON should be valid and
-   should result in the same in-memory data that a JSON parser
-   would have produced.
- - be deterministic; the format is flexible, but it is not
-   heuristic. It should be clear what's invalid and invalid files
-   should generate errors.
- - require minimal look-ahead; should be able to tokenize the file
-   by looking at only the next three characters. (right now, the
-   only reason to look at three is to find "//" comments;
-   otherwise you can parse looking at two.)
-
-HOCON is significantly harder to specify and to parse than
-JSON. Think of it as moving the work from the person maintaining
-the config file to the computer program.
-
-## Definitions
-
- - a _key_ is a string JSON would have to the left of `:` and a _value_ is
-   anything JSON would have to the right of `:`. i.e. the two
-   halves of an object _field_.
-
- - a _value_ is any "value" as defined in the JSON spec, plus
-   unquoted strings and substitutions as defined in this spec.
-
- - a _simple value_ is any value excluding an object or array
-   value.
-
- - a _field_ is a key, any separator such as ':', and a value.
-
- - references to a _file_ ("the file being parsed") can be
-   understood to mean any byte stream being parsed, not just
-   literal files in a filesystem.
-
-## Syntax
-
-Much of this is defined with reference to JSON; you can find the
-JSON spec at https://json.org/ of course.
-
-### Unchanged from JSON
-
- - files must be valid UTF-8
- - quoted strings are in the same format as JSON strings
- - values have possible types: string, number, object, array, boolean, null
- - allowed number formats matches JSON; as in JSON, some possible
-   floating-point values are not represented, such as `NaN`
-
-### Comments
-
-Anything between `//` or `#` and the next newline is considered a comment
-and ignored, unless the `//` or `#` is inside a quoted string.
-
-### Omit root braces
-
-JSON documents must have an array or object at the root. Empty
-files are invalid documents, as are files containing only a
-non-array non-object value such as a string.
-
-In HOCON, if the file does not begin with a square bracket or
-curly brace, it is parsed as if it were enclosed with `{}` curly
-braces.
-
-A HOCON file is invalid if it omits the opening `{` but still has
-a closing `}`; the curly braces must be balanced.
-
-### Key-value separator
-
-The `=` character can be used anywhere JSON allows `:`, i.e. to
-separate keys from values.
-
-If a key is followed by `{`, the `:` or `=` may be omitted. So
-`"foo" {}` means `"foo" : {}`
-
-### Commas
-
-Values in arrays, and fields in objects, need not have a comma
-between them as long as they have at least one ASCII newline
-(`\n`, decimal value 10) between them.
-
-The last element in an array or last field in an object may be
-followed by a single comma. This extra comma is ignored.
-
- - `[1,2,3,]` and `[1,2,3]` are the same array.
- - `[1\n2\n3]` and `[1,2,3]` are the same array.
- - `[1,2,3,,]` is invalid because it has two trailing commas.
- - `[,1,2,3]` is invalid because it has an initial comma.
- - `[1,,2,3]` is invalid because it has two commas in a row.
- - these same comma rules apply to fields in objects.
-
-### Whitespace
-
-The JSON spec simply says "whitespace"; in HOCON whitespace is
-defined as follows:
-
- - any Unicode space separator (Zs category), line separator (Zl
-   category), or paragraph separator (Zp category), including
-   nonbreaking spaces (such as 0x00A0, 0x2007, and 0x202F).
-   The BOM (0xFEFF) must also be treated as whitespace.
- - tab (`\t` 0x0009), newline ('\n' 0x000A), vertical tab ('\v'
-   0x000B)`, form feed (`\f' 0x000C), carriage return ('\r'
-   0x000D), file separator (0x001C), group separator (0x001D),
-   record separator (0x001E), unit separator (0x001F).
-
-In Java, the `isWhitespace()` method covers these characters with
-the exception of nonbreaking spaces and the BOM.
-
-While all Unicode separators should be treated as whitespace, in
-this spec "newline" refers only and specifically to ASCII newline
-0x000A.
-
-### Duplicate keys and object merging
-
-The JSON spec does not clarify how duplicate keys in the same
-object should be handled. In HOCON, duplicate keys that appear
-later override those that appear earlier, unless both values are
-objects. If both values are objects, then the objects are merged.
-
-Note: this would make HOCON a non-superset of JSON if you assume
-that JSON requires duplicate keys to have a behavior. The
-assumption here is that duplicate keys are invalid JSON.
-
-To merge objects:
-
- - add fields present in only one of the two objects to the merged
-   object.
- - for non-object-valued fields present in both objects,
-   the field found in the second object must be used.
- - for object-valued fields present in both objects, the
-   object values should be recursively merged according to
-   these same rules.
-
-Object merge can be prevented by setting the key to another value
-first. This is because merging is always done two values at a
-time; if you set a key to an object, a non-object, then an object,
-first the non-object falls back to the object (non-object always
-wins), and then the object falls back to the non-object (no
-merging, object is the new value). So the two objects never see
-each other.
-
-These two are equivalent:
-
-    {
-        "foo" : { "a" : 42 },
-        "foo" : { "b" : 43 }
-    }
-
-    {
-        "foo" : { "a" : 42, "b" : 43 }
-    }
-
-And these two are equivalent:
-
-    {
-        "foo" : { "a" : 42 },
-        "foo" : null,
-        "foo" : { "b" : 43 }
-    }
-
-    {
-        "foo" : { "b" : 43 }
-    }
-
-The intermediate setting of `"foo"` to `null` prevents the object merge.
-
-### Unquoted strings
-
-A sequence of characters outside of a quoted string is a string
-value if:
-
- - it does not contain "forbidden characters": '$', '"', '{', '}',
-   '[', ']', ':', '=', ',', '+', '#', '`', '^', '?', '!', '@',
-   '*', '&', '\' (backslash), or whitespace.
- - it does not contain the two-character string "//" (which
-   starts a comment)
- - its initial characters do not parse as `true`, `false`, `null`,
-   or a number.
-
-Unquoted strings are used literally, they do not support any kind
-of escaping. Quoted strings may always be used as an alternative
-when you need to write a character that is not permitted in an
-unquoted string.
-
-`truefoo` parses as the boolean token `true` followed by the
-unquoted string `foo`. However, `footrue` parses as the unquoted
-string `footrue`. Similarly, `10.0bar` is the number `10.0` then
-the unquoted string `bar` but `bar10.0` is the unquoted string
-`bar10.0`. (In practice, this distinction doesn't matter much
-because of value concatenation; see later section.)
-
-In general, once an unquoted string begins, it continues until a
-forbidden character or the two-character string "//" is
-encountered. Embedded (non-initial) booleans, nulls, and numbers
-are not recognized as such, they are part of the string.
-
-An unquoted string may not _begin_ with the digits 0-9 or with a
-hyphen (`-`, 0x002D) because those are valid characters to begin a
-JSON number. The initial number character, plus any valid-in-JSON
-number characters that follow it, must be parsed as a number
-value. Again, these characters are not special _inside_ an
-unquoted string; they only trigger number parsing if they appear
-initially.
-
-Note that quoted JSON strings may not contain control characters
-(control characters include some whitespace characters, such as
-newline). This rule is from the JSON spec. However, unquoted
-strings have no restriction on control characters, other than the
-ones listed as "forbidden characters" above.
-
-Some of the "forbidden characters" are forbidden because they
-already have meaning in JSON or HOCON, others are essentially
-reserved keywords to allow future extensions to this spec.
-
-### Multi-line strings
-
-Multi-line strings are similar to Python or Scala, using triple
-quotes. If the three-character sequence `"""` appears, then all
-Unicode characters until a closing `"""` sequence are used
-unmodified to create a string value. Newlines and whitespace
-receive no special treatment. Unlike Scala, and unlike JSON quoted
-strings, Unicode escapes are not interpreted in triple-quoted
-strings.
-
-In Python, `"""foo""""` is a syntax error (a triple-quoted string
-followed by a dangling unbalanced quote). In Scala, it is a
-four-character string `foo"`. HOCON works like Scala; any sequence
-of at least three quotes ends the multi-line string, and any
-"extra" quotes are part of the string.
-
-### Value concatenation
-
-The value of an object field or array element may consist of
-multiple values which are combined. There are three kinds of value
-concatenation:
-
- - if all the values are simple values (neither objects nor
-   arrays), they are concatenated into a string.
- - if all the values are arrays, they are concatenated into
-   one array.
- - if all the values are objects, they are merged (as with
-   duplicate keys) into one object.
-
-String value concatenation is allowed in field keys, in addition
-to field values and array elements. Objects and arrays do not make
-sense as field keys.
-
-Note: Akka 2.0 (and thus Play 2.0) contains an embedded
-implementation of the config lib which does not support array and
-object value concatenation; it only supports string value
-concatenation.
-
-#### String value concatenation
-
-String value concatenation is the trick that makes unquoted
-strings work; it also supports substitutions (`${foo}` syntax) in
-strings.
-
-Only simple values participate in string value
-concatenation. Recall that a simple value is any value other than
-arrays and objects.
-
-As long as simple values are separated only by non-newline
-whitespace, the _whitespace between them is preserved_ and the
-values, along with the whitespace, are concatenated into a string.
-
-String value concatenations never span a newline, or a character
-that is not part of a simple value.
-
-A string value concatenation may appear in any place that a string
-may appear, including object keys, object values, and array
-elements.
-
-Whenever a value would appear in JSON, a HOCON parser instead
-collects multiple values (including the whitespace between them)
-and concatenates those values into a string.
-
-Whitespace before the first and after the last simple value must
-be discarded. Only whitespace _between_ simple values must be
-preserved.
-
-So for example ` foo bar baz ` parses as three unquoted strings,
-and the three are value-concatenated into one string. The inner
-whitespace is kept and the leading and trailing whitespace is
-trimmed. The equivalent string, written in quoted form, would be
-`"foo bar baz"`.
-
-Value concatenating `foo bar` (two unquoted strings with
-whitespace) and quoted string `"foo bar"` would result in the same
-in-memory representation, seven characters.
-
-For purposes of string value concatenation, non-string values are
-converted to strings as follows (strings shown as quoted strings):
-
- - `true` and `false` become the strings `"true"` and `"false"`.
- - `null` becomes the string `"null"`.
- - quoted and unquoted strings are themselves.
- - numbers should be kept as they were originally written in the
-   file. For example, if you parse `1e5` then you might render
-   it alternatively as `1E5` with capital `E`, or just `100000`.
-   For purposes of value concatenation, it should be rendered
-   as it was written in the file.
- - a substitution is replaced with its value which is then
-   converted to a string as above.
- - it is invalid for arrays or objects to appear in a string value
-   concatenation.
-
-A single value is never converted to a string. That is, it would
-be wrong to value concatenate `true` by itself; that should be
-parsed as a boolean-typed value. Only `true foo` (`true` with
-another simple value on the same line) should be parsed as a value
-concatenation and converted to a string.
-
-#### Array and object concatenation
-
-Arrays can be concatenated with arrays, and objects with objects,
-but it is an error if they are mixed.
-
-For purposes of concatenation, "array" also means "substitution
-that resolves to an array" and "object" also means "substitution
-that resolves to an object."
-
-Within an field value or array element, if only non-newline
-whitespace separates the end of a first array or object or
-substitution from the start of a second array or object or
-substitution, the two values are concatenated. Newlines may occur
-_within_ the array or object, but not _between_ them. Newlines
-_between_ prevent concatenation.
-
-For objects, "concatenation" means "merging", so the second object
-overrides the first.
-
-Arrays and objects cannot be field keys, whether concatenation is
-involved or not.
-
-Here are several ways to define `a` to the same object value:
-
-    // one object
-    a : { b : 1, c : 2 }
-    // two objects that are merged via concatenation rules
-    a : { b : 1 } { c : 2 }
-    // two fields that are merged
-    a : { b : 1 }
-    a : { c : 2 }
-
-Here are several ways to define `a` to the same array value:
-
-    // one array
-    a : [ 1, 2, 3, 4 ]
-    // two arrays that are concatenated
-    a : [ 1, 2 ] [ 3, 4 ]
-    // a later definition referring to an earlier
-    // (see "self-referential substitutions" below)
-    a : [ 1, 2 ]
-    a : ${a} [ 3, 4 ]
-
-A common use of object concatenation is "inheritance":
-
-    data-center-generic = { cluster-size = 6 }
-    data-center-east = ${data-center-generic} { name = "east" }
-
-A common use of array concatenation is to add to paths:
-
-    path = [ /bin ]
-    path = ${path} [ /usr/bin ]
-
-#### Note: Concatenation with whitespace and substitutions
-
-When concatenating substitutions such as `${foo} ${bar}`, the
-substitutions may turn out to be strings (which makes the
-whitespace between them significant) or may turn out to be objects
-or lists (which makes it irrelevant). Unquoted whitespace must be
-ignored in between substitutions which resolve to objects or
-lists. Quoted whitespace should be an error.
-
-#### Note: Arrays without commas or newlines
-
-Arrays allow you to use newlines instead of commas, but not
-whitespace instead of commas. Non-newline whitespace will produce
-concatenation rather than separate elements.
-
-    // this is an array with one element, the string "1 2 3 4"
-    [ 1 2 3 4 ]
-    // this is an array of four integers
-    [ 1
-      2
-      3
-      4 ]
-
-    // an array of one element, the array [ 1, 2, 3, 4 ]
-    [ [ 1, 2 ] [ 3, 4 ] ]
-    // an array of two arrays
-    [ [ 1, 2 ]
-      [ 3, 4 ] ]
-
-If this gets confusing, just use commas. The concatenation
-behavior is useful rather than surprising in cases like:
-
-    [ This is an unquoted string my name is ${name}, Hello ${world} ]
-    [ ${a} ${b}, ${x} ${y} ]
-
-Non-newline whitespace is never an element or field separator.
-
-### Path expressions
-
-Path expressions are used to write out a path through the object
-graph. They appear in two places; in substitutions, like
-`${foo.bar}`, and as the keys in objects like `{ foo.bar : 42 }`.
-
-Path expressions are syntactically identical to a value
-concatenation, except that they may not contain
-substitutions. This means that you can't nest substitutions inside
-other substitutions, and you can't have substitutions in keys.
-
-When concatenating the path expression, any `.` characters outside
-quoted strings are understood as path separators, while inside
-quoted strings `.` has no special meaning. So
-`foo.bar."hello.world"` would be a path with three elements,
-looking up key `foo`, key `bar`, then key `hello.world`.
-
-The main tricky point is that `.` characters in numbers do count
-as a path separator. When dealing with a number as part of a path
-expression, it's essential to retain the _original_ string
-representation of the number as it appeared in the file (rather
-than converting it back to a string with a generic
-number-to-string library function).
-
- - `10.0foo` is a number then unquoted string `foo` and should
-   be the two-element path with `10` and `0foo` as the elements.
- - `foo10.0` is an unquoted string with a `.` in it, so this would
-   be a two-element path with `foo10` and `0` as the elements.
- - `foo"10.0"` is an unquoted then a quoted string which are
-   concatenated, so this is a single-element path.
- - `1.2.3` is the three-element path with `1`,`2`,`3`
-
-Unlike value concatenations, path expressions are _always_
-converted to a string, even if they are just a single value.
-
-If you have an array or element value consisting of the single
-value `true`, it's a value concatenation and retains its character
-as a boolean value.
-
-If you have a path expression (in a key or substitution) then it
-must always be converted to a string, so `true` becomes the string
-that would be quoted as `"true"`.
-
-If a path element is an empty string, it must always be quoted.
-That is, `a."".b` is a valid path with three elements, and the
-middle element is an empty string. But `a..b` is invalid and
-should generate an error. Following the same rule, a path that
-starts or ends with a `.` is invalid and should generate an error.
-
-### Paths as keys
-
-If a key is a path expression with multiple elements, it is
-expanded to create an object for each path element other than the
-last. The last path element, combined with the value, becomes a
-field in the most-nested object.
-
-In other words:
-
-    foo.bar : 42
-
-is equivalent to:
-
-    foo { bar : 42 }
-
-and:
-
-    foo.bar.baz : 42
-
-is equivalent to:
-
-    foo { bar { baz : 42 } }
-
-and so on. These values are merged in the usual way; which implies
-that:
-
-    a.x : 42, a.y : 43
-
-is equivalent to:
-
-    a { x : 42, y : 43 }
-
-Because path expressions work like value concatenations, you can
-have whitespace in keys:
-
-    a b c : 42
-
-is equivalent to:
-
-    "a b c" : 42
-
-Because path expressions are always converted to strings, even
-single values that would normally have another type become
-strings.
-
-   - `true : 42` is `"true" : 42`
-   - `3 : 42` is `"3" : 42`
-   - `3.14 : 42` is `"3" : { "14" : 42 }`
-
-As a special rule, the unquoted string `include` may not begin a
-path expression in a key, because it has a special interpretation
-(see below).
-
-### Substitutions
-
-Substitutions are a way of referring to other parts of the
-configuration tree.
-
-The syntax is `${pathexpression}` or `${?pathexpression}` where
-the `pathexpression` is a path expression as described above. This
-path expression has the same syntax that you could use for an
-object key.
-
-The `?` in `${?pathexpression}` must not have whitespace before
-it; the three characters `${?` must be exactly like that, grouped
-together.
-
-For substitutions which are not found in the configuration tree,
-implementations may try to resolve them by looking at system
-environment variables or other external sources of configuration.
-(More detail on environment variables in a later section.)
-
-Substitutions are not parsed inside quoted strings. To get a
-string containing a substitution, you must use value concatenation
-with the substitution in the unquoted portion:
-
-    key : ${animal.favorite} is my favorite animal
-
-Or you could quote the non-substitution portion:
-
-    key : ${animal.favorite}" is my favorite animal"
-
-Substitutions are resolved by looking up the path in the
-configuration. The path begins with the root configuration object,
-i.e. it is "absolute" rather than "relative."
-
-Substitution processing is performed as the last parsing step, so
-a substitution can look forward in the configuration. If a
-configuration consists of multiple files, it may even end up
-retrieving a value from another file.
-
-If a key has been specified more than once, the substitution will
-always evaluate to its latest-assigned value (that is, it will
-evaluate to the merged object, or the last non-object value that
-was set, in the entire document being parsed including all
-included files).
-
-If a configuration sets a value to `null` then it should not be
-looked up in the external source. Unfortunately there is no way to
-"undo" this in a later configuration file; if you have `{ "HOME" :
-null }` in a root object, then `${HOME}` will never look at the
-environment variable. There is no equivalent to JavaScript's
-`delete` operation in other words.
-
-If a substitution does not match any value present in the
-configuration and is not resolved by an external source, then it
-is undefined. An undefined substitution with the `${foo}` syntax
-is invalid and should generate an error.
-
-If a substitution with the `${?foo}` syntax is undefined:
-
- - if it is the value of an object field then the field should not
-   be created. If the field would have overridden a previously-set
-   value for the same field, then the previous value remains.
- - if it is an array element then the element should not be added.
- - if it is part of a value concatenation with another string then
-   it should become an empty string; if part of a value
-   concatenation with an object or array it should become an empty
-   object or array.
- - `foo : ${?bar}` would avoid creating field `foo` if `bar` is
-   undefined. `foo : ${?bar}${?baz}` would also avoid creating the
-   field if _both_ `bar` and `baz` are undefined.
-
-Substitutions are only allowed in field values and array
-elements (value concatenations), they are not allowed in keys or
-nested inside other substitutions (path expressions).
-
-A substitution is replaced with any value type (number, object,
-string, array, true, false, null). If the substitution is the only
-part of a value, then the type is preserved. Otherwise, it is
-value-concatenated to form a string.
-
-#### Self-Referential Substitutions
-
-The big picture:
-
- - substitutions normally "look forward" and use the final value
-   for their path expression
- - when this would create a cycle, when possible the cycle must be
-   broken by looking backward only (thus removing one of the
-   substitutions that's a link in the cycle)
-
-The idea is to allow a new value for a field to be based on the
-older value:
-
-    path : "a:b:c"
-    path : ${path}":d"
-
-A _self-referential field_ is one which:
-
- - has a substitution, or value concatenation containing a
-   substitution, as its value
- - where this field value refers to the field being defined,
-   either directly or by referring to one or more other
-   substitutions which eventually point back to the field being
-   defined
-
-Examples of self-referential fields:
-
- - `a : ${a}`
- - `a : ${a}bc`
- - `path : ${path} [ /usr/bin ]`
-
-Note that an object or array with a substitution inside it is
-_not_ considered self-referential for this purpose. The
-self-referential rules do _not_ apply to:
-
- - `a : { b : ${a} }`
- - `a : [${a}]`
-
-These cases are unbreakable cycles that generate an error. (If
-"looking backward" were allowed for these, something like
-`a={ x : 42, y : ${a.x} }` would look backward for a
-nonexistent `a` while resolving `${a.x}`.)
-
-A possible implementation is:
-
- - substitutions are resolved by looking up paths in a document.
-   Cycles only arise when the lookup document is an ancestor
-   node of the substitution node.
- - while resolving a potentially self-referential field (any
-   substitution or value concatenation that contains a
-   substitution), remove that field and all fields which override
-   it from the lookup document.
-
-The simplest form of this implementation will report a circular
-reference as missing; in `a : ${a}` you would remove `a : ${a}`
-while resolving `${a}`, leaving an empty document to look up
-`${a}` in. You can give a more helpful error message if, rather
-than simply removing the field, you leave a marker value
-describing the cycle. Then generate an error if you return to that
-marker value during resolution.
-
-Cycles should be treated the same as a missing value when
-resolving an optional substitution (i.e. the `${?foo}` syntax).
-If `${?foo}` refers to itself then it's as if it referred to a
-nonexistent value.
-
-#### The `+=` field separator
-
-Fields may have `+=` as a separator rather than `:` or `=`. A
-field with `+=` transforms into a self-referential array
-concatenation, like this:
-
-    a += b
-
-becomes:
-
-    a = ${?a} [b]
-
-`+=` appends an element to a previous array. If the previous value
-was not an array, an error will result just as it would in the
-long form `a = ${?a} [b]`. Note that the previous value is
-optional (`${?a}` not `${a}`), which allows `a += b` to be the
-first mention of `a` in the file (it is not necessary to have `a =
-[]` first).
-
-Note: Akka 2.0 (and thus Play 2.0) contains an embedded
-implementation of the config lib which does not support `+=`.
-
-#### Examples of Self-Referential Substitutions
-
-In isolation (with no merges involved), a self-referential field
-is an error because the substitution cannot be resolved:
-
-    foo : ${foo} // an error
-
-When `foo : ${foo}` is merged with an earlier value for `foo`,
-however, the substitution can be resolved to that earlier value.
-When merging two objects, the self-reference in the overriding
-field refers to the overridden field. Say you have:
-
-    foo : { a : 1 }
-
-and then:
-
-    foo : ${foo}
-
-Then `${foo}` resolves to `{ a : 1 }`, the value of the overridden
-field.
-
-It would be an error if these two fields were reversed, so first:
-
-    foo : ${foo}
-
-and then second:
-
-    foo : { a : 1 }
-
-Here the `${foo}` self-reference comes before `foo` has a value,
-so it is undefined, exactly as if the substitution referenced a
-path not found in the document.
-
-Because `foo : ${foo}` conceptually looks to previous definitions
-of `foo` for a value, the error should be treated as "undefined"
-rather than "intractable cycle"; as a result, the optional
-substitution syntax `${?foo}` does not create a cycle:
-
-    foo : ${?foo} // this field just disappears silently
-
-If a substitution is hidden by a value that could not be merged
-with it (by a non-object value) then it is never evaluated and no
-error will be reported. So for example:
-
-    foo : ${does-not-exist}
-    foo : 42
-
-In this case, no matter what `${does-not-exist}` resolves to, we
-know `foo` is `42`, so `${does-not-exist}` is never evaluated and
-there is no error. The same is true for cycles like `foo : ${foo},
-foo : 42`, where the initial self-reference must simply be ignored.
-
-A self-reference resolves to the value "below" even if it's part
-of a path expression. So for example:
-
-    foo : { a : { c : 1 } }
-    foo : ${foo.a}
-    foo : { a : 2 }
-
-Here, `${foo.a}` would refer to `{ c : 1 }` rather than `2` and so
-the final merge would be `{ a : 2, c : 1 }`.
-
-Recall that for a field to be self-referential, it must have a
-substitution or value concatenation as its value. If a field has
-an object or array value, for example, then it is not
-self-referential even if there is a reference to the field itself
-inside that object or array.
-
-Implementations must be careful to allow objects to refer to paths
-within themselves, for example:
-
-    bar : { foo : 42,
-            baz : ${bar.foo}
-          }
-
-Here, if an implementation resolved all substitutions in `bar` as
-part of resolving the substitution `${bar.foo}`, there would be a
-cycle. The implementation must only resolve the `foo` field in
-`bar`, rather than recursing the entire `bar` object.
-
-Because there is no inherent cycle here, the substitution must
-"look forward" (including looking at the field currently being
-defined). To make this clearer, `bar.baz` would be `43` in:
-
-    bar : { foo : 42,
-            baz : ${bar.foo}
-          }
-    bar : { foo : 43 }
-
-Mutually-referring objects should also work, and are not
-self-referential (so they look forward):
-
-    // bar.a should end up as 4
-    bar : { a : ${foo.d}, b : 1 }
-    bar.b = 3
-    // foo.c should end up as 3
-    foo : { c : ${bar.b}, d : 2 }
-    foo.d = 4
-
-Another tricky case is an optional self-reference in a value
-concatenation, in this example `a` should be `foo` not `foofoo`
-because the self reference has to "look back" to an undefined `a`:
-
-    a = ${?a}foo
-
-In general, in resolving a substitution the implementation must:
-
- - lazy-evaluate the substitution target so there's no
-   "circularity by side effect"
- - "look forward" and use the final value for the path
-   specified in the substitution
- - if a cycle results, the implementation must "look back"
-   in the merge stack to try to resolve the cycle
- - if neither lazy evaluation nor "looking only backward" resolves
-   a cycle, the substitution is missing which is an error unless
-   the `${?foo}` optional-substitution syntax was used.
-
-For example, this is not possible to resolve:
-
-    bar : ${foo}
-    foo : ${bar}
-
-A multi-step loop like this should also be detected as invalid:
-
-    a : ${b}
-    b : ${c}
-    c : ${a}
-
-Some cases have undefined behavior because the behavior depends on
-the order in which two fields are resolved, and that order is not
-defined. For example:
-
-    a : 1
-    b : 2
-    a : ${b}
-    b : ${a}
-
-Implementations are allowed to handle this by setting both `a` and
-`b` to 1, setting both to `2`, or generating an error. Ideally
-this situation would generate an error, but that may be difficult
-to implement. Making the behavior defined would require always
-working with ordered maps rather than unordered maps, which is too
-constraining. Implementations only have to track order for
-duplicate instances of the same field (i.e. merges).
-
-Implementations must set both `a` and `b` to the same value in
-this case, however. In practice this means that all substitutions
-must be memoized (resolved once, with the result
-retained). Memoization should be keyed by the substitution
-"instance" (the specific occurrence of the `${}` expression)
-rather than by the path inside the `${}` expression, because
-substitutions may be resolved differently depending on their
-position in the file.
-
-### Includes
-
-#### Include syntax
-
-An _include statement_ consists of the unquoted string `include`
-followed by whitespace and then either:
- - a single _quoted_ string which is interpreted heuristically as
-   URL, filename, or classpath resource.
- - `url()`, `file()`, or `classpath()` surrounding a quoted string
-   which is then interpreted as a URL, file, or classpath. The
-   string must be quoted, unlike in CSS.
- - `required()` surrounding one of the above
-
-An include statement can appear in place of an object field.
-
-If the unquoted string `include` appears at the start of a path
-expression where an object key would be expected, then it is not
-interpreted as a path expression or a key.
-
-Instead, the next value must be a _quoted_ string or a quoted
-string surrounded by `url()`, `file()`, or `classpath()`.
-This value is the _resource name_.
-
-Together, the unquoted `include` and the resource name substitute
-for an object field syntactically, and are separated from the
-following object fields or includes by the usual comma (and as
-usual the comma may be omitted if there's a newline).
-
-If an unquoted `include` at the start of a key is followed by
-anything other than a single quoted string or the
-`url("")`/`file("")`/`classpath("")` syntax, it is invalid and an
-error should be generated.
-
-There can be any amount of whitespace, including newlines, between
-the unquoted `include` and the resource name. For `url()` etc.,
-whitespace is allowed inside the parentheses `()` (outside of the
-quotes).
-
-Value concatenation is NOT performed on the "argument" to
-`include` or `url()` etc. The argument must be a single quoted
-string. No substitutions are allowed, and the argument may not be
-an unquoted string or any other kind of value.
-
-Unquoted `include` has no special meaning if it is not the start
-of a key's path expression.
-
-It may appear later in the key:
-
-    # this is valid
-    { foo include : 42 }
-    # equivalent to
-    { "foo include" : 42 }
-
-It may appear as an object or array value:
-
-    { foo : include } # value is the string "include"
-    [ include ]       # array of one string "include"
-
-You can quote `"include"` if you want a key that starts with the
-word `"include"`, only unquoted `include` is special:
-
-    { "include" : 42 }
-
-Note: Akka 2.0 (and thus Play 2.0) contains an embedded
-implementation of the config lib which does not support the
-`url()`/`file()`/`classpath()` syntax. Only the heuristic `include
-"foo"` syntax is supported in that version.
-
-#### Include semantics: merging
-
-An _including file_ contains the include statement and an
-_included file_ is the one specified in the include statement.
-(They need not be regular files on a filesystem, but assume they
-are for the moment.)
-
-An included file must contain an object, not an array. This is
-significant because both JSON and HOCON allow arrays as root
-values in a document.
-
-If an included file contains an array as the root value, it is
-invalid and an error should be generated.
-
-The included file should be parsed, producing a root object. The
-keys from the root object are conceptually substituted for the
-include statement in the including file.
-
- - If a key in the included object occurred prior to the include
-   statement in the including object, the included key's value
-   overrides or merges with the earlier value, exactly as with
-   duplicate keys found in a single file.
- - If the including file repeats a key from an earlier-included
-   object, the including file's value would override or merge
-   with the one from the included file.
-
-#### Include semantics: substitution
-
-Substitutions in included files are looked up at two different
-paths; first, relative to the root of the included file; second,
-relative to the root of the including configuration.
-
-Recall that substitution happens as a final step, _after_
-parsing. It should be done for the entire app's configuration, not
-for single files in isolation.
-
-Therefore, if an included file contains substitutions, they must
-be "fixed up" to be relative to the app's configuration root.
-
-Say for example that the root configuration is this:
-
-    { a : { include "foo.conf" } }
-
-And "foo.conf" might look like this:
-
-    { x : 10, y : ${x} }
-
-If you parsed "foo.conf" in isolation, then `${x}` would evaluate
-to 10, the value at the path `x`. If you include "foo.conf" in an
-object at key `a`, however, then it must be fixed up to be
-`${a.x}` rather than `${x}`.
-
-Say that the root configuration redefines `a.x`, like this:
-
-    {
-        a : { include "foo.conf" }
-        a : { x : 42 }
-    }
-
-Then the `${x}` in "foo.conf", which has been fixed up to
-`${a.x}`, would evaluate to `42` rather than to `10`.
-Substitution happens _after_ parsing the whole configuration.
-
-However, there are plenty of cases where the included file might
-intend to refer to the application's root config. For example, to
-get a value from a system property or from the reference
-configuration. So it's not enough to only look up the "fixed up"
-path, it's necessary to look up the original path as well.
-
-#### Include semantics: missing files and required files
-
-By default, if an included file does not exist then the include statement should
-be silently ignored (as if the included file contained only an
-empty object).
-
-If however an included resource is mandatory then the name of the
-included resource may be wrapped with `required()`, in which case
-file parsing will fail with an error if the resource cannot be resolved.
-
-The syntax for this is
-
-    include required("foo.conf")
-    include required(file("foo.conf"))
-    include required(classpath("foo.conf"))
-    include required(url("http://localhost/foo.conf"))
-
-
-Other IO errors probably should not be ignored but implementations
-will have to make a judgment which IO errors reflect an ignorable
-missing file, and which reflect a problem to bring to the user's
-attention.
-
-#### Include semantics: file formats and extensions
-
-Implementations may support including files in other formats.
-Those formats must be compatible with the JSON type system, or
-have some documented mapping to JSON's type system.
-
-If an implementation supports multiple formats, then the extension
-may be omitted from the name of included files:
-
-    include "foo"
-
-If a filename has no extension, the implementation should treat it
-as a basename and try loading the file with all known extensions.
-
-If the file exists with multiple extensions, they should _all_ be
-loaded and merged together.
-
-Files in HOCON format should be parsed last. Files in JSON format
-should be parsed next-to-last.
-
-In short, `include "foo"` might be equivalent to:
-
-    include "foo.properties"
-    include "foo.json"
-    include "foo.conf"
-
-This same extension-based behavior is applied to classpath
-resources and files.
-
-For URLs, a basename without extension is not allowed; only the
-exact URL specified is used. The format will be chosen based on
-the Content-Type if available, or by the extension of the path
-component of the URL if no Content-Type is set. This is true even
-for file: URLs.
-
-#### Include semantics: locating resources
-
-A quoted string not surrounded by `url()`, `file()`, `classpath()`
-must be interpreted heuristically. The heuristic is to treat the
-quoted string as:
-
- - a URL, if the quoted string is a valid URL with a known
-   protocol.
- - otherwise, a file or other resource "adjacent to" the one being
-   parsed and of the same type as the one being parsed. The meaning
-   of "adjacent to", and the string itself, has to be specified
-   separately for each kind of resource.
- - On the Java Virtual Machine, if an include statement does not
-   identify a valid URL or an existing resource "adjacent to" the
-   including resource, implementations may wish to fall back to a
-   classpath resource.  This allows configurations found in files
-   or URLs to access classpath resources in a natural way.
-
-Implementations may vary in the kinds of resources they can
-include.
-
-For resources located on the Java classpath:
-
- - included resources are looked up by calling `getResource()` on
-   the same class loader used to look up the including resource.
- - if the included resource name is absolute (starts with '/')
-   then it should be passed to `getResource()` with the '/'
-   removed.
- - if the included resource name does not start with '/' then it
-   should have the "directory" of the including resource
-   prepended to it, before passing it to `getResource()`.  If the
-   including resource is not absolute (no '/') and has no "parent
-   directory" (is just a single path element), then the included
-   relative resource name should be left as-is.
- - it would be wrong to use `getResource()` to get a URL and then
-   locate the included name relative to that URL, because a class
-   loader is not required to have a one-to-one mapping between
-   paths in its URLs and the paths it handles in `getResource()`.
-   In other words, the "adjacent to" computation should be done
-   on the resource name not on the resource's URL.
-
-For plain files on the filesystem:
-
- - if the included file is an absolute path then it should be kept
-   absolute and loaded as such.
- - if the included file is a relative path, then it should be
-   located relative to the directory containing the including
-   file.  The current working directory of the process parsing a
-   file must NOT be used when interpreting included paths.
- - if the file is not found, fall back to the classpath resource.
-   The classpath resource should not have any package name added
-   in front, it should be relative to the "root"; which means any
-   leading "/" should just be removed (absolute is the same as
-   relative since it's root-relative). The "/" is handled for
-   consistency with including resources from inside other
-   classpath resources, where the resource name may not be
-   root-relative and "/" allows specifying relative to root.
-
-URLs:
-
- - for files loaded from a URL, "adjacent to" should be based
-   on parsing the URL's path component, replacing the last
-   path element with the included name.
- - file: URLs should behave in exactly the same way as a plain
-   filename
-
-Implementations need not support files, Java resources, or URLs;
-and they need not support particular URL protocols. However, if
-they do support them they should do so as described above.
-
-Note that at present, if `url()`/`file()`/`classpath()` are
-specified, the included items are NOT interpreted relative to the
-including items. Relative-to-including-file paths only work with
-the heuristic `include "foo.conf"`. This may change in the future.
-
-### Conversion of numerically-indexed objects to arrays
-
-In some file formats and contexts, such as Java properties files,
-there isn't a good way to define arrays. To provide some mechanism
-for this, implementations should support converting objects with
-numeric keys into arrays. For example, this object:
-
-    { "0" : "a", "1" : "b" }
-
-could be treated as:
-
-    [ "a", "b" ]
-
-This allows creating an array in a properties file like this:
-
-    foo.0 = "a"
-    foo.1 = "b"
-
-The details:
-
- - the conversion should be done lazily when required to avoid
-   a type error, NOT eagerly anytime an object has numeric
-   keys.
- - the conversion should be done when you would do an automatic
-   type conversion (see the section "Automatic type conversions"
-   below).
- - the conversion should be done in a concatenation when a list
-   is expected and an object with numeric keys is found.
- - the conversion should not occur if the object is empty or
-   has no keys which parse as positive integers.
- - the conversion should ignore any keys which do not parse
-   as positive integers.
- - the conversion should sort by the integer value of each
-   key and then build the array; if the integer keys are "0" and
-   "2" then the resulting array would have indices "0" and "1",
-   i.e. missing indices in the object are eliminated.
-
-## MIME Type
-
-Use "application/hocon" for Content-Type.
-
-## API Recommendations
-
-Implementations of HOCON ideally follow certain conventions and
-work in a predictable way.
-
-### Automatic type conversions
-
-If an application asks for a value with a particular type, the
-implementation should attempt to convert types as follows:
-
- - number to string: convert the number into a string
-   representation that would be a valid number in JSON.
- - boolean to string: should become the string "true" or "false"
- - string to number: parse the number with the JSON rules
- - string to boolean: the strings "true", "yes", "on", "false",
-   "no", "off" should be converted to boolean values. It's
-   tempting to support a long list of other ways to write a
-   boolean, but for interoperability and keeping it simple, it's
-   recommended to stick to these six.
- - string to null: the string `"null"` should be converted to a
-   null value if the application specifically asks for a null
-   value, though there's probably no reason an app would do this.
- - numerically-indexed object to array: see the section
-   "Conversion of numerically-indexed objects to arrays" above
-
-The following type conversions should NOT be performed:
-
- - null to anything: If the application asks for a specific type
-   and finds null instead, that should usually result in an error.
- - object to anything
- - array to anything
- - anything to object
- - anything to array, with the exception of numerically-indexed
-   object to array
-
-Converting objects and arrays to and from strings is tempting, but
-in practical situations raises thorny issues of quoting and
-double-escaping.
-
-### Units format
-
-Implementations may wish to support interpreting a value with some
-family of units, such as time units or memory size units: `10ms`
-or `512K`. HOCON does not have an extensible type system and there
-is no way to add a "duration" type. However, for example, if an
-application asks for milliseconds, the implementation can try to
-interpret a value as a milliseconds value.
-
-If an API supports this, for each family of units it should define
-a default unit in the family. For example, the family of duration
-units might default to milliseconds (see below for details on
-durations). The implementation should then interpret values as
-follows:
-
- - if the value is a number, it is taken to be a number in
-   the default unit.
- - if the value is a string, it is taken to be this sequence:
-
-     - optional whitespace
-     - a number
-     - optional whitespace
-     - an optional unit name consisting only of letters (letters
-       are the Unicode `L*` categories, Java `isLetter()`)
-     - optional whitespace
-
-   If a string value has no unit name, then it should be
-   interpreted with the default unit, as if it were a number. If a
-   string value has a unit name, that name of course specifies the
-   value's interpretation.
-
-### Duration format
-
-Implementations may wish to support a `getMilliseconds()` (and
-similar for other time units).
-
-This can use the general "units format" described above; bare
-numbers are taken to be in milliseconds already, while strings are
-parsed as a number plus an optional unit string.
-
-The supported unit strings for duration are case sensitive and
-must be lowercase. Exactly these strings are supported:
-
- - `ns`, `nano`, `nanos`, `nanosecond`, `nanoseconds`
- - `us`, `micro`, `micros`, `microsecond`, `microseconds`
- - `ms`, `milli`, `millis`, `millisecond`, `milliseconds`
- - `s`, `second`, `seconds`
- - `m`, `minute`, `minutes`
- - `h`, `hour`, `hours`
- - `d`, `day`, `days`
- 
-### Period Format
- 
-Similar to the `getDuration()` method, there is a `getPeriod()` method 
-available for getting time units as a `java.time.Period`. 
-
-This can use the general "units format" described above; bare
-numbers are taken to be in days, while strings are
-parsed as a number plus an optional unit string.
-
-The supported unit strings for period are case sensitive and
-must be lowercase. Exactly these strings are supported:
-
- - `d`, `day`, `days`
- - `w`, `week`, `weeks`
- - `m`, `mo`, `month`, `months` (note that if you are using `getTemporal()`
- which may return either a `java.time.Duration` or a `java.time.Period`
- you will want to use `mo` rather than `m` to prevent your unit being 
- parsed as minutes)
- - `y`, `year`, `years`
- 
-### Size in bytes format
-
-Implementations may wish to support a `getBytes()` returning a
-size in bytes.
-
-This can use the general "units format" described above; bare
-numbers are taken to be in bytes already, while strings are
-parsed as a number plus an optional unit string.
-
-The one-letter unit strings may be uppercase (note: duration units
-are always lowercase, so this convention is specific to size
-units).
-
-There is an unfortunate nightmare with size-in-bytes units, that
-they may be in powers or two or powers of ten. The approach
-defined by standards bodies appears to differ from common usage,
-such that following the standard leads to people being confused.
-Worse, common usage varies based on whether people are talking
-about RAM or disk sizes, and various existing operating systems
-and apps do all kinds of different things.  See
-https://en.wikipedia.org/wiki/Binary_prefix#Deviation_between_powers_of_1024_and_powers_of_1000
-for examples. It appears impossible to sort this out without
-causing confusion for someone sometime.
-
-For single bytes, exactly these strings are supported:
-
- - `B`, `b`, `byte`, `bytes`
-
-For powers of ten, exactly these strings are supported:
-
- - `kB`, `kilobyte`, `kilobytes`
- - `MB`, `megabyte`, `megabytes`
- - `GB`, `gigabyte`, `gigabytes`
- - `TB`, `terabyte`, `terabytes`
- - `PB`, `petabyte`, `petabytes`
- - `EB`, `exabyte`, `exabytes`
- - `ZB`, `zettabyte`, `zettabytes`
- - `YB`, `yottabyte`, `yottabytes`
-
-For powers of two, exactly these strings are supported:
-
- - `K`, `k`, `Ki`, `KiB`, `kibibyte`, `kibibytes`
- - `M`, `m`, `Mi`, `MiB`, `mebibyte`, `mebibytes`
- - `G`, `g`, `Gi`, `GiB`, `gibibyte`, `gibibytes`
- - `T`, `t`, `Ti`, `TiB`, `tebibyte`, `tebibytes`
- - `P`, `p`, `Pi`, `PiB`, `pebibyte`, `pebibytes`
- - `E`, `e`, `Ei`, `EiB`, `exbibyte`, `exbibytes`
- - `Z`, `z`, `Zi`, `ZiB`, `zebibyte`, `zebibytes`
- - `Y`, `y`, `Yi`, `YiB`, `yobibyte`, `yobibytes`
-
-It's very unclear which units the single-character abbreviations
-("128K") should go with; some precedents such as `java -Xmx 2G`
-and the GNU tools such as `ls` map these to powers of two, so this
-spec copies that. You can certainly find examples of mapping these
-to powers of ten, though. If you don't like ambiguity, don't use
-the single-letter abbreviations.
-
-Note: any value in zetta/zebi or yotta/yobi will overflow a 64-bit
-integer, and of course large-enough values in any of the units may
-overflow. Most real-world APIs and apps will not support byte
-counts that overflow a 64-bit integer. The huge units are provided
-just to be complete but probably aren't useful in practice. At
-least not in 2014.
-
-### Config object merging and file merging
-
-It may be useful to offer a method to merge two objects. If such a
-method is provided, it should work as if the two objects were
-duplicate values for the same key in the same file. (See the
-section earlier on duplicate key handling.)
-
-As with duplicate keys, an intermediate non-object value "hides"
-earlier object values. So say you merge three objects in this
-order:
-
- - `{ a : { x : 1 } }`  (first priority)
- - `{ a : 42 }` (fallback)
- - `{ a : { y : 2 } }` (another fallback)
-
-The result would be `{ a : { x : 1 } }`. The two objects are not
-merged because they are not "adjacent"; the merging is done in
-pairs, and when `42` is paired with `{ y : 2 }`, `42` simply wins
-and loses all information about what it overrode.
-
-But if you re-ordered like this:
-
- - `{ a : { x : 1 } }`  (first priority)
- - `{ a : { y : 2 } }` (fallback)
- - `{ a : 42 }` (another fallback)
-
-Now the result would be `{ a : { x : 1, y : 2 } }` because the two
-objects are adjacent.
-
-This rule for merging objects loaded from different files is
-_exactly_ the same behavior as for merging duplicate fields in the
-same file. All merging works the same way.
-
-Needless to say, normally it's well-defined whether a config
-setting is supposed to be a number or an object. This kind of
-weird pathology where the two are mixed should not be happening.
-
-The one place where it matters, though, is that it allows you to
-"clear" an object and start over by setting it to null and then
-setting it back to a new object. So this behavior gives people a
-way to get rid of default fallback values they don't want.
-
-### Java properties mapping
-
-It may be useful to merge Java properties data with data loaded
-from JSON or HOCON. See the Java properties spec here:
-https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html#load-java.io.Reader-
-
-Java properties parse as a one-level map from string keys to
-string values.
-
-To convert to HOCON, first split each key on the `.` character,
-keeping any empty strings (including leading and trailing empty
-strings). Note that this is _very different_ from parsing a path
-expression.
-
-The key split on `.` is a series of path elements. So the
-properties key with just `.` is a path with two elements, both of
-them an empty string. `a.` is a path with two elements, `a` and
-empty string.  (Java's `String.split()` does NOT do what you want
-for this.)
-
-It is impossible to represent a key with a `.` in it in a
-properties file.  If a JSON/HOCON key has a `.` in it, which is
-possible if the key is quoted, then there is no way to refer to it
-as a Java property. It is not recommended to name HOCON keys with
-a `.` in them, since it would be confusing at best in any case.
-
-Once you have a path for each value, construct a tree of
-JSON-style objects with the string value of each property located
-at that value's path.
-
-Values from properties files are _always_ strings, even if they
-could be parsed as some other type. Implementations should do type
-conversion if an app asks for an integer, as described in an
-earlier section.
-
-When Java loads a properties file, unfortunately it does not
-preserve the order of the file. As a result, there is an
-intractable case where a single key needs to refer to both a
-parent object and a string value. For example, say the Java
-properties file has:
-
-    a=hello
-    a.b=world
-
-In this case, `a` needs to be both an object and a string value.
-The _object_ must always win in this case... the "object wins"
-rule throws out at most one value (the string) while "string wins"
-would throw out all values in the object. Unfortunately, when
-properties files are mapped to the JSON structure, there is no way
-to access these strings that conflict with objects.
-
-The usual rule in HOCON would be that the later assignment in the
-file wins, rather than "object wins"; but implementing that for
-Java properties would require implementing a custom Java
-properties parser, which is surely not worth it and wouldn't help
-with system properties anyway.
-
-### Conventional configuration files for JVM apps
-
-By convention, JVM apps have two parts to their configuration:
-
- - the _reference_ config is made up of all resources named
-   `reference.conf` on the classpath, merged in the order they
-   are returned by `ClassLoader.getResources()`; also, system
-   property overrides are applied.
- - the _application_ config can be loaded from anywhere an
-   application likes, but by default if the application doesn't
-   provide a config it would be loaded from files
-   `application.{conf,json,properties}` on the classpath and
-   then system property overrides are applied.
- - the reference config may be different for different class
-   loaders, since each jar may provide a `reference.conf`
-   to go with the code in that jar.
- - a single JVM may have multiple application configs if
-   it has multiple modules or contexts of some kind.
-
-The reference config for a given class loader should be merged and
-resolved first, and may be shared among all application configs in
-that class loader. Substitutions in the reference config are not
-affected by any application configs, because the reference config
-should be resolved by itself.
-
-The application config should then be loaded, have the reference
-config added as a fallback, and have substitutions resolved. This
-means the application config can refer to the reference config in
-its substitutions.
-
-### Conventional override by system properties
-
-For an application's config, Java system properties _override_
-settings found in the configuration file. This supports specifying
-config options on the command line.
-
-### Substitution fallback to environment variables
-
-Recall that if a substitution is not present (not even set to
-`null`) within a configuration tree, implementations may search
-for it from external sources. One such source could be environment
-variables.
-
-It's recommended that HOCON keys always use lowercase, because
-environment variables generally are capitalized. This avoids
-naming collisions between environment variables and configuration
-properties. (While on Windows getenv() is generally not
-case-sensitive, the lookup will be case sensitive all the way
-until the env variable fallback lookup is reached).
-
-See also the notes below on Windows and case sensitivity.
-
-An application can explicitly block looking up a substitution in
-the environment by setting a value in the configuration, with the
-same name as the environment variable. You could set `HOME : null`
-in your root object to avoid expanding `${HOME}` from the
-environment, for example.
-
-Environment variables are interpreted as follows:
-
- - env variables set to the empty string are kept as such (set to
-   empty string, rather than undefined)
- - System.getenv throws SecurityException: treated as not present
- - encoding is handled by Java (System.getenv already returns
-   a Unicode string)
- - environment variables always become a string value, though
-   if an app asks for another type automatic type conversion
-   would kick in
-
-### hyphen-separated vs. camelCase
-
-Config keys are encouraged to be `hyphen-separated` rather than
-`camelCase`.
-
-## Note on Java properties similarity
-
-You can write a HOCON file that looks much like a Java properties
-file, and many valid Java properties files will also parse as
-HOCON.
-
-However, HOCON is not a Java properties superset and the corner
-cases work like JSON, not like properties.
-
-Differences include but are probably not limited to:
-
- - certain characters that can be unquoted in properties files
-   have to be placed in JSON-style double-quoted strings in HOCON
- - unquoted strings in HOCON do not support escape sequences
- - unquoted strings in HOCON do not preserve trailing whitespace
- - multi-line unquoted strings using backslash to continue the
-   line are not allowed in HOCON
- - in properties files you can omit the value for a key and it's
-   interpreted as an empty string, in HOCON you cannot omit the
-   value
- - properties files support '!' as a comment character
- - HOCON allows comments on the same line as a key or value, while
-   properties files only recognize comment characters if they
-   occur as the first character on the line
- - HOCON interprets `${}` as a substitution
-
-## Note on Windows and case sensitivity of environment variables
-
-HOCON's lookup of environment variable values is always case sensitive, but
-Linux and Windows differ in their handling of case.
-
-Linux allows one to define multiple environment variables with the same
-name but with different case; so both "PATH" and "Path" may be defined
-simultaneously. HOCON's access to these environment variables on Linux
-is straightforward; ie just make sure you define all your vars with the required case.
-
-Windows is more confusing. Windows environment variables names may contain a
-mix of upper and lowercase characters, eg "Path", however Windows does not
-allow one to define multiple instances of the same name but differing in case.
-Whilst accessing env vars in Windows is case insensitive, accessing env vars in
-HOCON is case sensitive.
-So if you know that you HOCON needs "PATH" then you must ensure that
-the variable is defined as "PATH" rather than some other name such as
-"Path" or "path".
-However, Windows does not allow us to change the case of an existing env var; we can't
-simply redefine the var with an upper case name.
-The only way to ensure that your environment variables have the desired case
-is to first undefine all the env vars that you will depend on then redefine
-them with the required case.
-
-For example, the the ambient environment might have this definition ...
-
-```
-set Path=A;B;C
-```
-.. we just don't know. But if the HOCON needs "PATH", then the start script must
-take a precautionary approach and enforce the necessary case as follows ...
-
-```
-set OLDPATH=%PATH%
-set PATH=
-set PATH=%OLDPATH%
-
-%JAVA_HOME%/bin/java ....
-```
-
-You cannot know what ambient environment variables might exist in the ambient environment
-when your program is invoked, nor what case those definitions might have.
-Therefore the only safe thing to do is redefine all the vars you rely on as shown above.
diff --git a/seatunnel-config/README.md b/seatunnel-config/README.md
deleted file mode 100644
index 7e06f99..0000000
--- a/seatunnel-config/README.md
+++ /dev/null
@@ -1,930 +0,0 @@
-This project is a fork of https://github.com/lightbend/config, its mainly purpose is to solve these problems : 
-
-* [Keep config item order in ConfigObject](https://github.com/lightbend/config/issues/365)
-
-* Change path token separator from `"."` to `"->""`.
-
-* Added `parseObjectForseatunnel()` to parse config objects in `input`, `filter`, `output` for seatunnel.
-
-* Change package name to avoid implementation conflict when using this code with the official typesafe config used by Apache Flink.
-
-
-If you want to do some test, please see:
-
-* Test Main Class: seatunnel-config/src/test/java/org/apache/seatunnel/config/CompleteTests.java
-
-* Config File Example: seatunnel-config/src/test/resources/seatunnel/variables.conf
-
-If you want to Package the jar:
-
-```
-git checkout garyelephant.fea.changed_package_name
-rm -rf ./target
-rm -rf ./config/target
-sbt package
-```
-
-then you can find `config-1.3.3.jar` in `./config/target/`
-
----
-
-Configuration library for JVM languages.
-
-[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.typesafe/config/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.typesafe/config)
-[![Build Status](https://travis-ci.org/lightbend/config.svg?branch=master)](https://travis-ci.org/lightbend/config)
-
-If you have questions or are working on a pull request or just
-curious, please feel welcome to join the chat room:
-[![Join chat https://gitter.im/lightbend/config](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/lightbend/config?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-## Overview
-
- - implemented in plain Java with no dependencies
- - supports files in three formats: Java properties, JSON, and a
-   human-friendly JSON superset
- - merges multiple files across all formats
- - can load from files, URLs, or classpath
- - good support for "nesting" (treat any subtree of the config the
-   same as the whole config)
- - users can override the config with Java system properties,
-    `java -Dmyapp.foo.bar=10`
- - supports configuring an app, with its framework and libraries,
-   all from a single file such as `application.conf`
- - parses duration and size settings, "512k" or "10 seconds"
- - converts types, so if you ask for a boolean and the value
-   is the string "yes", or you ask for a float and the value is
-   an int, it will figure it out.
- - JSON superset features:
-    - comments
-    - includes
-    - substitutions (`"foo" : ${bar}`, `"foo" : Hello ${who}`)
-    - properties-like notation (`a.b=c`)
-    - less noisy, more lenient syntax
-    - substitute environment variables (`logdir=${HOME}/logs`)
- - API based on immutable `Config` instances, for thread safety
-   and easy reasoning about config transformations
- - extensive test coverage
-
-This library limits itself to config files. If you want to load
-config from a database or something, you would need to write some
-custom code. The library has nice support for merging
-configurations so if you build one from a custom source it's easy
-to merge it in.
-
-<!-- START doctoc generated TOC please keep comment here to allow auto update -->
-<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
-**Table of Contents**  *generated with [DocToc](https://github.com/thlorenz/doctoc)*
-
-- [Essential Information](#essential-information)
-  - [License](#license)
-  - [Binary Releases](#binary-releases)
-  - [Release Notes](#release-notes)
-  - [API docs](#api-docs)
-  - [Bugs and Patches](#bugs-and-patches)
-  - [Build](#build)
-- [Using the Library](#using-the-library)
-  - [API Example](#api-example)
-  - [Longer Examples](#longer-examples)
-  - [Immutability](#immutability)
-  - [Schemas and Validation](#schemas-and-validation)
-  - [Standard behavior](#standard-behavior)
-    - [Note about resolving substitutions in `reference.conf` and `application.conf`](#note-about-resolving-substitutions-in-referenceconf-and-applicationconf)
-  - [Merging config trees](#merging-config-trees)
-  - [How to handle defaults](#how-to-handle-defaults)
-  - [Understanding `Config` and `ConfigObject`](#understanding-config-and-configobject)
-  - [ConfigBeanFactory](#configbeanfactory)
-- [Using HOCON, the JSON Superset](#using-hocon-the-json-superset)
-  - [Features of HOCON](#features-of-hocon)
-  - [Examples of HOCON](#examples-of-hocon)
-  - [Uses of Substitutions](#uses-of-substitutions)
-    - [Factor out common values](#factor-out-common-values)
-    - [Inheritance](#inheritance)
-    - [Optional system or env variable overrides](#optional-system-or-env-variable-overrides)
-  - [Concatenation](#concatenation)
-  - [`reference.conf` can't refer to `application.conf`](#referenceconf-cant-refer-to-applicationconf)
-- [Miscellaneous Notes](#miscellaneous-notes)
-  - [Debugging Your Configuration](#debugging-your-configuration)
-  - [Supports Java 8 and Later](#supports-java-8-and-later)
-  - [Rationale for Supported File Formats](#rationale-for-supported-file-formats)
-  - [Other APIs (Wrappers, Ports and Utilities)](#other-apis-wrappers-ports-and-utilities)
-    - [Guice integration](#guice-integration)
-    - [Java (yep!) wrappers for the Java library](#java-yep-wrappers-for-the-java-library)
-    - [Scala wrappers for the Java library](#scala-wrappers-for-the-java-library)
-    - [Clojure wrappers for the Java library](#clojure-wrappers-for-the-java-library)
-    - [Kotlin wrappers for the Java library](#kotlin-wrappers-for-the-java-library)
-    - [Scala port](#scala-port)
-    - [Ruby port](#ruby-port)
-    - [Puppet module](#puppet-module)
-    - [Python port](#python-port)
-    - [C++ port](#c-port)
-    - [JavaScript port](#javascript-port)
-    - [C# port](#c-port-1)
-    - [Linting tool](#linting-tool)
-
-<!-- END doctoc generated TOC please keep comment here to allow auto update -->
-
-## Essential Information
-
-### Binary Releases
-
-Version 1.2.1 and earlier were built for Java 6, while newer
-versions (1.3.0 and above) will be built for Java 8.
-
-You can find published releases on Maven Central.
-
-    <dependency>
-        <groupId>com.typesafe</groupId>
-        <artifactId>config</artifactId>
-        <version>1.3.2</version>
-    </dependency>
-
-sbt dependency:
-
-    libraryDependencies += "com.typesafe" % "config" % "1.3.2"
-
-Link for direct download if you don't use a dependency manager:
-
- - https://mvnrepository.com/artifact/com.typesafe/config
-
-### Release Notes
-
-Please see NEWS.md in this directory,
-https://github.com/lightbend/config/blob/master/NEWS.md
-
-### API docs
-
- - Online: https://lightbend.github.io/config/latest/api/
- - also published in jar form
- - consider reading this README first for an intro
- - for questions about the `.conf` file format, read
-   [HOCON.md](https://github.com/lightbend/config/blob/master/HOCON.md)
-   in this directory
-
-### Bugs and Patches
-
-Report bugs to the GitHub issue tracker. Send patches as pull
-requests on GitHub.
-
-Before we can accept pull requests, you will need to agree to the
-Typesafe Contributor License Agreement online, using your GitHub
-account - it takes 30 seconds.  You can do this at
-https://www.lightbend.com/contribute/cla
-
-Please see
-[CONTRIBUTING](https://github.com/lightbend/config/blob/master/CONTRIBUTING.md)
-for more including how to make a release.
-
-### Build
-
-The build uses sbt and the tests are written in Scala; however,
-the library itself is plain Java and the published jar has no
-Scala dependency.
-
-## Using the Library
-
-### API Example
-    import com.typesafe.config.ConfigFactory
-
-    Config conf = ConfigFactory.load();
-    int bar1 = conf.getInt("foo.bar");
-    Config foo = conf.getConfig("foo");
-    int bar2 = foo.getInt("bar");
-
-### Longer Examples
-
-See the examples in the `examples/` [directory](https://github.com/lightbend/config/tree/master/examples).
-
-You can run these from the sbt console with the commands `project
-config-simple-app-java` and then `run`.
-
-In brief, as shown in the examples:
-
- - libraries should use a `Config` instance provided by the app,
-   if any, and use `ConfigFactory.load()` if no special `Config`
-   is provided. Libraries should put their defaults in a
-   `reference.conf` on the classpath.
- - apps can create a `Config` however they want
-   (`ConfigFactory.load()` is easiest and least-surprising), then
-   provide it to their libraries. A `Config` can be created with
-   the parser methods in `ConfigFactory` or built up from any file
-   format or data source you like with the methods in
-   `ConfigValueFactory`.
-
-### Immutability
-
-Objects are immutable, so methods on `Config` which transform the
-configuration return a new `Config`. Other types such as
-`ConfigParseOptions`, `ConfigResolveOptions`, `ConfigObject`,
-etc. are also immutable. See the
-[API docs](https://lightbend.github.io/config/latest/api/) for
-details of course.
-
-### Schemas and Validation
-
-There isn't a schema language or anything like that. However, two
-suggested tools are:
-
- - use the
-   [checkValid() method](https://lightbend.github.io/config/latest/api/com/typesafe/config/Config.html#checkValid-com.typesafe.config.Config-java.lang.String...-)
- - access your config through a Settings class with a field for
-   each setting, and instantiate it on startup (immediately
-   throwing an exception if any settings are missing)
-
-In Scala, a Settings class might look like:
-
-    class Settings(config: Config) {
-
-        // validate vs. reference.conf
-        config.checkValid(ConfigFactory.defaultReference(), "simple-lib")
-
-        // non-lazy fields, we want all exceptions at construct time
-        val foo = config.getString("simple-lib.foo")
-        val bar = config.getInt("simple-lib.bar")
-    }
-
-See the examples/ directory for a full compilable program using
-this pattern.
-
-### Standard behavior
-
-The convenience method `ConfigFactory.load()` loads the following
-(first-listed are higher priority):
-
-  - system properties
-  - `application.conf` (all resources on classpath with this name)
-  - `application.json` (all resources on classpath with this name)
-  - `application.properties` (all resources on classpath with this
-    name)
-  - `reference.conf` (all resources on classpath with this name)
-
-The idea is that libraries and frameworks should ship with a
-`reference.conf` in their jar. Applications should provide an
-`application.conf`, or if they want to create multiple
-configurations in a single JVM, they could use
-`ConfigFactory.load("myapp")` to load their own `myapp.conf`.
-(Applications _can_ provide a `reference.conf` also if they want,
-but you may not find it necessary to separate it from
-`application.conf`.)
-
-Libraries and frameworks should default to `ConfigFactory.load()`
-if the application does not provide a custom `Config` object. This
-way, libraries will see configuration from `application.conf` and
-users can configure the whole app, with its libraries, in a single
-`application.conf` file.
-
-Libraries and frameworks should also allow the application to
-provide a custom `Config` object to be used instead of the
-default, in case the application needs multiple configurations in
-one JVM or wants to load extra config files from somewhere.  The
-library examples in `examples/` show how to accept a custom config
-while defaulting to `ConfigFactory.load()`.
-
-For applications using `application.{conf,json,properties}`,
-system properties can be used to force a different config source
-(e.g. from command line `-Dconfig.file=path/to/config-file`):
-
- - `config.resource` specifies a resource name - not a
-   basename, i.e. `application.conf` not `application`
- - `config.file` specifies a filesystem path, again
-   it should include the extension, not be a basename
- - `config.url` specifies a URL
-
-These system properties specify a _replacement_ for
-`application.{conf,json,properties}`, not an addition. They only
-affect apps using the default `ConfigFactory.load()`
-configuration. In the replacement config file, you can use
-`include "application"` to include the original default config
-file; after the include statement you could go on to override
-certain settings.
-
-If you set `config.resource`, `config.file`, or `config.url`
-on-the-fly from inside your program (for example with
-`System.setProperty()`), be aware that `ConfigFactory` has some
-internal caches and may not see new values for system
-properties. Use `ConfigFactory.invalidateCaches()` to force-reload
-system properties.
-
-#### Note about resolving substitutions in `reference.conf` and `application.conf`
-
-The substitution syntax `${foo.bar}` will be resolved
-twice. First, all the `reference.conf` files are merged and then
-the result gets resolved. Second, all the `application.conf` are
-layered over the `reference.conf` and the result of that gets
-resolved again.
-
-The implication of this is that the `reference.conf` stack has to
-be self-contained; you can't leave an undefined value `${foo.bar}`
-to be provided by `application.conf`, or refer to `${foo.bar}` in
-a way that you want to allow `application.conf` to
-override. However, `application.conf` can refer to a `${foo.bar}`
-in `reference.conf`.
-
-This can be frustrating at times, but possible workarounds
-include:
-
-  * putting an `application.conf` in a library jar, alongside the
-`reference.conf`, with values intended for later resolution.
-  * putting some logic in code instead of building up values in the
-    config itself.
-
-### Merging config trees
-
-Any two Config objects can be merged with an associative operation
-called `withFallback`, like `merged = firstConfig.withFallback(secondConfig)`.
-
-The `withFallback` operation is used inside the library to merge
-duplicate keys in the same file and to merge multiple files.
-`ConfigFactory.load()` uses it to stack system properties over
-`application.conf` over `reference.conf`.
-
-You can also use `withFallback` to merge in some hardcoded values,
-or to "lift" a subtree up to the root of the configuration; say
-you have something like:
-
-    foo=42
-    dev.foo=57
-    prod.foo=10
-
-Then you could code something like:
-
-    Config devConfig = originalConfig
-                         .getConfig("dev")
-                         .withFallback(originalConfig)
-
-There are lots of ways to use `withFallback`.
-
-### How to handle defaults
-
-Many other configuration APIs allow you to provide a default to
-the getter methods, like this:
-
-    boolean getBoolean(String path, boolean fallback)
-
-Here, if the path has no setting, the fallback would be
-returned. An API could also return `null` for unset values, so you
-would check for `null`:
-
-    // returns null on unset, check for null and fall back
-    Boolean getBoolean(String path)
-
-The methods on the `Config` interface do NOT do this, for two
-major reasons:
-
- 1. If you use a config setting in two places, the default
- fallback value gets cut-and-pasted and typically out of
- sync. This can result in Very Evil Bugs.
- 2. If the getter returns `null` (or `None`, in Scala) then every
- time you get a setting you have to write handling code for
- `null`/`None` and that code will almost always just throw an
- exception. Perhaps more commonly, people forget to check for
- `null` at all, so missing settings result in
- `NullPointerException`.
-
-For most situations, failure to have a setting is simply a bug to fix
-(in either code or the deployment environment). Therefore, if a
-setting is unset, by default the getters on the `Config` interface
-throw an exception.
-
-If you want to allow a setting to be missing from
-`application.conf` in a particular case, then here are some
-options:
-
- 1. Set it in a `reference.conf` included in your library or
- application jar, so there's a default value.
- 2. Use the `Config.hasPath()` method to check in advance whether
- the path exists (rather than checking for `null`/`None` after as
- you might in other APIs).
- 3. Catch and handle `ConfigException.Missing`. NOTE: using an
- exception for control flow like this is much slower than using
- `Config.hasPath()`; the JVM has to do a lot of work to throw
- an exception.
- 4. In your initialization code, generate a `Config` with your
- defaults in it (using something like `ConfigFactory.parseMap()`)
- then fold that default config into your loaded config using
- `withFallback()`, and use the combined config in your
- program. "Inlining" your reference config in the code like this
- is probably less convenient than using a `reference.conf` file,
- but there may be reasons to do it.
- 5. Use `Config.root()` to get the `ConfigObject` for the
- `Config`; `ConfigObject` implements `java.util.Map<String,?>` and
- the `get()` method on `Map` returns null for missing keys. See
- the API docs for more detail on `Config` vs. `ConfigObject`.
- 6. Set the setting to `null` in `reference.conf`, then use
- `Config.getIsNull` and `Config.hasPathOrNull` to handle `null`
- in a special way while still throwing an exception if the setting
- is entirely absent.
-
-The *recommended* path (for most cases, in most apps) is that you
-require all settings to be present in either `reference.conf` or
-`application.conf` and allow `ConfigException.Missing` to be
-thrown if they are not. That's the design intent of the `Config`
-API design.
-
-Consider the "Settings class" pattern with `checkValid()` to
-verify that you have all settings when you initialize the
-app. See the [Schemas and Validation](#schemas-and-validation)
-section of this README for more details on this pattern.
-
-**If you do need a setting to be optional**: checking `hasPath()` in
-advance should be the same amount of code (in Java) as checking
-for `null` afterward, without the risk of `NullPointerException`
-when you forget. In Scala, you could write an enrichment class
-like this to use the idiomatic `Option` syntax:
-
-```scala
-implicit class RichConfig(val underlying: Config) extends AnyVal {
-  def getOptionalBoolean(path: String): Option[Boolean] = if (underlying.hasPath(path)) {
-     Some(underlying.getBoolean(path))
-  } else {
-     None
-  }
-}
-```
-
-Since this library is a Java library it doesn't come with that out
-of the box, of course.
-
-It is understood that sometimes defaults in code make sense. For
-example, if your configuration lets users invent new sections, you
-may not have all paths up front and may be unable to set up
-defaults in `reference.conf` for dynamic paths. The design intent
-of `Config` isn't to *prohibit* inline defaults, but simply to
-recognize that it seems to be the 10% case (rather than the 90%
-case). Even in cases where dynamic defaults are needed, you may
-find that using `withFallback()` to build a complete
-nothing-missing `Config` in one central place in your code keeps
-things tidy.
-
-Whatever you do, please remember not to cut-and-paste default
-values into multiple places in your code. You have been warned!
-:-)
-
-### Understanding `Config` and `ConfigObject`
-
-To read and modify configuration, you'll use the
-[Config](https://lightbend.github.io/config/latest/api/com/typesafe/config/Config.html)
-interface. A `Config` looks at a JSON-equivalent data structure as
-a one-level map from paths to values. So if your JSON looks like
-this:
-
-```
-  "foo" : {
-    "bar" : 42
-    "baz" : 43
-  }
-```
-
-Using the `Config` interface, you could write
-`conf.getInt("foo.bar")`. The `foo.bar` string is called a _path
-expression_
-([HOCON.md](https://github.com/lightbend/config/blob/master/HOCON.md)
-has the syntax details for these expressions). Iterating over this
-`Config`, you would get two entries; `"foo.bar" : 42` and
-`"foo.baz" : 43`. When iterating a `Config` you will not find
-nested `Config` (because everything gets flattened into one
-level).
-
-When looking at a JSON tree as a `Config`, `null` values are
-treated as if they were missing. Iterating over a `Config` will
-skip `null` values.
-
-You can also look at a `Config` in the way most JSON APIs would,
-through the
-[ConfigObject](https://lightbend.github.io/config/latest/api/com/typesafe/config/ConfigObject.html)
-interface. This interface represents an object node in the JSON
-tree. `ConfigObject` instances come in multi-level trees, and the
-keys do not have any syntax (they are just strings, not path
-expressions). Iterating over the above example as a
-`ConfigObject`, you would get one entry `"foo" : { "bar" : 42,
-"baz" : 43 }`, where the value at `"foo"` is another nested
-`ConfigObject`.
-
-In `ConfigObject`, `null` values are visible (distinct from
-missing values), just as they are in JSON.
-
-`ConfigObject` is a subtype of [ConfigValue](https://lightbend.github.io/config/latest/api/com/typesafe/config/ConfigValue.html), where the other
-subtypes are the other JSON types (list, string, number, boolean, null).
-
-`Config` and `ConfigObject` are two ways to look at the same
-internal data structure, and you can convert between them for free
-using
-[Config.root()](https://lightbend.github.io/config/latest/api/com/typesafe/config/Config.html#root--)
-and
-[ConfigObject.toConfig()](https://lightbend.github.io/config/latest/api/com/typesafe/config/ConfigObject.html#toConfig--).
-
-### ConfigBeanFactory
-
-As of version 1.3.0, if you have a Java object that follows
-JavaBean conventions (zero-args constructor, getters and setters),
-you can automatically initialize it from a `Config`.
-
-Use
-`ConfigBeanFactory.create(config.getConfig("subtree-that-matches-bean"),
-MyBean.class)` to do this.
-
-Creating a bean from a `Config` automatically validates that the
-config matches the bean's implied schema. Bean fields can be
-primitive types, typed lists such as `List<Integer>`,
-`java.time.Duration`, `ConfigMemorySize`, or even a raw `Config`,
-`ConfigObject`, or `ConfigValue` (if you'd like to deal with a
-particular value manually).
-
-## Using HOCON, the JSON Superset
-
-The JSON superset is called "Human-Optimized Config Object
-Notation" or HOCON, and files use the suffix `.conf`.  See
-[HOCON.md](https://github.com/lightbend/config/blob/master/HOCON.md)
-in this directory for more detail.
-
-After processing a `.conf` file, the result is always just a JSON
-tree that you could have written (less conveniently) in JSON.
-
-### Features of HOCON
-
-  - Comments, with `#` or `//`
-  - Allow omitting the `{}` around a root object
-  - Allow `=` as a synonym for `:`
-  - Allow omitting the `=` or `:` before a `{` so
-    `foo { a : 42 }`
-  - Allow omitting commas as long as there's a newline
-  - Allow trailing commas after last element in objects and arrays
-  - Allow unquoted strings for keys and values
-  - Unquoted keys can use dot-notation for nested objects,
-    `foo.bar=42` means `foo { bar : 42 }`
-  - Duplicate keys are allowed; later values override earlier,
-    except for object-valued keys where the two objects are merged
-    recursively
-  - `include` feature merges root object in another file into
-    current object, so `foo { include "bar.json" }` merges keys in
-    `bar.json` into the object `foo`
-  - include with no file extension includes any of `.conf`,
-    `.json`, `.properties`
-  - you can include files, URLs, or classpath resources; use
-    `include url("http://example.com")` or `file()` or
-    `classpath()` syntax to force the type, or use just `include
-    "whatever"` to have the library do what you probably mean
-    (Note: `url()`/`file()`/`classpath()` syntax is not supported
-    in Play/Akka 2.0, only in later releases.)
-  - substitutions `foo : ${a.b}` sets key `foo` to the same value
-    as the `b` field in the `a` object
-  - substitutions concatenate into unquoted strings, `foo : the
-    quick ${colors.fox} jumped`
-  - substitutions fall back to environment variables if they don't
-    resolve in the config itself, so `${HOME}` would work as you
-    expect. Also, most configs have system properties merged in so
-    you could use `${user.home}`.
-  - substitutions normally cause an error if unresolved, but
-    there is a syntax `${?a.b}` to permit them to be missing.
-  - `+=` syntax to append elements to arrays, `path += "/bin"`
-  - multi-line strings with triple quotes as in Python or Scala
-
-### Examples of HOCON
-
-All of these are valid HOCON.
-
-Start with valid JSON:
-
-    {
-        "foo" : {
-            "bar" : 10,
-            "baz" : 12
-        }
-    }
-
-Drop root braces:
-
-    "foo" : {
-        "bar" : 10,
-        "baz" : 12
-    }
-
-Drop quotes:
-
-    foo : {
-        bar : 10,
-        baz : 12
-    }
-
-Use `=` and omit it before `{`:
-
-    foo {
-        bar = 10,
-        baz = 12
-    }
-
-Remove commas:
-
-    foo {
-        bar = 10
-        baz = 12
-    }
-
-Use dotted notation for unquoted keys:
-
-    foo.bar=10
-    foo.baz=12
-
-Put the dotted-notation fields on a single line:
-
-    foo.bar=10, foo.baz=12
-
-The syntax is well-defined (including handling of whitespace and
-escaping). But it handles many reasonable ways you might want to
-format the file.
-
-Note that while you can write HOCON that looks a lot like a Java
-properties file (and many properties files will parse as HOCON),
-the details of escaping, whitespace handling, comments, and so
-forth are more like JSON. The spec (see HOCON.md in this
-directory) has some more detailed notes on this topic.
-
-### Uses of Substitutions
-
-The `${foo.bar}` substitution feature lets you avoid cut-and-paste
-in some nice ways.
-
-#### Factor out common values
-
-This is the obvious use,
-
-    standard-timeout = 10ms
-    foo.timeout = ${standard-timeout}
-    bar.timeout = ${standard-timeout}
-
-#### Inheritance
-
-If you duplicate a field with an object value, then the objects
-are merged with last-one-wins. So:
-
-    foo = { a : 42, c : 5 }
-    foo = { b : 43, c : 6 }
-
-means the same as:
-
-    foo = { a : 42, b : 43, c : 6 }
-
-You can take advantage of this for "inheritance":
-
-    data-center-generic = { cluster-size = 6 }
-    data-center-east = ${data-center-generic}
-    data-center-east = { name = "east" }
-    data-center-west = ${data-center-generic}
-    data-center-west = { name = "west", cluster-size = 8 }
-
-Using `include` statements you could split this across multiple
-files, too.
-
-If you put two objects next to each other (close brace of the first
-on the same line with open brace of the second), they are merged, so
-a shorter way to write the above "inheritance" example would be:
-
-    data-center-generic = { cluster-size = 6 }
-    data-center-east = ${data-center-generic} { name = "east" }
-    data-center-west = ${data-center-generic} { name = "west", cluster-size = 8 }
-
-#### Optional system or env variable overrides
-
-In default uses of the library, exact-match system properties
-already override the corresponding config properties.  However,
-you can add your own overrides, or allow environment variables to
-override, using the `${?foo}` substitution syntax.
-
-    basedir = "/whatever/whatever"
-    basedir = ${?FORCED_BASEDIR}
-
-Here, the override field `basedir = ${?FORCED_BASEDIR}` simply
-vanishes if there's no value for `FORCED_BASEDIR`, but if you set
-an environment variable `FORCED_BASEDIR` for example, it would be
-used.
-
-A natural extension of this idea is to support several different
-environment variable names or system property names, if you aren't
-sure which one will exist in the target environment.
-
-Object fields and array elements with a `${?foo}` substitution
-value just disappear if the substitution is not found:
-
-    // this array could have one or two elements
-    path = [ "a", ${?OPTIONAL_A} ]
-
-### Concatenation
-
-Values _on the same line_ are concatenated (for strings and
-arrays) or merged (for objects).
-
-This is why unquoted strings work, here the number `42` and the
-string `foo` are concatenated into a string `42 foo`:
-
-    key : 42 foo
-
-When concatenating values into a string, leading and trailing
-whitespace is stripped but whitespace between values is kept.
-
-Unquoted strings also support substitutions of course:
-
-    tasks-url : ${base-url}/tasks
-
-A concatenation can refer to earlier values of the same field:
-
-    path : "/bin"
-    path : ${path}":/usr/bin"
-
-Arrays can be concatenated as well:
-
-    path : [ "/bin" ]
-    path : ${path} [ "/usr/bin" ]
-
-There is a shorthand for appending to arrays:
-
-    // equivalent to: path = ${?path} [ "/usr/bin" ]
-    path += "/usr/bin"
-
-To prepend or insert into an array, there is no shorthand.
-
-When objects are "concatenated," they are merged, so object
-concatenation is just a shorthand for defining the same object
-twice. The long way (mentioned earlier) is:
-
-    data-center-generic = { cluster-size = 6 }
-    data-center-east = ${data-center-generic}
-    data-center-east = { name = "east" }
-
-The concatenation-style shortcut is:
-
-    data-center-generic = { cluster-size = 6 }
-    data-center-east = ${data-center-generic} { name = "east" }
-
-When concatenating objects and arrays, newlines are allowed
-_inside_ each object or array, but not between them.
-
-Non-newline whitespace is never a field or element separator. So
-`[ 1 2 3 4 ]` is an array with one unquoted string element
-`"1 2 3 4"`. To get an array of four numbers you need either commas or
-newlines separating the numbers.
-
-See the spec for full details on concatenation.
-
-Note: Play/Akka 2.0 have an earlier version that supports string
-concatenation, but not object/array concatenation. `+=` does not
-work in Play/Akka 2.0 either. Post-2.0 versions support these
-features.
-
-### `reference.conf` can't refer to `application.conf`
-
-Please see <a
-href="#note-about-resolving-substitutions-in-referenceconf-and-applicationconf">this
-earlier section</a>; all `reference.conf` have substitutions
-resolved first, without `application.conf` in the stack, so the
-reference stack has to be self-contained.
-
-## Miscellaneous Notes
-
-### Debugging Your Configuration
-
-If you have trouble with your configuration, some useful tips.
-
- - Set the Java system property `-Dconfig.trace=loads` to get
-   output on stderr describing each file that is loaded.
-   Note: this feature is not included in the older version in
-   Play/Akka 2.0.
- - Use `myConfig.root().render()` to get a `Config` printed out as a
-   string with comments showing where each value came from.
-
-### Supports Java 8 and Later
-
-Currently the library is maintained against Java 8, but
-version 1.2.1 and earlier will work with Java 6.
-
-Please use 1.2.1 if you need Java 6 support, though some people
-have expressed interest in a branch off of 1.3.x supporting
-Java 7. If you want to work on that branch you might bring it up
-on [chat](https://gitter.im/lightbend/config). We can release a
-jar for Java 7 if someone(s) steps up to maintain the branch. The
-master branch does not use Java 8 "gratuitously" but some APIs
-that use Java 8 types will need to be removed.
-
-### Rationale for Supported File Formats
-
-(For the curious.)
-
-The three file formats each have advantages.
-
- - Java `.properties`:
-   - Java standard, built in to JVM
-   - Supported by many tools such as IDEs
- - JSON:
-   - easy to generate programmatically
-   - well-defined and standard
-   - bad for human maintenance, with no way to write comments,
-     and no mechanisms to avoid duplication of similar config
-     sections
- - HOCON/`.conf`:
-   - nice for humans to read, type, and maintain, with more
-     lenient syntax
-   - built-in tools to avoid cut-and-paste
-   - ways to refer to the system environment, such as system
-     properties and environment variables
-
-The idea would be to use JSON if you're writing a script to spit
-out config, and use HOCON if you're maintaining config by hand.
-If you're doing both, then mix the two.
-
-Two alternatives to HOCON syntax could be:
-
-  - YAML is also a JSON superset and has a mechanism for adding
-    custom types, so the include statements in HOCON could become
-    a custom type tag like `!include`, and substitutions in HOCON
-    could become a custom tag such as `!subst`, for example. The
-    result is somewhat clunky to write, but would have the same
-    in-memory representation as the HOCON approach.
-  - Put a syntax inside JSON strings, so you might write something
-    like `"$include" : "filename"` or allow `"foo" : "${bar}"`.
-    This is a way to tunnel new syntax through a JSON parser, but
-    other than the implementation benefit (using a standard JSON
-    parser), it doesn't really work. It's a bad syntax for human
-    maintenance, and it's not valid JSON anymore because properly
-    interpreting it requires treating some valid JSON strings as
-    something other than plain strings. A better approach is to
-    allow mixing true JSON files into the config but also support
-    a nicer format.
-
-### Other APIs (Wrappers, Ports and Utilities)
-
-This may not be comprehensive - if you'd like to add mention of
-your wrapper, just send a pull request for this README. We would
-love to know what you're doing with this library or with the HOCON
-format.
-
-#### Guice integration
-  * Typesafe Config Guice https://github.com/racc/typesafeconfig-guice
-
-#### Java (yep!) wrappers for the Java library
-
-  * tscfg https://github.com/carueda/tscfg
-
-#### Scala wrappers for the Java library
-
-  * Ficus https://github.com/ceedubs/ficus
-  * configz https://github.com/arosien/configz
-  * configs https://github.com/kxbmap/configs
-  * config-annotation https://github.com/zhongl/config-annotation
-  * PureConfig https://github.com/pureconfig/pureconfig
-  * Simple Scala Config https://github.com/ElderResearch/ssc
-  * konfig https://github.com/vpon/konfig
-  * ScalaConfig https://github.com/andr83/scalaconfig
-  * static-config https://github.com/Krever/static-config
-  * validated-config https://github.com/carlpulley/validated-config
-  * Cedi Config https://github.com/ccadllc/cedi-config
-  * Cfg https://github.com/carueda/cfg
-  * circe-config https://github.com/circe/circe-config
-
-#### Clojure wrappers for the Java library
-
-  * beamly-core.config https://github.com/beamly/beamly-core.config
-
-#### Kotlin wrappers for the Java library
-  * config4k https://github.com/config4k/config4k
-
-#### Scala port
-
-  * SHocon https://github.com/unicredit/shocon (work with both Scala and Scala.Js)
-
-#### Ruby port
-
-   * https://github.com/puppetlabs/ruby-hocon
-
-#### Puppet module
-
-   * Manage your HOCON configuration files with Puppet!: https://forge.puppetlabs.com/puppetlabs/hocon
-
-#### Python port
-
-   * pyhocon https://github.com/chimpler/pyhocon
-
-#### C++ port
-
-   * https://github.com/puppetlabs/cpp-hocon
-
-#### JavaScript port
-
-  * https://github.com/yellowblood/hocon-js (missing features, under development)
-
-#### C# port
-
-  * https://github.com/akkadotnet/HOCON
-
-#### Linting tool
-
-   * A web based linting tool http://www.hoconlint.com/
-   
-# Maintanance notes
-
-## License
-
-The license is Apache 2.0, see LICENSE-2.0.txt.
-
-## Maintained by 
-
-This project is maintained mostly by [@havocp](https://github.com/havocp) and [@akka-team](https://github.com/orgs/lightbend/teams/akka-team/members).
-
-Feel free to ping above maintainers for code review or discussions. Pull requests are very welcome–thanks in advance!
diff --git a/seatunnel-config/pom.xml b/seatunnel-config/pom.xml
index a0488ba..3874d71 100644
--- a/seatunnel-config/pom.xml
+++ b/seatunnel-config/pom.xml
@@ -35,6 +35,94 @@
         <maven.compiler.source>${java.version}</maven.compiler.source>
         <maven.compiler.target>${java.version}</maven.compiler.target>
         <skip.pmd.check>true</skip.pmd.check>
+        <seatunnel.shade.package>org.apache.seatunnel.shade</seatunnel.shade.package>
     </properties>
 
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.typesafe</groupId>
+            <artifactId>config</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+
+        <finalName>${project.artifactId}-${project.version}</finalName>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <configuration>
+                    <minimizeJar>true</minimizeJar>
+                    <createSourcesJar>true</createSourcesJar>
+                    <shadeSourcesContent>true</shadeSourcesContent>
+                    <shadedArtifactAttached>false</shadedArtifactAttached>
+                    <filters>
+                        <filter>
+                            <artifact>com.typesafe:config</artifact>
+                            <includes>
+                                <include>**</include>
+                            </includes>
+                            <excludes>
+                                <exclude>META-INF/MANIFEST.MF</exclude>
+                                <exclude>META-INF/NOTICE</exclude>
+                                <exclude>com/typesafe/config/ConfigParseOptions.class</exclude>
+                                <exclude>com/typesafe/config/impl/ConfigParser.class</exclude>
+                                <exclude>com/typesafe/config/impl/ConfigNodePath.class</exclude>
+                                <exclude>com/typesafe/config/impl/PathParser.class</exclude>
+                            </excludes>
+                        </filter>
+                    </filters>
+                    <relocations>
+                        <relocation>
+                            <pattern>com.typesafe.config</pattern>
+                            <shadedPattern>${seatunnel.shade.package}.com.typesafe.config</shadedPattern>
+                        </relocation>
+                    </relocations>
+                    <transformers>
+                        <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer"/>
+                        <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer"/>
+                    </transformers>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>compile</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>attach-artifact</goal>
+                        </goals>
+                        <configuration>
+                            <artifacts>
+                                <artifact>
+                                    <file>${basedir}/target/${project.artifactId}-${project.version}.jar</file>
+                                    <type>jar</type>
+                                    <classifier>optional</classifier>
+                                </artifact>
+                            </artifacts>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+        </plugins>
+    </build>
 </project>
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigParseOptions.java b/seatunnel-config/src/main/java/com/typesafe/config/ConfigParseOptions.java
similarity index 90%
rename from seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigParseOptions.java
rename to seatunnel-config/src/main/java/com/typesafe/config/ConfigParseOptions.java
index 5e6904c..a0895c6 100644
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigParseOptions.java
+++ b/seatunnel-config/src/main/java/com/typesafe/config/ConfigParseOptions.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.seatunnel.config;
+package com.typesafe.config;
 
 /**
  * A set of options related to parsing.
@@ -76,9 +76,10 @@ public final class ConfigParseOptions {
     public ConfigParseOptions setSyntax(ConfigSyntax syntax) {
         if (this.syntax == syntax) {
             return this;
-        }
-        return new ConfigParseOptions(syntax, this.originDescription, this.allowMissing,
+        } else {
+            return new ConfigParseOptions(syntax, this.originDescription, this.allowMissing,
                 this.includer, this.classLoader);
+        }
     }
 
     /**
@@ -104,11 +105,13 @@ public final class ConfigParseOptions {
         // findbugs complains about == here but is wrong, do not "fix"
         if (this.originDescription == originDescription) {
             return this;
-        } else if (this.originDescription != null && originDescription != null && this.originDescription.equals(originDescription)) {
+        } else if (this.originDescription != null && originDescription != null
+            && this.originDescription.equals(originDescription)) {
             return this;
-        }
-        return new ConfigParseOptions(this.syntax, originDescription, this.allowMissing,
+        } else {
+            return new ConfigParseOptions(this.syntax, originDescription, this.allowMissing,
                 this.includer, this.classLoader);
+        }
     }
 
     /**
@@ -126,8 +129,9 @@ public final class ConfigParseOptions {
     ConfigParseOptions withFallbackOriginDescription(String originDescription) {
         if (this.originDescription == null) {
             return setOriginDescription(originDescription);
+        } else {
+            return this;
         }
-        return this;
     }
 
     /**
@@ -142,9 +146,10 @@ public final class ConfigParseOptions {
     public ConfigParseOptions setAllowMissing(boolean allowMissing) {
         if (this.allowMissing == allowMissing) {
             return this;
-        }
-        return new ConfigParseOptions(this.syntax, this.originDescription, allowMissing,
+        } else {
+            return new ConfigParseOptions(this.syntax, this.originDescription, allowMissing,
                 this.includer, this.classLoader);
+        }
     }
 
     /**
@@ -166,9 +171,10 @@ public final class ConfigParseOptions {
     public ConfigParseOptions setIncluder(ConfigIncluder includer) {
         if (this.includer == includer) {
             return this;
-        }
-        return new ConfigParseOptions(this.syntax, this.originDescription, this.allowMissing,
+        } else {
+            return new ConfigParseOptions(this.syntax, this.originDescription, this.allowMissing,
                 includer, this.classLoader);
+        }
     }
 
     /**
@@ -188,8 +194,9 @@ public final class ConfigParseOptions {
             return this;
         } else if (this.includer != null) {
             return setIncluder(includer.withFallback(this.includer));
+        } else {
+            return setIncluder(includer);
         }
-        return setIncluder(includer);
     }
 
     /**
@@ -208,8 +215,9 @@ public final class ConfigParseOptions {
             return this;
         } else if (this.includer != null) {
             return setIncluder(this.includer.withFallback(includer));
+        } else {
+            return setIncluder(includer);
         }
-        return setIncluder(includer);
     }
 
     /**
@@ -232,9 +240,10 @@ public final class ConfigParseOptions {
     public ConfigParseOptions setClassLoader(ClassLoader loader) {
         if (this.classLoader == loader) {
             return this;
-        }
-        return new ConfigParseOptions(this.syntax, this.originDescription, this.allowMissing,
+        } else {
+            return new ConfigParseOptions(this.syntax, this.originDescription, this.allowMissing,
                 this.includer, loader);
+        }
     }
 
     /**
@@ -247,7 +256,8 @@ public final class ConfigParseOptions {
     public ClassLoader getClassLoader() {
         if (this.classLoader == null) {
             return Thread.currentThread().getContextClassLoader();
+        } else {
+            return this.classLoader;
         }
-        return this.classLoader;
     }
 }
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigNodePath.java b/seatunnel-config/src/main/java/com/typesafe/config/impl/ConfigNodePath.java
similarity index 86%
rename from seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigNodePath.java
rename to seatunnel-config/src/main/java/com/typesafe/config/impl/ConfigNodePath.java
index e5486b3..609e4f8 100644
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigNodePath.java
+++ b/seatunnel-config/src/main/java/com/typesafe/config/impl/ConfigNodePath.java
@@ -15,10 +15,10 @@
  * limitations under the License.
  */
 
-package org.apache.seatunnel.config.impl;
+package com.typesafe.config.impl;
 
-import org.apache.seatunnel.config.ConfigException;
-import org.apache.seatunnel.config.ConfigParseOptions;
+import com.typesafe.config.ConfigException;
+import com.typesafe.config.ConfigParseOptions;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -46,7 +46,7 @@ final class ConfigNodePath extends AbstractConfigNode {
         ArrayList<Token> tokensCopy = new ArrayList<Token>(tokens);
         for (int i = 0; i < tokensCopy.size(); i++) {
             if (Tokens.isUnquotedText(tokensCopy.get(i)) &&
-                    tokensCopy.get(i).tokenText().equals(ConfigParseOptions.PATH_TOKEN_SEPARATOR)) {
+                tokensCopy.get(i).tokenText().equals(ConfigParseOptions.PATH_TOKEN_SEPARATOR)) {
                 periodCount++;
             }
 
@@ -61,7 +61,7 @@ final class ConfigNodePath extends AbstractConfigNode {
         ArrayList<Token> tokensCopy = new ArrayList<Token>(tokens);
         for (int i = 0; i < tokensCopy.size(); i++) {
             if (Tokens.isUnquotedText(tokensCopy.get(i)) &&
-                    tokensCopy.get(i).tokenText().equals(ConfigParseOptions.PATH_TOKEN_SEPARATOR)) {
+                tokensCopy.get(i).tokenText().equals(ConfigParseOptions.PATH_TOKEN_SEPARATOR)) {
                 return new ConfigNodePath(path.subPath(0, 1), tokensCopy.subList(0, i));
             }
         }
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigParser.java b/seatunnel-config/src/main/java/com/typesafe/config/impl/ConfigParser.java
similarity index 87%
rename from seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigParser.java
rename to seatunnel-config/src/main/java/com/typesafe/config/impl/ConfigParser.java
index 3e0e7b2..02c21a1 100644
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigParser.java
+++ b/seatunnel-config/src/main/java/com/typesafe/config/impl/ConfigParser.java
@@ -15,15 +15,14 @@
  * limitations under the License.
  */
 
-package org.apache.seatunnel.config.impl;
+package com.typesafe.config.impl;
 
-import org.apache.seatunnel.config.ConfigException;
-import org.apache.seatunnel.config.ConfigException.BugOrBroken;
-import org.apache.seatunnel.config.ConfigIncludeContext;
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigParseOptions;
-import org.apache.seatunnel.config.ConfigSyntax;
-import org.apache.seatunnel.config.ConfigValueFactory;
+import com.typesafe.config.ConfigException;
+import com.typesafe.config.ConfigIncludeContext;
+import com.typesafe.config.ConfigOrigin;
+import com.typesafe.config.ConfigParseOptions;
+import com.typesafe.config.ConfigSyntax;
+import com.typesafe.config.ConfigValueFactory;
 
 import java.io.File;
 import java.net.MalformedURLException;
@@ -41,7 +40,7 @@ final class ConfigParser {
                                      ConfigOrigin origin, ConfigParseOptions options,
                                      ConfigIncludeContext includeContext) {
         ParseContext context = new ParseContext(options.getSyntax(), origin, document,
-                SimpleIncluder.makeFull(options.getIncluder()), includeContext);
+            SimpleIncluder.makeFull(options.getIncluder()), includeContext);
         return context.parse();
     }
 
@@ -77,7 +76,7 @@ final class ConfigParser {
         private AbstractConfigValue parseConcatenation(ConfigNodeConcatenation n) {
             // this trick is not done in JSON
             if (flavor == ConfigSyntax.JSON) {
-                throw new BugOrBroken("Found a concatenation node in JSON");
+                throw new ConfigException.BugOrBroken("Found a concatenation node in JSON");
             }
 
             List<AbstractConfigValue> values = new ArrayList<AbstractConfigValue>();
@@ -109,8 +108,9 @@ final class ConfigParser {
             // pathStack has top of stack at front
             if (pathStack.isEmpty()) {
                 throw new ConfigException.BugOrBroken("Bug in parser; tried to get current path when at root");
+            } else {
+                return new Path(pathStack.descendingIterator());
             }
-            return new Path(pathStack.descendingIterator());
         }
 
         private AbstractConfigValue parseValue(AbstractConfigNodeValue n, List<String> comments) {
@@ -125,13 +125,13 @@ final class ConfigParser {
                 Path path = pathStack.peekFirst();
 
                 if (path != null
-                        && ("input".equals(path.first())
-                        || "filter".equals(path.first())
-                        || "output".equals(path.first())
-                        || "source".equals(path.first())
-                        || "transform".equals(path.first())
-                        || "sink".equals(path.first()))) {
-                    v = parseObjectForSeatunnel((ConfigNodeObject) n);
+                    && ("input".equals(path.first())
+                    || "filter".equals(path.first())
+                    || "output".equals(path.first())
+                    || "source".equals(path.first())
+                    || "transform".equals(path.first())
+                    || "sink".equals(path.first()))) {
+                    v = parseObjectForWaterdrop((ConfigNodeObject) n);
                 } else {
                     v = parseObject((ConfigNodeObject) n);
                 }
@@ -181,11 +181,11 @@ final class ConfigParser {
             ListIterator<String> i = keys.listIterator(keys.size());
             String deepest = i.previous();
             AbstractConfigObject o = new SimpleConfigObject(value.origin().withComments(null),
-                    Collections.<String, AbstractConfigValue>singletonMap(
-                            deepest, value));
+                Collections.<String, AbstractConfigValue>singletonMap(
+                    deepest, value));
             while (i.hasPrevious()) {
                 Map<String, AbstractConfigValue> m = Collections.<String, AbstractConfigValue>singletonMap(
-                        i.previous(), o);
+                    i.previous(), o);
                 o = new SimpleConfigObject(value.origin().withComments(null), m);
             }
 
@@ -210,7 +210,7 @@ final class ConfigParser {
 
                 case FILE:
                     obj = (AbstractConfigObject) includer.includeFile(cic,
-                            new File(n.name()));
+                        new File(n.name()));
                     break;
 
                 case CLASSPATH:
@@ -219,7 +219,7 @@ final class ConfigParser {
 
                 case HEURISTIC:
                     obj = (AbstractConfigObject) includer
-                            .include(cic, n.name());
+                        .include(cic, n.name());
                     break;
 
                 default:
@@ -231,8 +231,8 @@ final class ConfigParser {
             // See https://github.com/lightbend/config/issues/160
             if (arrayCount > 0 && obj.resolveStatus() != ResolveStatus.RESOLVED) {
                 throw parseError("Due to current limitations of the config parser, when an include statement is nested inside a list value, "
-                        + "${} substitutions inside the included file cannot be resolved correctly. Either move the include outside of the list value or "
-                        + "remove the ${} statements from the included file.");
+                    + "${} substitutions inside the included file cannot be resolved correctly. Either move the include outside of the list value or "
+                    + "remove the ${} statements from the included file.");
             }
 
             if (!pathStack.isEmpty()) {
@@ -251,7 +251,7 @@ final class ConfigParser {
             }
         }
 
-        private SimpleConfigList parseObjectForSeatunnel(ConfigNodeObject n) {
+        private SimpleConfigList parseObjectForWaterdrop(ConfigNodeObject n) {
 
             Map<String, AbstractConfigValue> values = new LinkedHashMap<String, AbstractConfigValue>();
             List<AbstractConfigValue> valuesList = new ArrayList<AbstractConfigValue>();
@@ -265,8 +265,7 @@ final class ConfigParser {
                 if (node instanceof ConfigNodeComment) {
                     lastWasNewline = false;
                     comments.add(((ConfigNodeComment) node).commentText());
-                } else if (node instanceof ConfigNodeSingleToken
-                        && Tokens.isNewline(((ConfigNodeSingleToken) node).token())) {
+                } else if (node instanceof ConfigNodeSingleToken && Tokens.isNewline(((ConfigNodeSingleToken) node).token())) {
                     lineNumber++;
                     if (lastWasNewline) {
                         // Drop all comments if there was a blank line and start a new comment block
@@ -290,8 +289,8 @@ final class ConfigParser {
                         // https://github.com/lightbend/config/issues/160
                         if (arrayCount > 0) {
                             throw parseError("Due to current limitations of the config parser, += does not work nested inside a list. "
-                                    + "+= expands to a ${} substitution and the path in ${} cannot currently refer to list elements. "
-                                    + "You might be able to move the += outside of the list and then refer to it from inside the list with ${}.");
+                                + "+= expands to a ${} substitution and the path in ${} cannot currently refer to list elements. "
+                                + "You might be able to move the += outside of the list and then refer to it from inside the list with ${}.");
                         }
 
                         // because we will put it in an array after the fact so
@@ -313,9 +312,9 @@ final class ConfigParser {
 
                         List<AbstractConfigValue> concat = new ArrayList<AbstractConfigValue>(2);
                         AbstractConfigValue previousRef = new ConfigReference(newValue.origin(),
-                                new SubstitutionExpression(fullCurrentPath(), true /* optional */));
+                            new SubstitutionExpression(fullCurrentPath(), true /* optional */));
                         AbstractConfigValue list = new SimpleConfigList(newValue.origin(),
-                                Collections.singletonList(newValue));
+                            Collections.singletonList(newValue));
                         concat.add(previousRef);
                         concat.add(list);
                         newValue = ConfigConcatenation.concatenate(concat);
@@ -328,7 +327,7 @@ final class ConfigParser {
                             if (nodes.get(i) instanceof ConfigNodeComment) {
                                 ConfigNodeComment comment = (ConfigNodeComment) nodes.get(i);
                                 newValue = newValue.withOrigin(newValue.origin().appendComments(
-                                        Collections.singletonList(comment.commentText())));
+                                    Collections.singletonList(comment.commentText())));
                                 break;
                             } else if (nodes.get(i) instanceof ConfigNodeSingleToken) {
                                 ConfigNodeSingleToken curr = (ConfigNodeSingleToken) nodes.get(i);
@@ -361,11 +360,11 @@ final class ConfigParser {
                     } else {
                         if (flavor == ConfigSyntax.JSON) {
                             throw new ConfigException.BugOrBroken(
-                                    "somehow got multi-element path in JSON mode");
+                                "somehow got multi-element path in JSON mode");
                         }
 
                         AbstractConfigObject obj = createValueUnderPath(
-                                remaining, newValue);
+                            remaining, newValue);
 
                         Map<String, String> m = Collections.singletonMap("plugin_name", key);
                         obj = obj.withFallback(ConfigValueFactory.fromMap(m));
@@ -391,8 +390,7 @@ final class ConfigParser {
                 if (node instanceof ConfigNodeComment) {
                     lastWasNewline = false;
                     comments.add(((ConfigNodeComment) node).commentText());
-                } else if (node instanceof ConfigNodeSingleToken
-                        && Tokens.isNewline(((ConfigNodeSingleToken) node).token())) {
+                } else if (node instanceof ConfigNodeSingleToken && Tokens.isNewline(((ConfigNodeSingleToken) node).token())) {
                     lineNumber++;
                     if (lastWasNewline) {
                         // Drop all comments if there was a blank line and start a new comment block
@@ -416,8 +414,8 @@ final class ConfigParser {
                         // https://github.com/lightbend/config/issues/160
                         if (arrayCount > 0) {
                             throw parseError("Due to current limitations of the config parser, += does not work nested inside a list. "
-                                    + "+= expands to a ${} substitution and the path in ${} cannot currently refer to list elements. "
-                                    + "You might be able to move the += outside of the list and then refer to it from inside the list with ${}.");
+                                + "+= expands to a ${} substitution and the path in ${} cannot currently refer to list elements. "
+                                + "You might be able to move the += outside of the list and then refer to it from inside the list with ${}.");
                         }
 
                         // because we will put it in an array after the fact so
@@ -439,9 +437,9 @@ final class ConfigParser {
 
                         List<AbstractConfigValue> concat = new ArrayList<AbstractConfigValue>(2);
                         AbstractConfigValue previousRef = new ConfigReference(newValue.origin(),
-                                new SubstitutionExpression(fullCurrentPath(), true /* optional */));
+                            new SubstitutionExpression(fullCurrentPath(), true /* optional */));
                         AbstractConfigValue list = new SimpleConfigList(newValue.origin(),
-                                Collections.singletonList(newValue));
+                            Collections.singletonList(newValue));
                         concat.add(previousRef);
                         concat.add(list);
                         newValue = ConfigConcatenation.concatenate(concat);
@@ -454,7 +452,7 @@ final class ConfigParser {
                             if (nodes.get(i) instanceof ConfigNodeComment) {
                                 ConfigNodeComment comment = (ConfigNodeComment) nodes.get(i);
                                 newValue = newValue.withOrigin(newValue.origin().appendComments(
-                                        Collections.singletonList(comment.commentText())));
+                                    Collections.singletonList(comment.commentText())));
                                 break;
                             } else if (nodes.get(i) instanceof ConfigNodeSingleToken) {
                                 ConfigNodeSingleToken curr = (ConfigNodeSingleToken) nodes.get(i);
@@ -487,8 +485,9 @@ final class ConfigParser {
 
                             if (flavor == ConfigSyntax.JSON) {
                                 throw parseError("JSON does not allow duplicate fields: '"
-                                        + key + "' was already seen at "
-                                        + existing.origin().description());
+                                    + key
+                                    + "' was already seen at "
+                                    + existing.origin().description());
                             } else {
                                 newValue = newValue.withFallback(existing);
                             }
@@ -497,11 +496,11 @@ final class ConfigParser {
                     } else {
                         if (flavor == ConfigSyntax.JSON) {
                             throw new ConfigException.BugOrBroken(
-                                    "somehow got multi-element path in JSON mode");
+                                "somehow got multi-element path in JSON mode");
                         }
 
                         AbstractConfigObject obj = createValueUnderPath(
-                                remaining, newValue);
+                            remaining, newValue);
                         AbstractConfigValue existing = values.get(key);
                         if (existing != null) {
                             obj = obj.withFallback(existing);
@@ -529,8 +528,7 @@ final class ConfigParser {
                 if (node instanceof ConfigNodeComment) {
                     comments.add(((ConfigNodeComment) node).commentText());
                     lastWasNewLine = false;
-                } else if (node instanceof ConfigNodeSingleToken
-                        && Tokens.isNewline(((ConfigNodeSingleToken) node).token())) {
+                } else if (node instanceof ConfigNodeSingleToken && Tokens.isNewline(((ConfigNodeSingleToken) node).token())) {
                     lineNumber++;
                     if (lastWasNewLine && v == null) {
                         comments.clear();
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/PathParser.java b/seatunnel-config/src/main/java/com/typesafe/config/impl/PathParser.java
similarity index 89%
rename from seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/PathParser.java
rename to seatunnel-config/src/main/java/com/typesafe/config/impl/PathParser.java
index 9d4d283..c23feab 100644
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/PathParser.java
+++ b/seatunnel-config/src/main/java/com/typesafe/config/impl/PathParser.java
@@ -15,13 +15,13 @@
  * limitations under the License.
  */
 
-package org.apache.seatunnel.config.impl;
+package com.typesafe.config.impl;
 
-import org.apache.seatunnel.config.ConfigException.BadPath;
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigParseOptions;
-import org.apache.seatunnel.config.ConfigSyntax;
-import org.apache.seatunnel.config.ConfigValueType;
+import com.typesafe.config.ConfigException;
+import com.typesafe.config.ConfigOrigin;
+import com.typesafe.config.ConfigParseOptions;
+import com.typesafe.config.ConfigSyntax;
+import com.typesafe.config.ConfigValueType;
 
 import java.io.StringReader;
 import java.util.ArrayList;
@@ -58,7 +58,7 @@ final class PathParser {
 
         try {
             Iterator<Token> tokens = Tokenizer.tokenize(API_ORIGIN, reader,
-                    flavor);
+                flavor);
             tokens.next(); // drop START
             return parsePathNodeExpression(tokens, API_ORIGIN, path, flavor);
         } finally {
@@ -76,7 +76,7 @@ final class PathParser {
 
         try {
             Iterator<Token> tokens = Tokenizer.tokenize(API_ORIGIN, reader,
-                    ConfigSyntax.CONF);
+                ConfigSyntax.CONF);
             tokens.next(); // drop START
             return parsePathExpression(tokens, API_ORIGIN, path);
         } finally {
@@ -116,8 +116,8 @@ final class PathParser {
         buf.add(new Element("", false));
 
         if (!expression.hasNext()) {
-            throw new BadPath(origin, originalText,
-                    "Expecting a field name or path here, but got nothing");
+            throw new ConfigException.BadPath(origin, originalText,
+                "Expecting a field name or path here, but got nothing");
         }
 
         while (expression.hasNext()) {
@@ -174,11 +174,12 @@ final class PathParser {
                     }
                     text = Tokens.getUnquotedText(t);
                 } else {
-                    throw new BadPath(
-                            origin,
-                            originalText,
-                            "Token not allowed in path expression: "
-                                    + t + " (you can double-quote this token if you really want it here)");
+                    throw new ConfigException.BadPath(
+                        origin,
+                        originalText,
+                        "Token not allowed in path expression: "
+                            + t
+                            + " (you can double-quote this token if you really want it here)");
                 }
 
                 addPathText(buf, false, text);
@@ -188,12 +189,13 @@ final class PathParser {
         PathBuilder pb = new PathBuilder();
         for (Element e : buf) {
             if (e.sb.length() == 0 && !e.canBeEmpty) {
-                throw new BadPath(
-                        origin,
-                        originalText,
-                        "path has a leading, trailing, or two adjacent period '.' (use quoted \"\" empty string if you want an empty element)");
+                throw new ConfigException.BadPath(
+                    origin,
+                    originalText,
+                    "path has a leading, trailing, or two adjacent period '.' (use quoted \"\" empty string if you want an empty element)");
+            } else {
+                pb.appendKey(e.sb.toString());
             }
-            pb.appendKey(e.sb.toString());
         }
 
         return pb.result();
@@ -277,8 +279,9 @@ final class PathParser {
                     return true;
                 }
                 continue;
+            } else {
+                return true;
             }
-            return true;
         }
 
         if (lastWasDot) {
@@ -299,9 +302,10 @@ final class PathParser {
         if (splitAt < 0) {
             Path withOneMoreElement = new Path(s.substring(0, end), tail);
             return withOneMoreElement;
+        } else {
+            Path withOneMoreElement = new Path(s.substring(splitAt + ConfigParseOptions.PATH_TOKEN_SEPARATOR.length(), end), tail);
+            return fastPathBuild(withOneMoreElement, s, splitAt);
         }
-        Path withOneMoreElement = new Path(s.substring(splitAt + ConfigParseOptions.PATH_TOKEN_SEPARATOR.length(), end), tail);
-        return fastPathBuild(withOneMoreElement, s, splitAt);
     }
 
     // do something much faster than the full parser if
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/Config.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/Config.java
deleted file mode 100644
index db5a6c1..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/Config.java
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import java.time.Duration;
-import java.time.Period;
-import java.time.temporal.TemporalAmount;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/**
- * An immutable map from config paths to config values. Paths are dot-separated
- * expressions such as <code>foo.bar.baz</code>. Values are as in JSON
- * (booleans, strings, numbers, lists, or objects), represented by
- * {@link ConfigValue} instances. Values accessed through the
- * <code>Config</code> interface are never null.
- *
- * <p>
- * {@code Config} is an immutable object and thus safe to use from multiple
- * threads. There's never a need for "defensive copies."
- *
- * <p>
- * Fundamental operations on a {@code Config} include getting configuration
- * values, <em>resolving</em> substitutions with {@link Config#resolve()}, and
- * merging configs using {@link Config#withFallback(ConfigMergeable)}.
- *
- * <p>
- * All operations return a new immutable {@code Config} rather than modifying
- * the original instance.
- *
- * <p>
- * <strong>Examples</strong>
- *
- * <p>
- * You can find an example app and library <a
- * href="https://github.com/lightbend/config/tree/master/examples">on
- * GitHub</a>. Also be sure to read the <a
- * href="package-summary.html#package_description">package overview</a> which
- * describes the big picture as shown in those examples.
- *
- * <p>
- * <strong>Paths, keys, and Config vs. ConfigObject</strong>
- *
- * <p>
- * <code>Config</code> is a view onto a tree of {@link ConfigObject}; the
- * corresponding object tree can be found through {@link Config#root()}.
- * <code>ConfigObject</code> is a map from config <em>keys</em>, rather than
- * paths, to config values. Think of <code>ConfigObject</code> as a JSON object
- * and <code>Config</code> as a configuration API.
- *
- * <p>
- * The API tries to consistently use the terms "key" and "path." A key is a key
- * in a JSON object; it's just a string that's the key in a map. A "path" is a
- * parseable expression with a syntax and it refers to a series of keys. Path
- * expressions are described in the <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">spec for
- * Human-Optimized Config Object Notation</a>. In brief, a path is
- * period-separated so "a.b.c" looks for key c in object b in object a in the
- * root object. Sometimes double quotes are needed around special characters in
- * path expressions.
- *
- * <p>
- * The API for a {@code Config} is in terms of path expressions, while the API
- * for a {@code ConfigObject} is in terms of keys. Conceptually, {@code Config}
- * is a one-level map from <em>paths</em> to values, while a
- * {@code ConfigObject} is a tree of nested maps from <em>keys</em> to values.
- *
- * <p>
- * Use {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath} to convert
- * between path expressions and individual path elements (keys).
- *
- * <p>
- * Another difference between {@code Config} and {@code ConfigObject} is that
- * conceptually, {@code ConfigValue}s with a {@link ConfigValue#valueType()
- * valueType()} of {@link ConfigValueType#NULL NULL} exist in a
- * {@code ConfigObject}, while a {@code Config} treats null values as if they
- * were missing. (With the exception of two methods: {@link Config#hasPathOrNull}
- * and {@link Config#getIsNull} let you detect <code>null</code> values.)
- *
- * <p>
- * <strong>Getting configuration values</strong>
- *
- * <p>
- * The "getters" on a {@code Config} all work in the same way. They never return
- * null, nor do they return a {@code ConfigValue} with
- * {@link ConfigValue#valueType() valueType()} of {@link ConfigValueType#NULL
- * NULL}. Instead, they throw {@link ConfigException.Missing} if the value is
- * completely absent or set to null. If the value is set to null, a subtype of
- * {@code ConfigException.Missing} called {@link ConfigException.Null} will be
- * thrown. {@link ConfigException.WrongType} will be thrown anytime you ask for
- * a type and the value has an incompatible type. Reasonable type conversions
- * are performed for you though.
- *
- * <p>
- * <strong>Iteration</strong>
- *
- * <p>
- * If you want to iterate over the contents of a {@code Config}, you can get its
- * {@code ConfigObject} with {@link #root()}, and then iterate over the
- * {@code ConfigObject} (which implements <code>java.util.Map</code>). Or, you
- * can use {@link #entrySet()} which recurses the object tree for you and builds
- * up a <code>Set</code> of all path-value pairs where the value is not null.
- *
- * <p>
- * <strong>Resolving substitutions</strong>
- *
- * <p>
- * <em>Substitutions</em> are the <code>${foo.bar}</code> syntax in config
- * files, described in the <a href=
- * "https://github.com/lightbend/config/blob/master/HOCON.md#substitutions"
- * >specification</a>. Resolving substitutions replaces these references with real
- * values.
- *
- * <p>
- * Before using a {@code Config} it's necessary to call {@link Config#resolve()}
- * to handle substitutions (though {@link ConfigFactory#load()} and similar
- * methods will do the resolve for you already).
- *
- * <p>
- * <strong>Merging</strong>
- *
- * <p>
- * The full <code>Config</code> for your application can be constructed using
- * the associative operation {@link Config#withFallback(ConfigMergeable)}. If
- * you use {@link ConfigFactory#load()} (recommended), it merges system
- * properties over the top of <code>application.conf</code> over the top of
- * <code>reference.conf</code>, using <code>withFallback</code>. You can add in
- * additional sources of configuration in the same way (usually, custom layers
- * should go either just above or just below <code>application.conf</code>,
- * keeping <code>reference.conf</code> at the bottom and system properties at
- * the top).
- *
- * <p>
- * <strong>Serialization</strong>
- *
- * <p>
- * Convert a <code>Config</code> to a JSON or HOCON string by calling
- * {@link ConfigObject#render()} on the root object,
- * <code>myConfig.root().render()</code>. There's also a variant
- * {@link ConfigObject#render(ConfigRenderOptions)} which allows you to control
- * the format of the rendered string. (See {@link ConfigRenderOptions}.) Note
- * that <code>Config</code> does not remember the formatting of the original
- * file, so if you load, modify, and re-save a config file, it will be
- * substantially reformatted.
- *
- * <p>
- * As an alternative to {@link ConfigObject#render()}, the
- * <code>toString()</code> method produces a debug-output-oriented
- * representation (which is not valid JSON).
- *
- * <p>
- * Java serialization is supported as well for <code>Config</code> and all
- * subtypes of <code>ConfigValue</code>.
- *
- * <p>
- * <strong>This is an interface but don't implement it yourself</strong>
- *
- * <p>
- * <em>Do not implement {@code Config}</em>; it should only be implemented by
- * the config library. Arbitrary implementations will not work because the
- * library internals assume a specific concrete implementation. Also, this
- * interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface Config extends ConfigMergeable {
-    /**
-     * Gets the {@code Config} as a tree of {@link ConfigObject}. This is a
-     * constant-time operation (it is not proportional to the number of values
-     * in the {@code Config}).
-     *
-     * @return the root object in the configuration
-     */
-    ConfigObject root();
-
-    /**
-     * Gets the origin of the {@code Config}, which may be a file, or a file
-     * with a line number, or just a descriptive phrase.
-     *
-     * @return the origin of the {@code Config} for use in error messages
-     */
-    ConfigOrigin origin();
-
-    @Override
-    Config withFallback(ConfigMergeable other);
-
-    /**
-     * Returns a replacement config with all substitutions (the
-     * <code>${foo.bar}</code> syntax, see <a
-     * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
-     * spec</a>) resolved. Substitutions are looked up using this
-     * <code>Config</code> as the root object, that is, a substitution
-     * <code>${foo.bar}</code> will be replaced with the result of
-     * <code>getValue("foo.bar")</code>.
-     *
-     * <p>
-     * This method uses {@link ConfigResolveOptions#defaults()}, there is
-     * another variant {@link Config#resolve(ConfigResolveOptions)} which lets
-     * you specify non-default options.
-     *
-     * <p>
-     * A given {@link Config} must be resolved before using it to retrieve
-     * config values, but ideally should be resolved one time for your entire
-     * stack of fallbacks (see {@link Config#withFallback}). Otherwise, some
-     * substitutions that could have resolved with all fallbacks available may
-     * not resolve, which will be potentially confusing for your application's
-     * users.
-     *
-     * <p>
-     * <code>resolve()</code> should be invoked on root config objects, rather
-     * than on a subtree (a subtree is the result of something like
-     * <code>config.getConfig("foo")</code>). The problem with
-     * <code>resolve()</code> on a subtree is that substitutions are relative to
-     * the root of the config and the subtree will have no way to get values
-     * from the root. For example, if you did
-     * <code>config.getConfig("foo").resolve()</code> on the below config file,
-     * it would not work:
-     *
-     * <pre>
-     *   common-value = 10
-     *   foo {
-     *      whatever = ${common-value}
-     *   }
-     * </pre>
-     *
-     * <p>
-     * Many methods on {@link ConfigFactory} such as
-     * {@link ConfigFactory#load()} automatically resolve the loaded
-     * <code>Config</code> on the loaded stack of config files.
-     *
-     * <p>
-     * Resolving an already-resolved config is a harmless no-op, but again, it
-     * is best to resolve an entire stack of fallbacks (such as all your config
-     * files combined) rather than resolving each one individually.
-     *
-     * @return an immutable object with substitutions resolved
-     * @throws ConfigException.UnresolvedSubstitution if any substitutions refer to nonexistent paths
-     * @throws ConfigException                        some other config exception if there are other problems
-     */
-    Config resolve();
-
-    /**
-     * Like {@link Config#resolve()} but allows you to specify non-default
-     * options.
-     *
-     * @param options resolve options
-     * @return the resolved <code>Config</code> (may be only partially resolved if options are set to allow unresolved)
-     */
-    Config resolve(ConfigResolveOptions options);
-
-    /**
-     * Checks whether the config is completely resolved. After a successful call
-     * to {@link Config#resolve()} it will be completely resolved, but after
-     * calling {@link Config#resolve(ConfigResolveOptions)} with
-     * <code>allowUnresolved</code> set in the options, it may or may not be
-     * completely resolved. A newly-loaded config may or may not be completely
-     * resolved depending on whether there were substitutions present in the
-     * file.
-     *
-     * @return true if there are no unresolved substitutions remaining in this
-     * configuration.
-     * @since 1.2.0
-     */
-    boolean isResolved();
-
-    /**
-     * Like {@link Config#resolve()} except that substitution values are looked
-     * up in the given source, rather than in this instance. This is a
-     * special-purpose method which doesn't make sense to use in most cases;
-     * it's only needed if you're constructing some sort of app-specific custom
-     * approach to configuration. The more usual approach if you have a source
-     * of substitution values would be to merge that source into your config
-     * stack using {@link Config#withFallback} and then resolve.
-     * <p>
-     * Note that this method does NOT look in this instance for substitution
-     * values. If you want to do that, you could either merge this instance into
-     * your value source using {@link Config#withFallback}, or you could resolve
-     * multiple times with multiple sources (using
-     * {@link ConfigResolveOptions#setAllowUnresolved(boolean)} so the partial
-     * resolves don't fail).
-     *
-     * @param source configuration to pull values from
-     * @return an immutable object with substitutions resolved
-     * @throws ConfigException.UnresolvedSubstitution if any substitutions refer to paths which are not in the
-     *                                                source
-     * @throws ConfigException                        some other config exception if there are other problems
-     * @since 1.2.0
-     */
-    Config resolveWith(Config source);
-
-    /**
-     * Like {@link Config#resolveWith(Config)} but allows you to specify
-     * non-default options.
-     *
-     * @param source  source configuration to pull values from
-     * @param options resolve options
-     * @return the resolved <code>Config</code> (may be only partially resolved
-     * if options are set to allow unresolved)
-     * @since 1.2.0
-     */
-    Config resolveWith(Config source, ConfigResolveOptions options);
-
-    /**
-     * Validates this config against a reference config, throwing an exception
-     * if it is invalid. The purpose of this method is to "fail early" with a
-     * comprehensive list of problems; in general, anything this method can find
-     * would be detected later when trying to use the config, but it's often
-     * more user-friendly to fail right away when loading the config.
-     *
-     * <p>
-     * Using this method is always optional, since you can "fail late" instead.
-     *
-     * <p>
-     * You must restrict validation to paths you "own" (those whose meaning are
-     * defined by your code module). If you validate globally, you may trigger
-     * errors about paths that happen to be in the config but have nothing to do
-     * with your module. It's best to allow the modules owning those paths to
-     * validate them. Also, if every module validates only its own stuff, there
-     * isn't as much redundant work being done.
-     *
-     * <p>
-     * If no paths are specified in <code>checkValid()</code>'s parameter list,
-     * validation is for the entire config.
-     *
-     * <p>
-     * If you specify paths that are not in the reference config, those paths
-     * are ignored. (There's nothing to validate.)
-     *
-     * <p>
-     * Here's what validation involves:
-     *
-     * <ul>
-     * <li>All paths found in the reference config must be present in this
-     * config or an exception will be thrown.
-     * <li>
-     * Some changes in type from the reference config to this config will cause
-     * an exception to be thrown. Not all potential type problems are detected,
-     * in particular it's assumed that strings are compatible with everything
-     * except objects and lists. This is because string types are often "really"
-     * some other type (system properties always start out as strings, or a
-     * string like "5ms" could be used with {@link #getMilliseconds}). Also,
-     * it's allowed to set any type to null or override null with any type.
-     * <li>
-     * Any unresolved substitutions in this config will cause a validation
-     * failure; both the reference config and this config should be resolved
-     * before validation. If the reference config is unresolved, it's a bug in
-     * the caller of this method.
-     * </ul>
-     *
-     * <p>
-     * If you want to allow a certain setting to have a flexible type (or
-     * otherwise want validation to be looser for some settings), you could
-     * either remove the problematic setting from the reference config provided
-     * to this method, or you could intercept the validation exception and
-     * screen out certain problems. Of course, this will only work if all other
-     * callers of this method are careful to restrict validation to their own
-     * paths, as they should be.
-     *
-     * <p>
-     * If validation fails, the thrown exception contains a list of all problems
-     * found. See {@link ConfigException.ValidationFailed#problems}. The
-     * exception's <code>getMessage()</code> will have all the problems
-     * concatenated into one huge string, as well.
-     *
-     * <p>
-     * Again, <code>checkValid()</code> can't guess every domain-specific way a
-     * setting can be invalid, so some problems may arise later when attempting
-     * to use the config. <code>checkValid()</code> is limited to reporting
-     * generic, but common, problems such as missing settings and blatant type
-     * incompatibilities.
-     *
-     * @param reference       a reference configuration
-     * @param restrictToPaths only validate values underneath these paths that your code
-     *                        module owns and understands
-     * @throws ConfigException.ValidationFailed if there are any validation issues
-     * @throws ConfigException.NotResolved      if this config is not resolved
-     * @throws ConfigException.BugOrBroken      if the reference config is unresolved or caller otherwise
-     *                                          misuses the API
-     */
-    void checkValid(Config reference, String... restrictToPaths);
-
-    /**
-     * Checks whether a value is present and non-null at the given path. This
-     * differs in two ways from {@code Map.containsKey()} as implemented by
-     * {@link ConfigObject}: it looks for a path expression, not a key; and it
-     * returns false for null values, while {@code containsKey()} returns true
-     * indicating that the object contains a null value for the key.
-     *
-     * <p>
-     * If a path exists according to {@link #hasPath(String)}, then
-     * {@link #getValue(String)} will never throw an exception. However, the
-     * typed getters, such as {@link #getInt(String)}, will still throw if the
-     * value is not convertible to the requested type.
-     *
-     * <p>
-     * Note that path expressions have a syntax and sometimes require quoting
-     * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
-     *
-     * @param path the path expression
-     * @return true if a non-null value is present at the path
-     * @throws ConfigException.BadPath if the path expression is invalid
-     */
-    boolean hasPath(String path);
-
-    /**
-     * Checks whether a value is present at the given path, even
-     * if the value is null. Most of the getters on
-     * <code>Config</code> will throw if you try to get a null
-     * value, so if you plan to call {@link #getValue(String)},
-     * {@link #getInt(String)}, or another getter you may want to
-     * use plain {@link #hasPath(String)} rather than this method.
-     *
-     * <p>
-     * To handle all three cases (unset, null, and a non-null value)
-     * the code might look like:
-     * <pre><code>
-     * if (config.hasPathOrNull(path)) {
-     *     if (config.getIsNull(path)) {
-     *        // handle null setting
-     *     } else {
-     *        // get and use non-null setting
-     *     }
-     * } else {
-     *     // handle entirely unset path
-     * }
-     * </code></pre>
-     *
-     * <p> However, the usual thing is to allow entirely unset
-     * paths to be a bug that throws an exception (because you set
-     * a default in your <code>reference.conf</code>), so in that
-     * case it's OK to call {@link #getIsNull(String)} without
-     * checking <code>hasPathOrNull</code> first.
-     *
-     * <p>
-     * Note that path expressions have a syntax and sometimes require quoting
-     * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
-     *
-     * @param path the path expression
-     * @return true if a value is present at the path, even if the value is null
-     * @throws ConfigException.BadPath if the path expression is invalid
-     */
-    boolean hasPathOrNull(String path);
-
-    /**
-     * Returns true if the {@code Config}'s root object contains no key-value
-     * pairs.
-     *
-     * @return true if the configuration is empty
-     */
-    boolean isEmpty();
-
-    /**
-     * Returns the set of path-value pairs, excluding any null values, found by
-     * recursing {@link #root() the root object}. Note that this is very
-     * different from <code>root().entrySet()</code> which returns the set of
-     * immediate-child keys in the root object and includes null values.
-     * <p>
-     * Entries contain <em>path expressions</em> meaning there may be quoting
-     * and escaping involved. Parse path expressions with
-     * {@link ConfigUtil#splitPath}.
-     * <p>
-     * Because a <code>Config</code> is conceptually a single-level map from
-     * paths to values, there will not be any {@link ConfigObject} values in the
-     * entries (that is, all entries represent leaf nodes). Use
-     * {@link ConfigObject} rather than <code>Config</code> if you want a tree.
-     * (OK, this is a slight lie: <code>Config</code> entries may contain
-     * {@link ConfigList} and the lists may contain objects. But no objects are
-     * directly included as entry values.)
-     *
-     * @return set of paths with non-null values, built up by recursing the
-     * entire tree of {@link ConfigObject} and creating an entry for
-     * each leaf value.
-     */
-    Set<Map.Entry<String, ConfigValue>> entrySet();
-
-    /**
-     * Checks whether a value is set to null at the given path,
-     * but throws an exception if the value is entirely
-     * unset. This method will not throw if {@link
-     * #hasPathOrNull(String)} returned true for the same path, so
-     * to avoid any possible exception check
-     * <code>hasPathOrNull()</code> first.  However, an exception
-     * for unset paths will usually be the right thing (because a
-     * <code>reference.conf</code> should exist that has the path
-     * set, the path should never be unset unless something is
-     * broken).
-     *
-     * <p>
-     * Note that path expressions have a syntax and sometimes require quoting
-     * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
-     *
-     * @param path the path expression
-     * @return true if the value exists and is null, false if it
-     * exists and is not null
-     * @throws ConfigException.BadPath if the path expression is invalid
-     * @throws ConfigException.Missing if value is not set at all
-     */
-    boolean getIsNull(String path);
-
-    /**
-     * @param path path expression
-     * @return the boolean value at the requested path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to boolean
-     */
-    boolean getBoolean(String path);
-
-    /**
-     * @param path path expression
-     * @return the numeric value at the requested path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a number
-     */
-    Number getNumber(String path);
-
-    /**
-     * Gets the integer at the given path. If the value at the
-     * path has a fractional (floating point) component, it
-     * will be discarded and only the integer part will be
-     * returned (it works like a "narrowing primitive conversion"
-     * in the Java language specification).
-     *
-     * @param path path expression
-     * @return the 32-bit integer value at the requested path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to an int (for example it is out
-     *                                   of range, or it's a boolean value)
-     */
-    int getInt(String path);
-
-    /**
-     * Gets the long integer at the given path.  If the value at
-     * the path has a fractional (floating point) component, it
-     * will be discarded and only the integer part will be
-     * returned (it works like a "narrowing primitive conversion"
-     * in the Java language specification).
-     *
-     * @param path path expression
-     * @return the 64-bit long value at the requested path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a long
-     */
-    long getLong(String path);
-
-    /**
-     * @param path path expression
-     * @return the floating-point value at the requested path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a double
-     */
-    double getDouble(String path);
-
-    /**
-     * @param path path expression
-     * @return the string value at the requested path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a string
-     */
-    String getString(String path);
-
-    /**
-     * @param enumClass an enum class
-     * @param <T>       a generic denoting a specific type of enum
-     * @param path      path expression
-     * @return the {@code Enum} value at the requested path
-     * of the requested enum class
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to an Enum
-     */
-    public <T extends Enum<T>> T getEnum(Class<T> enumClass, String path);
-
-    /**
-     * @param path path expression
-     * @return the {@link ConfigObject} value at the requested path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to an object
-     */
-    ConfigObject getObject(String path);
-
-    /**
-     * @param path path expression
-     * @return the nested {@code Config} value at the requested path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a Config
-     */
-    Config getConfig(String path);
-
-    /**
-     * Gets the value at the path as an unwrapped Java boxed value (
-     * {@link java.lang.Boolean Boolean}, {@link java.lang.Integer Integer}, and
-     * so on - see {@link ConfigValue#unwrapped()}).
-     *
-     * @param path path expression
-     * @return the unwrapped value at the requested path
-     * @throws ConfigException.Missing if value is absent or null
-     */
-    Object getAnyRef(String path);
-
-    /**
-     * Gets the value at the given path, unless the value is a
-     * null value or missing, in which case it throws just like
-     * the other getters. Use {@code get()} on the {@link
-     * Config#root()} object (or other object in the tree) if you
-     * want an unprocessed value.
-     *
-     * @param path path expression
-     * @return the value at the requested path
-     * @throws ConfigException.Missing if value is absent or null
-     */
-    ConfigValue getValue(String path);
-
-    /**
-     * Gets a value as a size in bytes (parses special strings like "128M"). If
-     * the value is already a number, then it's left alone; if it's a string,
-     * it's parsed understanding unit suffixes such as "128K", as documented in
-     * the <a
-     * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
-     * spec</a>.
-     *
-     * @param path path expression
-     * @return the value at the requested path, in bytes
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to Long or String
-     * @throws ConfigException.BadValue  if value cannot be parsed as a size in bytes
-     */
-    Long getBytes(String path);
-
-    /**
-     * Gets a value as an amount of memory (parses special strings like "128M"). If
-     * the value is already a number, then it's left alone; if it's a string,
-     * it's parsed understanding unit suffixes such as "128K", as documented in
-     * the <a
-     * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
-     * spec</a>.
-     *
-     * @param path path expression
-     * @return the value at the requested path, in bytes
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to Long or String
-     * @throws ConfigException.BadValue  if value cannot be parsed as a size in bytes
-     * @since 1.3.0
-     */
-    ConfigMemorySize getMemorySize(String path);
-
-    /**
-     * Get value as a duration in milliseconds. If the value is already a
-     * number, then it's left alone; if it's a string, it's parsed understanding
-     * units suffixes like "10m" or "5ns" as documented in the <a
-     * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
-     * spec</a>.
-     *
-     * @param path path expression
-     * @return the duration value at the requested path, in milliseconds
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to Long or String
-     * @throws ConfigException.BadValue  if value cannot be parsed as a number of milliseconds
-     * @deprecated As of release 1.1, replaced by {@link #getDuration(String, TimeUnit)}
-     */
-    @Deprecated
-    Long getMilliseconds(String path);
-
-    /**
-     * Get value as a duration in nanoseconds. If the value is already a number
-     * it's taken as milliseconds and converted to nanoseconds. If it's a
-     * string, it's parsed understanding unit suffixes, as for
-     * {@link #getDuration(String, TimeUnit)}.
-     *
-     * @param path path expression
-     * @return the duration value at the requested path, in nanoseconds
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to Long or String
-     * @throws ConfigException.BadValue  if value cannot be parsed as a number of nanoseconds
-     * @deprecated As of release 1.1, replaced by {@link #getDuration(String, TimeUnit)}
-     */
-    @Deprecated
-    Long getNanoseconds(String path);
-
-    /**
-     * Gets a value as a duration in a specified
-     * {@link java.util.concurrent.TimeUnit TimeUnit}. If the value is already a
-     * number, then it's taken as milliseconds and then converted to the
-     * requested TimeUnit; if it's a string, it's parsed understanding units
-     * suffixes like "10m" or "5ns" as documented in the <a
-     * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
-     * spec</a>.
-     *
-     * @param path path expression
-     * @param unit convert the return value to this time unit
-     * @return the duration value at the requested path, in the given TimeUnit
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to Long or String
-     * @throws ConfigException.BadValue  if value cannot be parsed as a number of the given TimeUnit
-     * @since 1.2.0
-     */
-    long getDuration(String path, TimeUnit unit);
-
-    /**
-     * Gets a value as a java.time.Duration. If the value is
-     * already a number, then it's taken as milliseconds; if it's
-     * a string, it's parsed understanding units suffixes like
-     * "10m" or "5ns" as documented in the <a
-     * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
-     * spec</a>. This method never returns null.
-     *
-     * @param path path expression
-     * @return the duration value at the requested path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to Long or String
-     * @throws ConfigException.BadValue  if value cannot be parsed as a number of the given TimeUnit
-     * @since 1.3.0
-     */
-    Duration getDuration(String path);
-
-    /**
-     * Gets a value as a java.time.Period. If the value is
-     * already a number, then it's taken as days; if it's
-     * a string, it's parsed understanding units suffixes like
-     * "10d" or "5w" as documented in the <a
-     * href="https://github.com/lightbend/config/blob/master/HOCON.md">the
-     * spec</a>. This method never returns null.
-     *
-     * @param path path expression
-     * @return the period value at the requested path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to Long or String
-     * @throws ConfigException.BadValue  if value cannot be parsed as a number of the given TimeUnit
-     * @since 1.3.0
-     */
-    Period getPeriod(String path);
-
-    /**
-     * Gets a value as a java.time.temporal.TemporalAmount.
-     * This method will first try get get the value as a java.time.Duration, and if unsuccessful,
-     * then as a java.time.Period.
-     * This means that values like "5m" will be parsed as 5 minutes rather than 5 months
-     *
-     * @param path path expression
-     * @return the temporal value at the requested path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to Long or String
-     * @throws ConfigException.BadValue  if value cannot be parsed as a TemporalAmount
-     */
-    TemporalAmount getTemporal(String path);
-
-    /**
-     * Gets a list value (with any element type) as a {@link ConfigList}, which
-     * implements {@code java.util.List<ConfigValue>}. Throws if the path is
-     * unset or null.
-     *
-     * @param path the path to the list value.
-     * @return the {@link ConfigList} at the path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a ConfigList
-     */
-    ConfigList getList(String path);
-
-    /**
-     * Gets a list value with boolean elements.  Throws if the
-     * path is unset or null or not a list or contains values not
-     * convertible to boolean.
-     *
-     * @param path the path to the list value.
-     * @return the list at the path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a list of booleans
-     */
-    List<Boolean> getBooleanList(String path);
-
-    /**
-     * Gets a list value with number elements.  Throws if the
-     * path is unset or null or not a list or contains values not
-     * convertible to number.
-     *
-     * @param path the path to the list value.
-     * @return the list at the path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a list of numbers
-     */
-    List<Number> getNumberList(String path);
-
-    /**
-     * Gets a list value with int elements.  Throws if the
-     * path is unset or null or not a list or contains values not
-     * convertible to int.
-     *
-     * @param path the path to the list value.
-     * @return the list at the path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a list of ints
-     */
-    List<Integer> getIntList(String path);
-
-    /**
-     * Gets a list value with long elements.  Throws if the
-     * path is unset or null or not a list or contains values not
-     * convertible to long.
-     *
-     * @param path the path to the list value.
-     * @return the list at the path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a list of longs
-     */
-    List<Long> getLongList(String path);
-
-    /**
-     * Gets a list value with double elements.  Throws if the
-     * path is unset or null or not a list or contains values not
-     * convertible to double.
-     *
-     * @param path the path to the list value.
-     * @return the list at the path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a list of doubles
-     */
-    List<Double> getDoubleList(String path);
-
-    /**
-     * Gets a list value with string elements.  Throws if the
-     * path is unset or null or not a list or contains values not
-     * convertible to string.
-     *
-     * @param path the path to the list value.
-     * @return the list at the path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a list of strings
-     */
-    List<String> getStringList(String path);
-
-    /**
-     * Gets a list value with {@code Enum} elements.  Throws if the
-     * path is unset or null or not a list or contains values not
-     * convertible to {@code Enum}.
-     *
-     * @param enumClass the enum class
-     * @param <T>       a generic denoting a specific type of enum
-     * @param path      the path to the list value.
-     * @return the list at the path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a list of {@code Enum}
-     */
-    <T extends Enum<T>> List<T> getEnumList(Class<T> enumClass, String path);
-
-    /**
-     * Gets a list value with object elements.  Throws if the
-     * path is unset or null or not a list or contains values not
-     * convertible to <code>ConfigObject</code>.
-     *
-     * @param path the path to the list value.
-     * @return the list at the path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a list of objects
-     */
-    List<? extends ConfigObject> getObjectList(String path);
-
-    /**
-     * Gets a list value with <code>Config</code> elements.
-     * Throws if the path is unset or null or not a list or
-     * contains values not convertible to <code>Config</code>.
-     *
-     * @param path the path to the list value.
-     * @return the list at the path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a list of configs
-     */
-    List<? extends Config> getConfigList(String path);
-
-    /**
-     * Gets a list value with any kind of elements.  Throws if the
-     * path is unset or null or not a list. Each element is
-     * "unwrapped" (see {@link ConfigValue#unwrapped()}).
-     *
-     * @param path the path to the list value.
-     * @return the list at the path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a list
-     */
-    List<? extends Object> getAnyRefList(String path);
-
-    /**
-     * Gets a list value with elements representing a size in
-     * bytes.  Throws if the path is unset or null or not a list
-     * or contains values not convertible to memory sizes.
-     *
-     * @param path the path to the list value.
-     * @return the list at the path
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a list of memory sizes
-     */
-    List<Long> getBytesList(String path);
-
-    /**
-     * Gets a list, converting each value in the list to a memory size, using the
-     * same rules as {@link #getMemorySize(String)}.
-     *
-     * @param path a path expression
-     * @return list of memory sizes
-     * @throws ConfigException.Missing   if value is absent or null
-     * @throws ConfigException.WrongType if value is not convertible to a list of memory sizes
-     * @since 1.3.0
-     */
-    List<ConfigMemorySize> getMemorySizeList(String path);
-
-    /**
-     * @param path the path
-     * @return list of millisecond values
-     * @deprecated As of release 1.1, replaced by {@link #getDurationList(String, TimeUnit)}
-     */
-    @Deprecated
-    List<Long> getMillisecondsList(String path);
-
-    /**
-     * @param path the path
-     * @return list of nanosecond values
-     * @deprecated As of release 1.1, replaced by {@link #getDurationList(String, TimeUnit)}
-     */
-    @Deprecated
-    List<Long> getNanosecondsList(String path);
-
-    /**
-     * Gets a list, converting each value in the list to a duration, using the
-     * same rules as {@link #getDuration(String, TimeUnit)}.
-     *
-     * @param path a path expression
-     * @param unit time units of the returned values
-     * @return list of durations, in the requested units
-     * @since 1.2.0
-     */
-    List<Long> getDurationList(String path, TimeUnit unit);
-
-    /**
-     * Gets a list, converting each value in the list to a duration, using the
-     * same rules as {@link #getDuration(String)}.
-     *
-     * @param path a path expression
-     * @return list of durations
-     * @since 1.3.0
-     */
-    List<Duration> getDurationList(String path);
-
-    /**
-     * Clone the config with only the given path (and its children) retained;
-     * all sibling paths are removed.
-     * <p>
-     * Note that path expressions have a syntax and sometimes require quoting
-     * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
-     *
-     * @param path path to keep
-     * @return a copy of the config minus all paths except the one specified
-     */
-    Config withOnlyPath(String path);
-
-    /**
-     * Clone the config with the given path removed.
-     * <p>
-     * Note that path expressions have a syntax and sometimes require quoting
-     * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
-     *
-     * @param path path expression to remove
-     * @return a copy of the config minus the specified path
-     */
-    Config withoutPath(String path);
-
-    /**
-     * Places the config inside another {@code Config} at the given path.
-     * <p>
-     * Note that path expressions have a syntax and sometimes require quoting
-     * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
-     *
-     * @param path path expression to store this config at.
-     * @return a {@code Config} instance containing this config at the given
-     * path.
-     */
-    Config atPath(String path);
-
-    /**
-     * Places the config inside a {@code Config} at the given key. See also
-     * atPath(). Note that a key is NOT a path expression (see
-     * {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
-     *
-     * @param key key to store this config at.
-     * @return a {@code Config} instance containing this config at the given
-     * key.
-     */
-    Config atKey(String key);
-
-    /**
-     * Returns a {@code Config} based on this one, but with the given path set
-     * to the given value. Does not modify this instance (since it's immutable).
-     * If the path already has a value, that value is replaced. To remove a
-     * value, use withoutPath().
-     * <p>
-     * Note that path expressions have a syntax and sometimes require quoting
-     * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}).
-     *
-     * @param path  path expression for the value's new location
-     * @param value value at the new path
-     * @return the new instance with the new map entry
-     */
-    Config withValue(String path, ConfigValue value);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigBeanFactory.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigBeanFactory.java
deleted file mode 100644
index e0e78f5..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigBeanFactory.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import org.apache.seatunnel.config.impl.ConfigBeanImpl;
-
-/**
- * Factory for automatically creating a Java class from a {@link Config}.
- * See {@link #create(Config, Class)}.
- *
- * @since 1.3.0
- */
-public class ConfigBeanFactory {
-
-    /**
-     * Creates an instance of a class, initializing its fields from a {@link Config}.
-     * <p>
-     * Example usage:
-     *
-     * <pre>
-     * Config configSource = ConfigFactory.load().getConfig("foo");
-     * FooConfig config = ConfigBeanFactory.create(configSource, FooConfig.class);
-     * </pre>
-     * <p>
-     * The Java class should follow JavaBean conventions. Field types
-     * can be any of the types you can normally get from a {@link
-     * Config}, including <code>java.time.Duration</code> or {@link
-     * ConfigMemorySize}. Fields may also be another JavaBean-style
-     * class.
-     * <p>
-     * Fields are mapped to config by converting the config key to
-     * camel case.  So the key <code>foo-bar</code> becomes JavaBean
-     * setter <code>setFooBar</code>.
-     *
-     * @param config source of config information
-     * @param clazz  class to be instantiated
-     * @param <T>    the type of the class to be instantiated
-     * @return an instance of the class populated with data from the config
-     * @throws ConfigException.BadBean          If something is wrong with the JavaBean
-     * @throws ConfigException.ValidationFailed If the config doesn't conform to the bean's implied schema
-     * @throws ConfigException                  Can throw the same exceptions as the getters on <code>Config</code>
-     * @since 1.3.0
-     */
-    public static <T> T create(Config config, Class<T> clazz) {
-        return ConfigBeanImpl.createInternal(config, clazz);
-    }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigException.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigException.java
deleted file mode 100644
index 402adc0..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigException.java
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import org.apache.seatunnel.config.impl.ConfigImplUtil;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.lang.reflect.Field;
-
-/**
- * All exceptions thrown by the library are subclasses of
- * <code>ConfigException</code>.
- */
-public abstract class ConfigException extends RuntimeException implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    private final transient ConfigOrigin origin;
-
-    protected ConfigException(ConfigOrigin origin, String message,
-                              Throwable cause) {
-        super(origin.description() + ": " + message, cause);
-        this.origin = origin;
-    }
-
-    protected ConfigException(ConfigOrigin origin, String message) {
-        this(origin.description() + ": " + message, null);
-    }
-
-    protected ConfigException(String message, Throwable cause) {
-        super(message, cause);
-        this.origin = null;
-    }
-
-    protected ConfigException(String message) {
-        this(message, null);
-    }
-
-    /**
-     * Returns an "origin" (such as a filename and line number) for the
-     * exception, or null if none is available. If there's no sensible origin
-     * for a given exception, or the kind of exception doesn't meaningfully
-     * relate to a particular origin file, this returns null. Never assume this
-     * will return non-null, it can always return null.
-     *
-     * @return origin of the problem, or null if unknown/inapplicable
-     */
-    public ConfigOrigin origin() {
-        return origin;
-    }
-
-    // we customize serialization because ConfigOrigin isn't
-    // serializable and we don't want it to be (don't want to
-    // support it)
-    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
-        out.defaultWriteObject();
-        ConfigImplUtil.writeOrigin(out, origin);
-    }
-
-    private void readObject(java.io.ObjectInputStream in) throws IOException,
-            ClassNotFoundException {
-        in.defaultReadObject();
-        ConfigOrigin origin = ConfigImplUtil.readOrigin(in);
-        // circumvent "final"
-        Field f;
-        try {
-            f = ConfigException.class.getDeclaredField("origin");
-        } catch (NoSuchFieldException e) {
-            throw new IOException("ConfigException has no origin field?", e);
-        } catch (SecurityException e) {
-            throw new IOException("unable to fill out origin field in ConfigException", e);
-        }
-        f.setAccessible(true);
-        try {
-            f.set(this, origin);
-        } catch (IllegalArgumentException e) {
-            throw new IOException("unable to set origin field", e);
-        } catch (IllegalAccessException e) {
-            throw new IOException("unable to set origin field", e);
-        }
-    }
-
-    /**
-     * Exception indicating that the type of a value does not match the type you
-     * requested.
-     */
-    public static class WrongType extends ConfigException {
-        private static final long serialVersionUID = 1L;
-
-        public WrongType(ConfigOrigin origin, String path, String expected, String actual,
-                         Throwable cause) {
-            super(origin, path + " has type " + actual + " rather than " + expected, cause);
-        }
-
-        public WrongType(ConfigOrigin origin, String path, String expected, String actual) {
-            this(origin, path, expected, actual, null);
-        }
-
-        public WrongType(ConfigOrigin origin, String message, Throwable cause) {
-            super(origin, message, cause);
-        }
-
-        public WrongType(ConfigOrigin origin, String message) {
-            super(origin, message, null);
-        }
-    }
-
-    /**
-     * Exception indicates that the setting was never set to anything, not even
-     * null.
-     */
-    public static class Missing extends ConfigException {
-        private static final long serialVersionUID = 1L;
-
-        public Missing(String path, Throwable cause) {
-            super("No configuration setting found for key '" + path + "'",
-                    cause);
-        }
-
-        public Missing(String path) {
-            this(path, null);
-        }
-
-        protected Missing(ConfigOrigin origin, String message, Throwable cause) {
-            super(origin, message, cause);
-        }
-
-        protected Missing(ConfigOrigin origin, String message) {
-            this(origin, message, null);
-        }
-    }
-
-    /**
-     * Exception indicates that the setting was treated as missing because it
-     * was set to null.
-     */
-    public static class Null extends Missing {
-        private static final long serialVersionUID = 1L;
-
-        private static String makeMessage(String path, String expected) {
-            if (expected != null) {
-                return "Configuration key '" + path + "' is set to null but expected " + expected;
-            }
-            return "Configuration key '" + path + "' is null";
-        }
-
-        public Null(ConfigOrigin origin, String path, String expected,
-                    Throwable cause) {
-            super(origin, makeMessage(path, expected), cause);
-        }
-
-        public Null(ConfigOrigin origin, String path, String expected) {
-            this(origin, path, expected, null);
-        }
-    }
-
-    /**
-     * Exception indicating that a value was messed up, for example you may have
-     * asked for a duration and the value can't be sensibly parsed as a
-     * duration.
-     */
-    public static class BadValue extends ConfigException {
-        private static final long serialVersionUID = 1L;
-
-        public BadValue(ConfigOrigin origin, String path, String message,
-                        Throwable cause) {
-            super(origin, "Invalid value at '" + path + "': " + message, cause);
-        }
-
-        public BadValue(ConfigOrigin origin, String path, String message) {
-            this(origin, path, message, null);
-        }
-
-        public BadValue(String path, String message, Throwable cause) {
-            super("Invalid value at '" + path + "': " + message, cause);
-        }
-
-        public BadValue(String path, String message) {
-            this(path, message, null);
-        }
-    }
-
-    /**
-     * Exception indicating that a path expression was invalid. Try putting
-     * double quotes around path elements that contain "special" characters.
-     */
-    public static class BadPath extends ConfigException {
-        private static final long serialVersionUID = 1L;
-
-        public BadPath(ConfigOrigin origin, String path, String message,
-                       Throwable cause) {
-            super(origin,
-                    path != null ? ("Invalid path '" + path + "': " + message) : message, cause);
-        }
-
-        public BadPath(ConfigOrigin origin, String path, String message) {
-            this(origin, path, message, null);
-        }
-
-        public BadPath(String path, String message, Throwable cause) {
-            super(path != null ? ("Invalid path '" + path + "': " + message) : message, cause);
-        }
-
-        public BadPath(String path, String message) {
-            this(path, message, null);
-        }
-
-        public BadPath(ConfigOrigin origin, String message) {
-            this(origin, null, message);
-        }
-    }
-
-    /**
-     * Exception indicating that there's a bug in something (possibly the
-     * library itself) or the runtime environment is broken. This exception
-     * should never be handled; instead, something should be fixed to keep the
-     * exception from occurring. This exception can be thrown by any method in
-     * the library.
-     */
-    public static class BugOrBroken extends ConfigException {
-        private static final long serialVersionUID = 1L;
-
-        public BugOrBroken(String message, Throwable cause) {
-            super(message, cause);
-        }
-
-        public BugOrBroken(String message) {
-            this(message, null);
-        }
-    }
-
-    /**
-     * Exception indicating that there was an IO error.
-     */
-    public static class IO extends ConfigException {
-        private static final long serialVersionUID = 1L;
-
-        public IO(ConfigOrigin origin, String message, Throwable cause) {
-            super(origin, message, cause);
-        }
-
-        public IO(ConfigOrigin origin, String message) {
-            this(origin, message, null);
-        }
-    }
-
-    /**
-     * Exception indicating that there was a parse error.
-     */
-    public static class Parse extends ConfigException {
-        private static final long serialVersionUID = 1L;
-
-        public Parse(ConfigOrigin origin, String message, Throwable cause) {
-            super(origin, message, cause);
-        }
-
-        public Parse(ConfigOrigin origin, String message) {
-            this(origin, message, null);
-        }
-    }
-
-    /**
-     * Exception indicating that a substitution did not resolve to anything.
-     * Thrown by {@link Config#resolve}.
-     */
-    public static class UnresolvedSubstitution extends Parse {
-        private static final long serialVersionUID = 1L;
-
-        public UnresolvedSubstitution(ConfigOrigin origin, String detail, Throwable cause) {
-            super(origin, "Could not resolve substitution to a value: " + detail, cause);
-        }
-
-        public UnresolvedSubstitution(ConfigOrigin origin, String detail) {
-            this(origin, detail, null);
-        }
-    }
-
-    /**
-     * Exception indicating that you tried to use a function that requires
-     * substitutions to be resolved, but substitutions have not been resolved
-     * (that is, {@link Config#resolve} was not called). This is always a bug in
-     * either application code or the library; it's wrong to write a handler for
-     * this exception because you should be able to fix the code to avoid it by
-     * adding calls to {@link Config#resolve}.
-     */
-    public static class NotResolved extends BugOrBroken {
-        private static final long serialVersionUID = 1L;
-
-        public NotResolved(String message, Throwable cause) {
-            super(message, cause);
-        }
-
-        public NotResolved(String message) {
-            this(message, null);
-        }
-    }
-
-    /**
-     * Information about a problem that occurred in {@link Config#checkValid}. A
-     * {@link ConfigException.ValidationFailed} exception thrown from
-     * <code>checkValid()</code> includes a list of problems encountered.
-     */
-    public static class ValidationProblem {
-
-        private final String path;
-        private final ConfigOrigin origin;
-        private final String problem;
-
-        public ValidationProblem(String path, ConfigOrigin origin, String problem) {
-            this.path = path;
-            this.origin = origin;
-            this.problem = problem;
-        }
-
-        /**
-         * Returns the config setting causing the problem.
-         *
-         * @return the path of the problem setting
-         */
-        public String path() {
-            return path;
-        }
-
-        /**
-         * Returns where the problem occurred (origin may include info on the
-         * file, line number, etc.).
-         *
-         * @return the origin of the problem setting
-         */
-        public ConfigOrigin origin() {
-            return origin;
-        }
-
-        /**
-         * Returns a description of the problem.
-         *
-         * @return description of the problem
-         */
-        public String problem() {
-            return problem;
-        }
-
-        @Override
-        public String toString() {
-            return "ValidationProblem(" + path + "," + origin + "," + problem + ")";
-        }
-    }
-
-    /**
-     * Exception indicating that {@link Config#checkValid} found validity
-     * problems. The problems are available via the {@link #problems()} method.
-     * The <code>getMessage()</code> of this exception is a potentially very
-     * long string listing all the problems found.
-     */
-    public static class ValidationFailed extends ConfigException {
-        private static final long serialVersionUID = 1L;
-
-        private final Iterable<ValidationProblem> problems;
-
-        public ValidationFailed(Iterable<ValidationProblem> problems) {
-            super(makeMessage(problems), null);
-            this.problems = problems;
-        }
-
-        public Iterable<ValidationProblem> problems() {
-            return problems;
-        }
-
-        private static String makeMessage(Iterable<ValidationProblem> problems) {
-            StringBuilder sb = new StringBuilder();
-            for (ValidationProblem p : problems) {
-                sb.append(p.origin().description());
-                sb.append(": ");
-                sb.append(p.path());
-                sb.append(": ");
-                sb.append(p.problem());
-                sb.append(", ");
-            }
-            if (sb.length() == 0) {
-                throw new BugOrBroken(
-                        "ValidationFailed must have a non-empty list of problems");
-            }
-            sb.setLength(sb.length() - 2); // chop comma and space
-
-            return sb.toString();
-        }
-    }
-
-    /**
-     * Some problem with a JavaBean we are trying to initialize.
-     *
-     * @since 1.3.0
-     */
-    public static class BadBean extends BugOrBroken {
-        private static final long serialVersionUID = 1L;
-
-        public BadBean(String message, Throwable cause) {
-            super(message, cause);
-        }
-
-        public BadBean(String message) {
-            this(message, null);
-        }
-    }
-
-    /**
-     * Exception that doesn't fall into any other category.
-     */
-    public static class Generic extends ConfigException {
-        private static final long serialVersionUID = 1L;
-
-        public Generic(String message, Throwable cause) {
-            super(message, cause);
-        }
-
-        public Generic(String message) {
-            this(message, null);
-        }
-    }
-
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigFactory.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigFactory.java
deleted file mode 100644
index 036b19a..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigFactory.java
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import org.apache.seatunnel.config.impl.ConfigImpl;
-import org.apache.seatunnel.config.impl.Parseable;
-
-import java.io.File;
-import java.io.Reader;
-import java.net.URL;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.Callable;
-
-/**
- * Contains static methods for creating {@link Config} instances.
- *
- * <p>
- * See also {@link ConfigValueFactory} which contains static methods for
- * converting Java values into a {@link ConfigObject}. You can then convert a
- * {@code ConfigObject} into a {@code Config} with {@link ConfigObject#toConfig}.
- *
- * <p>
- * The static methods with "load" in the name do some sort of higher-level
- * operation potentially parsing multiple resources and resolving substitutions,
- * while the ones with "parse" in the name just create a {@link ConfigValue}
- * from a resource and nothing else.
- *
- * <p> You can find an example app and library <a
- * href="https://github.com/lightbend/config/tree/master/examples">on
- * GitHub</a>.  Also be sure to read the <a
- * href="package-summary.html#package_description">package
- * overview</a> which describes the big picture as shown in those
- * examples.
- */
-public final class ConfigFactory {
-    private static final String STRATEGY_PROPERTY_NAME = "config.strategy";
-
-    private ConfigFactory() {
-    }
-
-    /**
-     * Loads an application's configuration from the given classpath resource or
-     * classpath resource basename, sandwiches it between default reference
-     * config and default overrides, and then resolves it. The classpath
-     * resource is "raw" (it should have no "/" prefix, and is not made relative
-     * to any package, so it's like {@link ClassLoader#getResource} not
-     * {@link Class#getResource}).
-     *
-     * <p>
-     * Resources are loaded from the current thread's
-     * {@link Thread#getContextClassLoader()}. In general, a library needs its
-     * configuration to come from the class loader used to load that library, so
-     * the proper "reference.conf" are present.
-     *
-     * <p>
-     * The loaded object will already be resolved (substitutions have already
-     * been processed). As a result, if you add more fallbacks then they won't
-     * be seen by substitutions. Substitutions are the "${foo.bar}" syntax. If
-     * you want to parse additional files or something then you need to use
-     * {@link #load(Config)}.
-     *
-     * <p>
-     * To load a standalone resource (without the default reference and default
-     * overrides), use {@link #parseResourcesAnySyntax(String)} rather than this
-     * method. To load only the reference config use {@link #defaultReference()}
-     * and to load only the overrides use {@link #defaultOverrides()}.
-     *
-     * @param resourceBasename name (optionally without extension) of a resource on classpath
-     * @return configuration for an application relative to context class loader
-     */
-    public static Config load(String resourceBasename) {
-        return load(resourceBasename, ConfigParseOptions.defaults(),
-                ConfigResolveOptions.defaults());
-    }
-
-    /**
-     * Like {@link #load(String)} but uses the supplied class loader instead of
-     * the current thread's context class loader.
-     *
-     * <p>
-     * To load a standalone resource (without the default reference and default
-     * overrides), use {@link #parseResourcesAnySyntax(ClassLoader, String)}
-     * rather than this method. To load only the reference config use
-     * {@link #defaultReference(ClassLoader)} and to load only the overrides use
-     * {@link #defaultOverrides(ClassLoader)}.
-     *
-     * @param loader           class loader to look for resources in
-     * @param resourceBasename basename (no .conf/.json/.properties suffix)
-     * @return configuration for an application relative to given class loader
-     */
-    public static Config load(ClassLoader loader, String resourceBasename) {
-        return load(resourceBasename, ConfigParseOptions.defaults().setClassLoader(loader),
-                ConfigResolveOptions.defaults());
-    }
-
-    /**
-     * Like {@link #load(String)} but allows you to specify parse and resolve
-     * options.
-     *
-     * @param resourceBasename the classpath resource name with optional extension
-     * @param parseOptions     options to use when parsing the resource
-     * @param resolveOptions   options to use when resolving the stack
-     * @return configuration for an application
-     */
-    public static Config load(String resourceBasename, ConfigParseOptions parseOptions,
-                              ConfigResolveOptions resolveOptions) {
-        ConfigParseOptions withLoader = ensureClassLoader(parseOptions, "load");
-        Config appConfig = ConfigFactory.parseResourcesAnySyntax(resourceBasename, withLoader);
-        return load(withLoader.getClassLoader(), appConfig, resolveOptions);
-    }
-
-    /**
-     * Like {@link #load(String, ConfigParseOptions, ConfigResolveOptions)} but
-     * has a class loader parameter that overrides any from the
-     * {@code ConfigParseOptions}.
-     *
-     * @param loader           class loader in which to find resources (overrides loader in
-     *                         parse options)
-     * @param resourceBasename the classpath resource name with optional extension
-     * @param parseOptions     options to use when parsing the resource (class loader
-     *                         overridden)
-     * @param resolveOptions   options to use when resolving the stack
-     * @return configuration for an application
-     */
-    public static Config load(ClassLoader loader, String resourceBasename,
-                              ConfigParseOptions parseOptions, ConfigResolveOptions resolveOptions) {
-        return load(resourceBasename, parseOptions.setClassLoader(loader), resolveOptions);
-    }
-
-    private static ClassLoader checkedContextClassLoader(String methodName) {
-        ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        if (loader == null) {
-            throw new ConfigException.BugOrBroken("Context class loader is not set for the current thread; "
-                    + "if Thread.currentThread().getContextClassLoader() returns null, you must pass a ClassLoader "
-                    + "explicitly to ConfigFactory."
-                    + methodName);
-        }
-        return loader;
-    }
-
-    private static ConfigParseOptions ensureClassLoader(ConfigParseOptions options, String methodName) {
-        if (options.getClassLoader() == null) {
-            return options.setClassLoader(checkedContextClassLoader(methodName));
-        }
-        return options;
-    }
-
-    /**
-     * Assembles a standard configuration using a custom <code>Config</code>
-     * object rather than loading "application.conf". The <code>Config</code>
-     * object will be sandwiched between the default reference config and
-     * default overrides and then resolved.
-     *
-     * @param config the application's portion of the configuration
-     * @return resolved configuration with overrides and fallbacks added
-     */
-    public static Config load(Config config) {
-        return load(checkedContextClassLoader("load"), config);
-    }
-
-    /**
-     * Like {@link #load(Config)} but allows you to specify
-     * the class loader for looking up resources.
-     *
-     * @param loader the class loader to use to find resources
-     * @param config the application's portion of the configuration
-     * @return resolved configuration with overrides and fallbacks added
-     */
-    public static Config load(ClassLoader loader, Config config) {
-        return load(loader, config, ConfigResolveOptions.defaults());
-    }
-
-    /**
-     * Like {@link #load(Config)} but allows you to specify
-     * {@link ConfigResolveOptions}.
-     *
-     * @param config         the application's portion of the configuration
-     * @param resolveOptions options for resolving the assembled config stack
-     * @return resolved configuration with overrides and fallbacks added
-     */
-    public static Config load(Config config, ConfigResolveOptions resolveOptions) {
-        return load(checkedContextClassLoader("load"), config, resolveOptions);
-    }
-
-    /**
-     * Like {@link #load(Config, ConfigResolveOptions)} but allows you to specify
-     * a class loader other than the context class loader.
-     *
-     * @param loader         class loader to use when looking up override and reference
-     *                       configs
-     * @param config         the application's portion of the configuration
-     * @param resolveOptions options for resolving the assembled config stack
-     * @return resolved configuration with overrides and fallbacks added
-     */
-    public static Config load(ClassLoader loader, Config config, ConfigResolveOptions resolveOptions) {
-        return defaultOverrides(loader).withFallback(config).withFallback(defaultReference(loader))
-                .resolve(resolveOptions);
-    }
-
-
-    /**
-     * Loads a default configuration, equivalent to {@link #load(Config)
-     * load(defaultApplication())} in most cases. This configuration should be used by
-     * libraries and frameworks unless an application provides a different one.
-     * <p>
-     * This method may return a cached singleton so will not see changes to
-     * system properties or config files. (Use {@link #invalidateCaches()} to
-     * force it to reload.)
-     *
-     * @return configuration for an application
-     */
-    public static Config load() {
-        ClassLoader loader = checkedContextClassLoader("load");
-        return load(loader);
-    }
-
-    /**
-     * Like {@link #load()} but allows specifying parse options.
-     *
-     * @param parseOptions Options for parsing resources
-     * @return configuration for an application
-     */
-    public static Config load(ConfigParseOptions parseOptions) {
-        return load(parseOptions, ConfigResolveOptions.defaults());
-    }
-
-    /**
-     * Like {@link #load()} but allows specifying a class loader other than the
-     * thread's current context class loader.
-     *
-     * @param loader class loader for finding resources
-     * @return configuration for an application
-     */
-    public static Config load(final ClassLoader loader) {
-        final ConfigParseOptions withLoader = ConfigParseOptions.defaults().setClassLoader(loader);
-        return ConfigImpl.computeCachedConfig(loader, "load", new Callable<Config>() {
-            @Override
-            public Config call() {
-                return load(loader, defaultApplication(withLoader));
-            }
-        });
-    }
-
-    /**
-     * Like {@link #load()} but allows specifying a class loader other than the
-     * thread's current context class loader and also specify parse options.
-     *
-     * @param loader       class loader for finding resources (overrides any loader in parseOptions)
-     * @param parseOptions Options for parsing resources
-     * @return configuration for an application
-     */
-    public static Config load(ClassLoader loader, ConfigParseOptions parseOptions) {
-        return load(parseOptions.setClassLoader(loader));
-    }
-
-    /**
-     * Like {@link #load()} but allows specifying a class loader other than the
-     * thread's current context class loader and also specify resolve options.
-     *
-     * @param loader         class loader for finding resources
-     * @param resolveOptions options for resolving the assembled config stack
-     * @return configuration for an application
-     */
-    public static Config load(ClassLoader loader, ConfigResolveOptions resolveOptions) {
-        return load(loader, ConfigParseOptions.defaults(), resolveOptions);
-    }
-
-
-    /**
-     * Like {@link #load()} but allows specifying a class loader other than the
-     * thread's current context class loader, parse options, and resolve options.
-     *
-     * @param loader         class loader for finding resources (overrides any loader in parseOptions)
-     * @param parseOptions   Options for parsing resources
-     * @param resolveOptions options for resolving the assembled config stack
-     * @return configuration for an application
-     */
-    public static Config load(ClassLoader loader, ConfigParseOptions parseOptions, ConfigResolveOptions resolveOptions) {
-        final ConfigParseOptions withLoader = ensureClassLoader(parseOptions, "load");
-        return load(loader, defaultApplication(withLoader), resolveOptions);
-    }
-
-    /**
-     * Like {@link #load()} but allows specifying parse options and resolve
-     * options.
-     *
-     * @param parseOptions   Options for parsing resources
-     * @param resolveOptions options for resolving the assembled config stack
-     * @return configuration for an application
-     * @since 1.3.0
-     */
-    public static Config load(ConfigParseOptions parseOptions, final ConfigResolveOptions resolveOptions) {
-        final ConfigParseOptions withLoader = ensureClassLoader(parseOptions, "load");
-        return load(defaultApplication(withLoader), resolveOptions);
-    }
-
-    /**
-     * Obtains the default reference configuration, which is currently created
-     * by merging all resources "reference.conf" found on the classpath and
-     * overriding the result with system properties. The returned reference
-     * configuration will already have substitutions resolved.
-     *
-     * <p>
-     * Libraries and frameworks should ship with a "reference.conf" in their
-     * jar.
-     *
-     * <p>
-     * The reference config must be looked up in the class loader that contains
-     * the libraries that you want to use with this config, so the
-     * "reference.conf" for each library can be found. Use
-     * {@link #defaultReference(ClassLoader)} if the context class loader is not
-     * suitable.
-     *
-     * <p>
-     * The {@link #load()} methods merge this configuration for you
-     * automatically.
-     *
-     * <p>
-     * Future versions may look for reference configuration in more places. It
-     * is not guaranteed that this method <em>only</em> looks at
-     * "reference.conf".
-     *
-     * @return the default reference config for context class loader
-     */
-    public static Config defaultReference() {
-        return defaultReference(checkedContextClassLoader("defaultReference"));
-    }
-
-    /**
-     * Like {@link #defaultReference()} but allows you to specify a class loader
-     * to use rather than the current context class loader.
-     *
-     * @param loader class loader to look for resources in
-     * @return the default reference config for this class loader
-     */
-    public static Config defaultReference(ClassLoader loader) {
-        return ConfigImpl.defaultReference(loader);
-    }
-
-    /**
-     * Obtains the default override configuration, which currently consists of
-     * system properties. The returned override configuration will already have
-     * substitutions resolved.
-     *
-     * <p>
-     * The {@link #load()} methods merge this configuration for you
-     * automatically.
-     *
-     * <p>
-     * Future versions may get overrides in more places. It is not guaranteed
-     * that this method <em>only</em> uses system properties.
-     *
-     * @return the default override configuration
-     */
-    public static Config defaultOverrides() {
-        return systemProperties();
-    }
-
-    /**
-     * Like {@link #defaultOverrides()} but allows you to specify a class loader
-     * to use rather than the current context class loader.
-     *
-     * @param loader class loader to look for resources in
-     * @return the default override configuration
-     */
-    public static Config defaultOverrides(ClassLoader loader) {
-        return systemProperties();
-    }
-
-    /**
-     * Obtains the default application-specific configuration,
-     * which defaults to parsing <code>application.conf</code>,
-     * <code>application.json</code>, and
-     * <code>application.properties</code> on the classpath, but
-     * can also be rerouted using the <code>config.file</code>,
-     * <code>config.resource</code>, and <code>config.url</code>
-     * system properties.
-     *
-     * <p> The no-arguments {@link #load()} method automatically
-     * stacks the {@link #defaultReference()}, {@link
-     * #defaultApplication()}, and {@link #defaultOverrides()}
-     * configs. You would use <code>defaultApplication()</code>
-     * directly only if you're somehow customizing behavior by
-     * reimplementing <code>load()</code>.
-     *
-     * <p>The configuration returned by
-     * <code>defaultApplication()</code> will not be resolved
-     * already, in contrast to <code>defaultReference()</code> and
-     * <code>defaultOverrides()</code>. This is because
-     * application.conf would normally be resolved <em>after</em>
-     * merging with the reference and override configs.
-     *
-     * <p>
-     * If the system properties <code>config.resource</code>,
-     * <code>config.file</code>, or <code>config.url</code> are set, then the
-     * classpath resource, file, or URL specified in those properties will be
-     * used rather than the default
-     * <code>application.{conf,json,properties}</code> classpath resources.
-     * These system properties should not be set in code (after all, you can
-     * just parse whatever you want manually and then use {@link #load(Config)}
-     * if you don't want to use <code>application.conf</code>). The properties
-     * are intended for use by the person or script launching the application.
-     * For example someone might have a <code>production.conf</code> that
-     * include <code>application.conf</code> but then change a couple of values.
-     * When launching the app they could specify
-     * <code>-Dconfig.resource=production.conf</code> to get production mode.
-     *
-     * <p>
-     * If no system properties are set to change the location of the default
-     * configuration, <code>defaultApplication()</code> is equivalent to
-     * <code>ConfigFactory.parseResources("application")</code>.
-     *
-     * @return the default application.conf or system-property-configured configuration
-     * @since 1.3.0
-     */
-    public static Config defaultApplication() {
-        return defaultApplication(ConfigParseOptions.defaults());
-    }
-
-    /**
-     * Like {@link #defaultApplication()} but allows you to specify a class loader
-     * to use rather than the current context class loader.
-     *
-     * @param loader class loader to look for resources in
-     * @return the default application configuration
-     * @since 1.3.0
-     */
-    public static Config defaultApplication(ClassLoader loader) {
-        return defaultApplication(ConfigParseOptions.defaults().setClassLoader(loader));
-    }
-
-    /**
-     * Like {@link #defaultApplication()} but allows you to specify parse options.
-     *
-     * @param options the options
-     * @return the default application configuration
-     * @since 1.3.0
-     */
-    public static Config defaultApplication(ConfigParseOptions options) {
-        return getConfigLoadingStrategy().parseApplicationConfig(ensureClassLoader(options, "defaultApplication"));
-    }
-
-    /**
-     * Reloads any cached configs, picking up changes to system properties for
-     * example. Because a {@link Config} is immutable, anyone with a reference
-     * to the old configs will still have the same outdated objects. However,
-     * new calls to {@link #load()} or {@link #defaultOverrides()} or
-     * {@link #defaultReference} may return a new object.
-     * <p>
-     * This method is primarily intended for use in unit tests, for example,
-     * that may want to update a system property then confirm that it's used
-     * correctly. In many cases, use of this method may indicate there's a
-     * better way to set up your code.
-     * <p>
-     * Caches may be reloaded immediately or lazily; once you call this method,
-     * the reload can occur at any time, even during the invalidation process.
-     * So FIRST make the changes you'd like the caches to notice, then SECOND
-     * call this method to invalidate caches. Don't expect that invalidating,
-     * making changes, then calling {@link #load()}, will work. Make changes
-     * before you invalidate.
-     */
-    public static void invalidateCaches() {
-        // We rely on this having the side effect that it drops
-        // all caches
-        ConfigImpl.reloadSystemPropertiesConfig();
-        ConfigImpl.reloadEnvVariablesConfig();
-    }
-
-    /**
-     * Gets an empty configuration. See also {@link #empty(String)} to create an
-     * empty configuration with a description, which may improve user-visible
-     * error messages.
-     *
-     * @return an empty configuration
-     */
-    public static Config empty() {
-        return empty(null);
-    }
-
-    /**
-     * Gets an empty configuration with a description to be used to create a
-     * {@link ConfigOrigin} for this <code>Config</code>. The description should
-     * be very short and say what the configuration is, like "default settings"
-     * or "foo settings" or something. (Presumably you will merge some actual
-     * settings into this empty config using {@link Config#withFallback}, making
-     * the description more useful.)
-     *
-     * @param originDescription description of the config
-     * @return an empty configuration
-     */
-    public static Config empty(String originDescription) {
-        return ConfigImpl.emptyConfig(originDescription);
-    }
-
-    /**
-     * Gets a <code>Config</code> containing the system properties from
-     * {@link java.lang.System#getProperties()}, parsed and converted as with
-     * {@link #parseProperties}.
-     * <p>
-     * This method can return a global immutable singleton, so it's preferred
-     * over parsing system properties yourself.
-     * <p>
-     * {@link #load} will include the system properties as overrides already, as
-     * will {@link #defaultReference} and {@link #defaultOverrides}.
-     *
-     * <p>
-     * Because this returns a singleton, it will not notice changes to system
-     * properties made after the first time this method is called. Use
-     * {@link #invalidateCaches()} to force the singleton to reload if you
-     * modify system properties.
-     *
-     * @return system properties parsed into a <code>Config</code>
-     */
-    public static Config systemProperties() {
-        return ConfigImpl.systemPropertiesAsConfig();
-    }
-
-    /**
-     * Gets a <code>Config</code> containing the system's environment variables.
-     * This method can return a global immutable singleton.
-     *
-     * <p>
-     * Environment variables are used as fallbacks when resolving substitutions
-     * whether or not this object is included in the config being resolved, so
-     * you probably don't need to use this method for most purposes. It can be a
-     * nicer API for accessing environment variables than raw
-     * {@link java.lang.System#getenv(String)} though, since you can use methods
-     * such as {@link Config#getInt}.
-     *
-     * @return system environment variables parsed into a <code>Config</code>
-     */
-    public static Config systemEnvironment() {
-        return ConfigImpl.envVariablesAsConfig();
-    }
-
-    /**
-     * Converts a Java {@link java.util.Properties} object to a
-     * {@link ConfigObject} using the rules documented in the <a
-     * href="https://github.com/lightbend/config/blob/master/HOCON.md">HOCON
-     * spec</a>. The keys in the <code>Properties</code> object are split on the
-     * period character '.' and treated as paths. The values will all end up as
-     * string values. If you have both "a=foo" and "a.b=bar" in your properties
-     * file, so "a" is both the object containing "b" and the string "foo", then
-     * the string value is dropped.
-     *
-     * <p>
-     * If you want to have <code>System.getProperties()</code> as a
-     * ConfigObject, it's better to use the {@link #systemProperties()} method
-     * which returns a cached global singleton.
-     *
-     * @param properties a Java Properties object
-     * @param options    the parse options
-     * @return the parsed configuration
-     */
-    public static Config parseProperties(Properties properties,
-                                         ConfigParseOptions options) {
-        return Parseable.newProperties(properties, options).parse().toConfig();
-    }
-
-    /**
-     * Like {@link #parseProperties(Properties, ConfigParseOptions)} but uses default
-     * parse options.
-     *
-     * @param properties a Java Properties object
-     * @return the parsed configuration
-     */
-    public static Config parseProperties(Properties properties) {
-        return parseProperties(properties, ConfigParseOptions.defaults());
-    }
-
-    /**
-     * Parses a Reader into a Config instance. Does not call
-     * {@link Config#resolve} or merge the parsed stream with any
-     * other configuration; this method parses a single stream and
-     * does nothing else. It does process "include" statements in
-     * the parsed stream, and may end up doing other IO due to those
-     * statements.
-     *
-     * @param reader  the reader to parse
-     * @param options parse options to control how the reader is interpreted
-     * @return the parsed configuration
-     * @throws ConfigException on IO or parse errors
-     */
-    public static Config parseReader(Reader reader, ConfigParseOptions options) {
-        return Parseable.newReader(reader, options).parse().toConfig();
-    }
-
-    /**
-     * Parses a reader into a Config instance as with
-     * {@link #parseReader(Reader, ConfigParseOptions)} but always uses the
-     * default parse options.
-     *
-     * @param reader the reader to parse
-     * @return the parsed configuration
-     * @throws ConfigException on IO or parse errors
-     */
-    public static Config parseReader(Reader reader) {
-        return parseReader(reader, ConfigParseOptions.defaults());
-    }
-
-    /**
-     * Parses a URL into a Config instance. Does not call
-     * {@link Config#resolve} or merge the parsed stream with any
-     * other configuration; this method parses a single stream and
-     * does nothing else. It does process "include" statements in
-     * the parsed stream, and may end up doing other IO due to those
-     * statements.
-     *
-     * @param url     the url to parse
-     * @param options parse options to control how the url is interpreted
-     * @return the parsed configuration
-     * @throws ConfigException on IO or parse errors
-     */
-    public static Config parseURL(URL url, ConfigParseOptions options) {
-        return Parseable.newURL(url, options).parse().toConfig();
-    }
-
-    /**
-     * Parses a url into a Config instance as with
-     * {@link #parseURL(URL, ConfigParseOptions)} but always uses the
-     * default parse options.
-     *
-     * @param url the url to parse
-     * @return the parsed configuration
-     * @throws ConfigException on IO or parse errors
-     */
-    public static Config parseURL(URL url) {
-        return parseURL(url, ConfigParseOptions.defaults());
-    }
-
-    /**
-     * Parses a file into a Config instance. Does not call
-     * {@link Config#resolve} or merge the file with any other
-     * configuration; this method parses a single file and does
-     * nothing else. It does process "include" statements in the
-     * parsed file, and may end up doing other IO due to those
-     * statements.
-     *
-     * @param file    the file to parse
-     * @param options parse options to control how the file is interpreted
-     * @return the parsed configuration
-     * @throws ConfigException on IO or parse errors
-     */
-    public static Config parseFile(File file, ConfigParseOptions options) {
-        return Parseable.newFile(file, options).parse().toConfig();
-    }
-
-    /**
-     * Parses a file into a Config instance as with
-     * {@link #parseFile(File, ConfigParseOptions)} but always uses the
-     * default parse options.
-     *
-     * @param file the file to parse
-     * @return the parsed configuration
-     * @throws ConfigException on IO or parse errors
-     */
-    public static Config parseFile(File file) {
-        return parseFile(file, ConfigParseOptions.defaults());
-    }
-
-    /**
-     * Parses a file with a flexible extension. If the <code>fileBasename</code>
-     * already ends in a known extension, this method parses it according to
-     * that extension (the file's syntax must match its extension). If the
-     * <code>fileBasename</code> does not end in an extension, it parses files
-     * with all known extensions and merges whatever is found.
-     *
-     * <p>
-     * In the current implementation, the extension ".conf" forces
-     * {@link ConfigSyntax#CONF}, ".json" forces {@link ConfigSyntax#JSON}, and
-     * ".properties" forces {@link ConfigSyntax#PROPERTIES}. When merging files,
-     * ".conf" falls back to ".json" falls back to ".properties".
-     *
-     * <p>
-     * Future versions of the implementation may add additional syntaxes or
-     * additional extensions. However, the ordering (fallback priority) of the
-     * three current extensions will remain the same.
-     *
-     * <p>
-     * If <code>options</code> forces a specific syntax, this method only parses
-     * files with an extension matching that syntax.
-     *
-     * <p>
-     * If {@link ConfigParseOptions#getAllowMissing options.getAllowMissing()}
-     * is true, then no files have to exist; if false, then at least one file
-     * has to exist.
-     *
-     * @param fileBasename a filename with or without extension
-     * @param options      parse options
-     * @return the parsed configuration
-     */
-    public static Config parseFileAnySyntax(File fileBasename,
-                                            ConfigParseOptions options) {
-        return ConfigImpl.parseFileAnySyntax(fileBasename, options).toConfig();
-    }
-
-    /**
-     * Like {@link #parseFileAnySyntax(File, ConfigParseOptions)} but always uses
-     * default parse options.
-     *
-     * @param fileBasename a filename with or without extension
-     * @return the parsed configuration
-     */
-    public static Config parseFileAnySyntax(File fileBasename) {
-        return parseFileAnySyntax(fileBasename, ConfigParseOptions.defaults());
-    }
-
-    /**
-     * Parses all resources on the classpath with the given name and merges them
-     * into a single <code>Config</code>.
-     *
-     * <p>
-     * If the resource name does not begin with a "/", it will have the supplied
-     * class's package added to it, in the same way as
-     * {@link java.lang.Class#getResource}.
-     *
-     * <p>
-     * Duplicate resources with the same name are merged such that ones returned
-     * earlier from {@link ClassLoader#getResources} fall back to (have higher
-     * priority than) the ones returned later. This implies that resources
-     * earlier in the classpath override those later in the classpath when they
-     * configure the same setting. However, in practice real applications may
-     * not be consistent about classpath ordering, so be careful. It may be best
-     * to avoid assuming too much.
-     *
-     * @param klass    <code>klass.getClassLoader()</code> will be used to load
-     *                 resources, and non-absolute resource names will have this
-     *                 class's package added
-     * @param resource resource to look up, relative to <code>klass</code>'s package
-     *                 or absolute starting with a "/"
-     * @param options  parse options
-     * @return the parsed configuration
-     */
-    public static Config parseResources(Class<?> klass, String resource,
-                                        ConfigParseOptions options) {
-        return Parseable.newResources(klass, resource, options).parse()
-                .toConfig();
-    }
-
-    /**
-     * Like {@link #parseResources(Class, String, ConfigParseOptions)} but always uses
-     * default parse options.
-     *
-     * @param klass    <code>klass.getClassLoader()</code> will be used to load
-     *                 resources, and non-absolute resource names will have this
-     *                 class's package added
-     * @param resource resource to look up, relative to <code>klass</code>'s package
-     *                 or absolute starting with a "/"
-     * @return the parsed configuration
-     */
-    public static Config parseResources(Class<?> klass, String resource) {
-        return parseResources(klass, resource, ConfigParseOptions.defaults());
-    }
-
-    /**
-     * Parses classpath resources with a flexible extension. In general, this
-     * method has the same behavior as
-     * {@link #parseFileAnySyntax(File, ConfigParseOptions)} but for classpath
-     * resources instead, as in {@link #parseResources}.
-     *
-     * <p>
-     * There is a thorny problem with this method, which is that
-     * {@link java.lang.ClassLoader#getResources} must be called separately for
-     * each possible extension. The implementation ends up with separate lists
-     * of resources called "basename.conf" and "basename.json" for example. As a
-     * result, the ideal ordering between two files with different extensions is
-     * unknown; there is no way to figure out how to merge the two lists in
-     * classpath order. To keep it simple, the lists are simply concatenated,
-     * with the same syntax priorities as
-     * {@link #parseFileAnySyntax(File, ConfigParseOptions) parseFileAnySyntax()}
-     * - all ".conf" resources are ahead of all ".json" resources which are
-     * ahead of all ".properties" resources.
-     *
-     * @param klass            class which determines the <code>ClassLoader</code> and the
-     *                         package for relative resource names
-     * @param resourceBasename a resource name as in {@link java.lang.Class#getResource},
-     *                         with or without extension
-     * @param options          parse options (class loader is ignored in favor of the one
-     *                         from klass)
-     * @return the parsed configuration
-     */
-    public static Config parseResourcesAnySyntax(Class<?> klass, String resourceBasename,
-                                                 ConfigParseOptions options) {
-        return ConfigImpl.parseResourcesAnySyntax(klass, resourceBasename,
-                options).toConfig();
-    }
-
-    /**
-     * Like {@link #parseResourcesAnySyntax(Class, String, ConfigParseOptions)}
-     * but always uses default parse options.
-     *
-     * @param klass            <code>klass.getClassLoader()</code> will be used to load
-     *                         resources, and non-absolute resource names will have this
-     *                         class's package added
-     * @param resourceBasename a resource name as in {@link java.lang.Class#getResource},
-     *                         with or without extension
-     * @return the parsed configuration
-     */
-    public static Config parseResourcesAnySyntax(Class<?> klass, String resourceBasename) {
-        return parseResourcesAnySyntax(klass, resourceBasename, ConfigParseOptions.defaults());
-    }
-
-    /**
-     * Parses all resources on the classpath with the given name and merges them
-     * into a single <code>Config</code>.
-     *
-     * <p>
-     * This works like {@link java.lang.ClassLoader#getResource}, not like
-     * {@link java.lang.Class#getResource}, so the name never begins with a
-     * slash.
-     *
-     * <p>
-     * See {@link #parseResources(Class, String, ConfigParseOptions)} for full
-     * details.
-     *
-     * @param loader   will be used to load resources by setting this loader on the
-     *                 provided options
-     * @param resource resource to look up
-     * @param options  parse options (class loader is ignored)
-     * @return the parsed configuration
-     */
-    public static Config parseResources(ClassLoader loader, String resource,
-                                        ConfigParseOptions options) {
-        return parseResources(resource, options.setClassLoader(loader));
-    }
-
-    /**
-     * Like {@link #parseResources(ClassLoader, String, ConfigParseOptions)} but always uses
-     * default parse options.
-     *
-     * @param loader   will be used to load resources
-     * @param resource resource to look up in the loader
-     * @return the parsed configuration
-     */
-    public static Config parseResources(ClassLoader loader, String resource) {
-        return parseResources(loader, resource, ConfigParseOptions.defaults());
-    }
-
-    /**
-     * Parses classpath resources with a flexible extension. In general, this
-     * method has the same behavior as
-     * {@link #parseFileAnySyntax(File, ConfigParseOptions)} but for classpath
-     * resources instead, as in
-     * {@link #parseResources(ClassLoader, String, ConfigParseOptions)}.
-     *
-     * <p>
-     * {@link #parseResourcesAnySyntax(Class, String, ConfigParseOptions)} differs
-     * in the syntax for the resource name, but otherwise see
-     * {@link #parseResourcesAnySyntax(Class, String, ConfigParseOptions)} for
-     * some details and caveats on this method.
-     *
-     * @param loader           class loader to look up resources in, will be set on options
-     * @param resourceBasename a resource name as in
-     *                         {@link java.lang.ClassLoader#getResource}, with or without
-     *                         extension
-     * @param options          parse options (class loader ignored)
-     * @return the parsed configuration
-     */
-    public static Config parseResourcesAnySyntax(ClassLoader loader, String resourceBasename,
-                                                 ConfigParseOptions options) {
-        return ConfigImpl.parseResourcesAnySyntax(resourceBasename, options.setClassLoader(loader))
-                .toConfig();
-    }
-
-    /**
-     * Like {@link #parseResourcesAnySyntax(ClassLoader, String, ConfigParseOptions)} but always uses
-     * default parse options.
-     *
-     * @param loader           will be used to load resources
-     * @param resourceBasename a resource name as in
-     *                         {@link java.lang.ClassLoader#getResource}, with or without
-     *                         extension
-     * @return the parsed configuration
-     */
-    public static Config parseResourcesAnySyntax(ClassLoader loader, String resourceBasename) {
-        return parseResourcesAnySyntax(loader, resourceBasename, ConfigParseOptions.defaults());
-    }
-
-    /**
-     * Like {@link #parseResources(ClassLoader, String, ConfigParseOptions)} but
-     * uses thread's current context class loader if none is set in the
-     * ConfigParseOptions.
-     *
-     * @param resource the resource name
-     * @param options  parse options
-     * @return the parsed configuration
-     */
-    public static Config parseResources(String resource, ConfigParseOptions options) {
-        ConfigParseOptions withLoader = ensureClassLoader(options, "parseResources");
-        return Parseable.newResources(resource, withLoader).parse().toConfig();
-    }
-
-    /**
-     * Like {@link #parseResources(ClassLoader, String)} but uses thread's
-     * current context class loader.
-     *
-     * @param resource the resource name
-     * @return the parsed configuration
-     */
-    public static Config parseResources(String resource) {
-        return parseResources(resource, ConfigParseOptions.defaults());
-    }
-
-    /**
-     * Like
-     * {@link #parseResourcesAnySyntax(ClassLoader, String, ConfigParseOptions)}
-     * but uses thread's current context class loader.
-     *
-     * @param resourceBasename the resource basename (no file type suffix)
-     * @param options          parse options
-     * @return the parsed configuration
-     */
-    public static Config parseResourcesAnySyntax(String resourceBasename, ConfigParseOptions options) {
-        return ConfigImpl.parseResourcesAnySyntax(resourceBasename, options).toConfig();
-    }
-
-    /**
-     * Like {@link #parseResourcesAnySyntax(ClassLoader, String)} but uses
-     * thread's current context class loader.
-     *
-     * @param resourceBasename the resource basename (no file type suffix)
-     * @return the parsed configuration
-     */
-    public static Config parseResourcesAnySyntax(String resourceBasename) {
-        return parseResourcesAnySyntax(resourceBasename, ConfigParseOptions.defaults());
-    }
-
-    /**
-     * Parses a string (which should be valid HOCON or JSON by default, or
-     * the syntax specified in the options otherwise).
-     *
-     * @param s       string to parse
-     * @param options parse options
-     * @return the parsed configuration
-     */
-    public static Config parseString(String s, ConfigParseOptions options) {
-        return Parseable.newString(s, options).parse().toConfig();
-    }
-
-    /**
-     * Parses a string (which should be valid HOCON or JSON).
-     *
-     * @param s string to parse
-     * @return the parsed configuration
-     */
-    public static Config parseString(String s) {
-        return parseString(s, ConfigParseOptions.defaults());
-    }
-
-    /**
-     * Creates a {@code Config} based on a {@link java.util.Map} from paths to
-     * plain Java values. Similar to
-     * {@link ConfigValueFactory#fromMap(Map, String)}, except the keys in the
-     * map are path expressions, rather than keys; and correspondingly it
-     * returns a {@code Config} instead of a {@code ConfigObject}. This is more
-     * convenient if you are writing literal maps in code, and less convenient
-     * if you are getting your maps from some data source such as a parser.
-     *
-     * <p>
-     * An exception will be thrown (and it is a bug in the caller of the method)
-     * if a path is both an object and a value, for example if you had both
-     * "a=foo" and "a.b=bar", then "a" is both the string "foo" and the parent
-     * object of "b". The caller of this method should ensure that doesn't
-     * happen.
-     *
-     * @param values            map from paths to plain Java objects
-     * @param originDescription description of what this map represents, like a filename, or
-     *                          "default settings" (origin description is used in error
-     *                          messages)
-     * @return the map converted to a {@code Config}
-     */
-    public static Config parseMap(Map<String, ? extends Object> values,
-                                  String originDescription) {
-        return ConfigImpl.fromPathMap(values, originDescription).toConfig();
-    }
-
-    /**
-     * See the other overload of {@link #parseMap(Map, String)} for details,
-     * this one just uses a default origin description.
-     *
-     * @param values map from paths to plain Java values
-     * @return the map converted to a {@code Config}
-     */
-    public static Config parseMap(Map<String, ? extends Object> values) {
-        return parseMap(values, null);
-    }
-
-    private static ConfigLoadingStrategy getConfigLoadingStrategy() {
-        String className = System.getProperties().getProperty(STRATEGY_PROPERTY_NAME);
-
-        if (className != null) {
-            try {
-                return ConfigLoadingStrategy.class.cast(Class.forName(className).newInstance());
-            } catch (Throwable e) {
-                throw new ConfigException.BugOrBroken("Failed to load strategy: " + className, e);
-            }
-        }
-        return new DefaultConfigLoadingStrategy();
-    }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncludeContext.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncludeContext.java
deleted file mode 100644
index 892b018..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncludeContext.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-/**
- * Context provided to a {@link ConfigIncluder}; this interface is only useful
- * inside a {@code ConfigIncluder} implementation, and is not intended for apps
- * to implement.
- *
- * <p>
- * <em>Do not implement this interface</em>; it should only be implemented by
- * the config library. Arbitrary implementations will not work because the
- * library internals assume a specific concrete implementation. Also, this
- * interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigIncludeContext {
-    /**
-     * Tries to find a name relative to whatever is doing the including, for
-     * example in the same directory as the file doing the including. Returns
-     * null if it can't meaningfully create a relative name. The returned
-     * parseable may not exist; this function is not required to do any IO, just
-     * compute what the name would be.
-     * <p>
-     * The passed-in filename has to be a complete name (with extension), not
-     * just a basename. (Include statements in config files are allowed to give
-     * just a basename.)
-     *
-     * @param filename the name to make relative to the resource doing the including
-     * @return parseable item relative to the resource doing the including, or
-     * null
-     */
-    ConfigParseable relativeTo(String filename);
-
-    /**
-     * Parse options to use (if you use another method to get a
-     * {@link ConfigParseable} then use {@link ConfigParseable#options()}
-     * instead though).
-     *
-     * @return the parse options
-     */
-    ConfigParseOptions parseOptions();
-
-
-    /**
-     * Copy this {@link ConfigIncludeContext} giving it a new value for its parseOptions.
-     *
-     * @param options new parse options to use
-     * @return the updated copy of this context
-     */
-    ConfigIncludeContext setParseOptions(ConfigParseOptions options);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluder.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluder.java
deleted file mode 100644
index cac9c28..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluder.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-/**
- * Implement this interface and provide an instance to
- * {@link ConfigParseOptions#setIncluder ConfigParseOptions.setIncluder()} to
- * customize handling of {@code include} statements in config files. You may
- * also want to implement {@link ConfigIncluderClasspath},
- * {@link ConfigIncluderFile}, and {@link ConfigIncluderURL}, or not.
- */
-public interface ConfigIncluder {
-    /**
-     * Returns a new includer that falls back to the given includer. This is how
-     * you can obtain the default includer; it will be provided as a fallback.
-     * It's up to your includer to chain to it if you want to. You might want to
-     * merge any files found by the fallback includer with any objects you load
-     * yourself.
-     * <p>
-     * It's important to handle the case where you already have the fallback
-     * with a "return this", i.e. this method should not create a new object if
-     * the fallback is the same one you already have. The same fallback may be
-     * added repeatedly.
-     *
-     * @param fallback the previous includer for chaining
-     * @return a new includer
-     */
-    ConfigIncluder withFallback(ConfigIncluder fallback);
-
-    /**
-     * Parses another item to be included. The returned object typically would
-     * not have substitutions resolved. You can throw a ConfigException here to
-     * abort parsing, or return an empty object, but may not return null.
-     * <p>
-     * This method is used for a "heuristic" include statement that does not
-     * specify file, URL, or classpath resource. If the include statement does
-     * specify, then the same class implementing {@link ConfigIncluder} must
-     * also implement {@link ConfigIncluderClasspath},
-     * {@link ConfigIncluderFile}, or {@link ConfigIncluderURL} as needed, or a
-     * default includer will be used.
-     *
-     * @param context some info about the include context
-     * @param what    the include statement's argument
-     * @return a non-null ConfigObject
-     */
-    ConfigObject include(ConfigIncludeContext context, String what);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderClasspath.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderClasspath.java
deleted file mode 100644
index d9876a3..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderClasspath.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-/**
- * Implement this <em>in addition to</em> {@link ConfigIncluder} if you want to
- * support inclusion of files with the {@code include classpath("resource")}
- * syntax. If you do not implement this but do implement {@link ConfigIncluder},
- * attempts to load classpath resources will use the default includer.
- */
-public interface ConfigIncluderClasspath {
-    /**
-     * Parses another item to be included. The returned object typically would
-     * not have substitutions resolved. You can throw a ConfigException here to
-     * abort parsing, or return an empty object, but may not return null.
-     *
-     * @param context some info about the include context
-     * @param what    the include statement's argument
-     * @return a non-null ConfigObject
-     */
-    ConfigObject includeResources(ConfigIncludeContext context, String what);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderFile.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderFile.java
deleted file mode 100644
index 86fc2e3..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderFile.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import java.io.File;
-
-/**
- * Implement this <em>in addition to</em> {@link ConfigIncluder} if you want to
- * support inclusion of files with the {@code include file("filename")} syntax.
- * If you do not implement this but do implement {@link ConfigIncluder},
- * attempts to load files will use the default includer.
- */
-public interface ConfigIncluderFile {
-    /**
-     * Parses another item to be included. The returned object typically would
-     * not have substitutions resolved. You can throw a ConfigException here to
-     * abort parsing, or return an empty object, but may not return null.
-     *
-     * @param context some info about the include context
-     * @param what    the include statement's argument
-     * @return a non-null ConfigObject
-     */
-    ConfigObject includeFile(ConfigIncludeContext context, File what);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderURL.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderURL.java
deleted file mode 100644
index fe27ebb..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigIncluderURL.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import java.net.URL;
-
-/**
- * Implement this <em>in addition to</em> {@link ConfigIncluder} if you want to
- * support inclusion of files with the {@code include url("http://example.com")}
- * syntax. If you do not implement this but do implement {@link ConfigIncluder},
- * attempts to load URLs will use the default includer.
- */
-public interface ConfigIncluderURL {
-    /**
-     * Parses another item to be included. The returned object typically would
-     * not have substitutions resolved. You can throw a ConfigException here to
-     * abort parsing, or return an empty object, but may not return null.
-     *
-     * @param context some info about the include context
-     * @param what    the include statement's argument
-     * @return a non-null ConfigObject
-     */
-    ConfigObject includeURL(ConfigIncludeContext context, URL what);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigList.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigList.java
deleted file mode 100644
index 282fb3e..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigList.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import java.util.List;
-
-/**
- * Subtype of {@link ConfigValue} representing a list value, as in JSON's
- * {@code [1,2,3]} syntax.
- *
- * <p>
- * {@code ConfigList} implements {@code java.util.List<ConfigValue>} so you can
- * use it like a regular Java list. Or call {@link #unwrapped()} to unwrap the
- * list elements into plain Java values.
- *
- * <p>
- * Like all {@link ConfigValue} subtypes, {@code ConfigList} is immutable. This
- * makes it threadsafe and you never have to create "defensive copies." The
- * mutator methods from {@link java.util.List} all throw
- * {@link java.lang.UnsupportedOperationException}.
- *
- * <p>
- * The {@link ConfigValue#valueType} method on a list returns
- * {@link ConfigValueType#LIST}.
- *
- * <p>
- * <em>Do not implement {@code ConfigList}</em>; it should only be implemented
- * by the config library. Arbitrary implementations will not work because the
- * library internals assume a specific concrete implementation. Also, this
- * interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigList extends List<ConfigValue>, ConfigValue {
-
-    /**
-     * Recursively unwraps the list, returning a list of plain Java values such
-     * as Integer or String or whatever is in the list.
-     *
-     * @return a {@link java.util.List} containing plain Java objects
-     */
-    @Override
-    List<Object> unwrapped();
-
-    @Override
-    ConfigList withOrigin(ConfigOrigin origin);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigLoadingStrategy.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigLoadingStrategy.java
deleted file mode 100644
index 7727708..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigLoadingStrategy.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-/**
- * This method allows you to alter default config loading strategy for all the code which
- * calls {@link ConfigFactory#load}.
- * <p>
- * Usually you don't have to implement this interface but it may be required
- * when you fixing a improperly implemented library with unavailable source code.
- * <p>
- * You have to define VM property {@code config.strategy} to replace default strategy with your own.
- */
-public interface ConfigLoadingStrategy {
-    /**
-     * This method must load and parse application config.
-     *
-     * @param parseOptions {@link ConfigParseOptions} to use
-     * @return loaded config
-     */
-    Config parseApplicationConfig(ConfigParseOptions parseOptions);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigMemorySize.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigMemorySize.java
deleted file mode 100644
index 9ec0133..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigMemorySize.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-/**
- * An immutable class representing an amount of memory.  Use
- * static factory methods such as {@link
- * ConfigMemorySize#ofBytes(long)} to create instances.
- *
- * @since 1.3.0
- */
-public final class ConfigMemorySize {
-    private final long bytes;
-
-    private ConfigMemorySize(long bytes) {
-        if (bytes < 0) {
-            throw new IllegalArgumentException("Attempt to construct ConfigMemorySize with negative number: " + bytes);
-        }
-        this.bytes = bytes;
-    }
-
-    /**
-     * Constructs a ConfigMemorySize representing the given
-     * number of bytes.
-     *
-     * @param bytes a number of bytes
-     * @return an instance representing the number of bytes
-     * @since 1.3.0
-     */
-    public static ConfigMemorySize ofBytes(long bytes) {
-        return new ConfigMemorySize(bytes);
-    }
-
-    /**
-     * Gets the size in bytes.
-     *
-     * @return how many bytes
-     * @since 1.3.0
-     */
-    public long toBytes() {
-        return bytes;
-    }
-
-    @Override
-    public String toString() {
-        return "ConfigMemorySize(" + bytes + ")";
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (other instanceof ConfigMemorySize) {
-            return ((ConfigMemorySize) other).bytes == this.bytes;
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        // in Java 8 this can become Long.hashCode(bytes)
-        return Long.valueOf(bytes).hashCode();
-    }
-
-}
-
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigMergeable.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigMergeable.java
deleted file mode 100644
index 4032e9f..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigMergeable.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-/**
- * Marker for types whose instances can be merged, that is {@link Config} and
- * {@link ConfigValue}. Instances of {@code Config} and {@code ConfigValue} can
- * be combined into a single new instance using the
- * {@link ConfigMergeable#withFallback withFallback()} method.
- *
- * <p>
- * <em>Do not implement this interface</em>; it should only be implemented by
- * the config library. Arbitrary implementations will not work because the
- * library internals assume a specific concrete implementation. Also, this
- * interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigMergeable {
-    /**
-     * Returns a new value computed by merging this value with another, with
-     * keys in this value "winning" over the other one.
-     *
-     * <p>
-     * This associative operation may be used to combine configurations from
-     * multiple sources (such as multiple configuration files).
-     *
-     * <p>
-     * The semantics of merging are described in the <a
-     * href="https://github.com/lightbend/config/blob/master/HOCON.md">spec
-     * for HOCON</a>. Merging typically occurs when either the same object is
-     * created twice in the same file, or two config files are both loaded. For
-     * example:
-     *
-     * <pre>
-     *  foo = { a: 42 }
-     *  foo = { b: 43 }
-     * </pre>
-     * <p>
-     * Here, the two objects are merged as if you had written:
-     *
-     * <pre>
-     *  foo = { a: 42, b: 43 }
-     * </pre>
-     *
-     * <p>
-     * Only {@link ConfigObject} and {@link Config} instances do anything in
-     * this method (they need to merge the fallback keys into themselves). All
-     * other values just return the original value, since they automatically
-     * override any fallback. This means that objects do not merge "across"
-     * non-objects; if you write
-     * <code>object.withFallback(nonObject).withFallback(otherObject)</code>,
-     * then <code>otherObject</code> will simply be ignored. This is an
-     * intentional part of how merging works, because non-objects such as
-     * strings and integers replace (rather than merging with) any prior value:
-     *
-     * <pre>
-     * foo = { a: 42 }
-     * foo = 10
-     * </pre>
-     * <p>
-     * Here, the number 10 "wins" and the value of <code>foo</code> would be
-     * simply 10. Again, for details see the spec.
-     *
-     * @param other an object whose keys should be used as fallbacks, if the keys
-     *              are not present in this one
-     * @return a new object (or the original one, if the fallback doesn't get
-     * used)
-     */
-    ConfigMergeable withFallback(ConfigMergeable other);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigObject.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigObject.java
deleted file mode 100644
index 72f3024..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigObject.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import java.util.Map;
-
-/**
- * Subtype of {@link ConfigValue} representing an object (AKA dictionary or map)
- * value, as in JSON's curly brace <code>{ "a" : 42 }</code> syntax.
- *
- * <p>
- * An object may also be viewed as a {@link Config} by calling
- * {@link ConfigObject#toConfig()}.
- *
- * <p>
- * {@code ConfigObject} implements {@code java.util.Map<String, ConfigValue>} so
- * you can use it like a regular Java map. Or call {@link #unwrapped()} to
- * unwrap the map to a map with plain Java values rather than
- * {@code ConfigValue}.
- *
- * <p>
- * Like all {@link ConfigValue} subtypes, {@code ConfigObject} is immutable.
- * This makes it threadsafe and you never have to create "defensive copies." The
- * mutator methods from {@link java.util.Map} all throw
- * {@link java.lang.UnsupportedOperationException}.
- *
- * <p>
- * The {@link ConfigValue#valueType} method on an object returns
- * {@link ConfigValueType#OBJECT}.
- *
- * <p>
- * In most cases you want to use the {@link Config} interface rather than this
- * one. Call {@link #toConfig()} to convert a {@code ConfigObject} to a
- * {@code Config}.
- *
- * <p>
- * The API for a {@code ConfigObject} is in terms of keys, while the API for a
- * {@link Config} is in terms of path expressions. Conceptually,
- * {@code ConfigObject} is a tree of maps from keys to values, while a
- * {@code Config} is a one-level map from paths to values.
- *
- * <p>
- * Use {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath} to convert
- * between path expressions and individual path elements (keys).
- *
- * <p>
- * A {@code ConfigObject} may contain null values, which will have
- * {@link ConfigValue#valueType()} equal to {@link ConfigValueType#NULL}. If
- * {@link ConfigObject#get(Object)} returns Java's null then the key was not
- * present in the parsed file (or wherever this value tree came from). If
- * {@code get("key")} returns a {@link ConfigValue} with type
- * {@code ConfigValueType#NULL} then the key was set to null explicitly in the
- * config file.
- *
- * <p>
- * <em>Do not implement interface {@code ConfigObject}</em>; it should only be
- * implemented by the config library. Arbitrary implementations will not work
- * because the library internals assume a specific concrete implementation.
- * Also, this interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigObject extends ConfigValue, Map<String, ConfigValue> {
-
-    /**
-     * Converts this object to a {@link Config} instance, enabling you to use
-     * path expressions to find values in the object. This is a constant-time
-     * operation (it is not proportional to the size of the object).
-     *
-     * @return a {@link Config} with this object as its root
-     */
-    Config toConfig();
-
-    /**
-     * Recursively unwraps the object, returning a map from String to whatever
-     * plain Java values are unwrapped from the object's values.
-     *
-     * @return a {@link java.util.Map} containing plain Java objects
-     */
-    @Override
-    Map<String, Object> unwrapped();
-
-    @Override
-    ConfigObject withFallback(ConfigMergeable other);
-
-    /**
-     * Gets a {@link ConfigValue} at the given key, or returns null if there is
-     * no value. The returned {@link ConfigValue} may have
-     * {@link ConfigValueType#NULL} or any other type, and the passed-in key
-     * must be a key in this object (rather than a path expression).
-     *
-     * @param key key to look up
-     * @return the value at the key or null if none
-     */
-    @Override
-    ConfigValue get(Object key);
-
-    /**
-     * Clone the object with only the given key (and its children) retained; all
-     * sibling keys are removed.
-     *
-     * @param key key to keep
-     * @return a copy of the object minus all keys except the one specified
-     */
-    ConfigObject withOnlyKey(String key);
-
-    /**
-     * Clone the object with the given key removed.
-     *
-     * @param key key to remove
-     * @return a copy of the object minus the specified key
-     */
-    ConfigObject withoutKey(String key);
-
-    /**
-     * Returns a {@code ConfigObject} based on this one, but with the given key
-     * set to the given value. Does not modify this instance (since it's
-     * immutable). If the key already has a value, that value is replaced. To
-     * remove a value, use {@link ConfigObject#withoutKey(String)}.
-     *
-     * @param key   key to add
-     * @param value value at the new key
-     * @return the new instance with the new map entry
-     */
-    ConfigObject withValue(String key, ConfigValue value);
-
-    @Override
-    ConfigObject withOrigin(ConfigOrigin origin);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigOrigin.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigOrigin.java
deleted file mode 100644
index 1bbeb2f..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigOrigin.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import java.net.URL;
-import java.util.List;
-
-/**
- * Represents the origin (such as filename and line number) of a
- * {@link ConfigValue} for use in error messages. Obtain the origin of a value
- * with {@link ConfigValue#origin}. Exceptions may have an origin, see
- * {@link ConfigException#origin}, but be careful because
- * <code>ConfigException.origin()</code> may return null.
- *
- * <p>
- * It's best to use this interface only for debugging; its accuracy is
- * "best effort" rather than guaranteed, and a potentially-noticeable amount of
- * memory could probably be saved if origins were not kept around, so in the
- * future there might be some option to discard origins.
- *
- * <p>
- * <em>Do not implement this interface</em>; it should only be implemented by
- * the config library. Arbitrary implementations will not work because the
- * library internals assume a specific concrete implementation. Also, this
- * interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigOrigin {
-    /**
-     * Returns a string describing the origin of a value or exception. This will
-     * never return null.
-     *
-     * @return string describing the origin
-     */
-    public String description();
-
-    /**
-     * Returns a filename describing the origin. This will return null if the
-     * origin was not a file.
-     *
-     * @return filename of the origin or null
-     */
-    public String filename();
-
-    /**
-     * Returns a URL describing the origin. This will return null if the origin
-     * has no meaningful URL.
-     *
-     * @return url of the origin or null
-     */
-    public URL url();
-
-    /**
-     * Returns a classpath resource name describing the origin. This will return
-     * null if the origin was not a classpath resource.
-     *
-     * @return resource name of the origin or null
-     */
-    public String resource();
-
-    /**
-     * Returns a line number where the value or exception originated. This will
-     * return -1 if there's no meaningful line number.
-     *
-     * @return line number or -1 if none is available
-     */
-    public int lineNumber();
-
-    /**
-     * Returns any comments that appeared to "go with" this place in the file.
-     * Often an empty list, but never null. The details of this are subject to
-     * change, but at the moment comments that are immediately before an array
-     * element or object field, with no blank line after the comment, "go with"
-     * that element or field.
-     *
-     * @return any comments that seemed to "go with" this origin, empty list if
-     * none
-     */
-    public List<String> comments();
-
-    /**
-     * Returns a {@code ConfigOrigin} based on this one, but with the given
-     * comments. Does not modify this instance or any {@code ConfigValue}s with
-     * this origin (since they are immutable).  To set the returned origin to a
-     * {@code ConfigValue}, use {@link ConfigValue#withOrigin}.
-     *
-     * <p>
-     * Note that when the given comments are equal to the comments on this object,
-     * a new instance may not be created and {@code this} is returned directly.
-     *
-     * @param comments the comments used on the returned origin
-     * @return the ConfigOrigin with the given comments
-     * @since 1.3.0
-     */
-    public ConfigOrigin withComments(List<String> comments);
-
-    /**
-     * Returns a {@code ConfigOrigin} based on this one, but with the given
-     * line number. This origin must be a FILE, URL or RESOURCE. Does not modify
-     * this instance or any {@code ConfigValue}s with this origin (since they are
-     * immutable).  To set the returned origin to a  {@code ConfigValue}, use
-     * {@link ConfigValue#withOrigin}.
-     *
-     * <p>
-     * Note that when the given lineNumber are equal to the lineNumber on this
-     * object, a new instance may not be created and {@code this} is returned
-     * directly.
-     *
-     * @param lineNumber the new line number
-     * @return the created ConfigOrigin
-     * @since 1.3.0
-     */
-    public ConfigOrigin withLineNumber(int lineNumber);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigOriginFactory.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigOriginFactory.java
deleted file mode 100644
index 7bdd5a3..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigOriginFactory.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import org.apache.seatunnel.config.impl.ConfigImpl;
-
-import java.net.URL;
-
-/**
- * This class contains some static factory methods for building a {@link
- * ConfigOrigin}. {@code ConfigOrigin}s are automatically created when you
- * call other API methods to get a {@code ConfigValue} or {@code Config}.
- * But you can also set the origin of an existing {@code ConfigValue}, using
- * {@link ConfigValue#withOrigin(ConfigOrigin)}.
- *
- * @since 1.3.0
- */
-public final class ConfigOriginFactory {
-    private ConfigOriginFactory() {
-    }
-
-    /**
-     * Returns the default origin for values when no other information is
-     * provided. This is the origin used in {@link ConfigValueFactory
-     * #fromAnyRef(Object)}.
-     *
-     * @return the default origin
-     * @since 1.3.0
-     */
-    public static ConfigOrigin newSimple() {
-        return newSimple(null);
-    }
-
-    /**
-     * Returns an origin with the given description.
-     *
-     * @param description brief description of what the origin is
-     * @return a new origin
-     * @since 1.3.0
-     */
-    public static ConfigOrigin newSimple(String description) {
-        return ConfigImpl.newSimpleOrigin(description);
-    }
-
-    /**
-     * Creates a file origin with the given filename.
-     *
-     * @param filename the filename of this origin
-     * @return a new origin
-     * @since 1.3.0
-     */
-    public static ConfigOrigin newFile(String filename) {
-        return ConfigImpl.newFileOrigin(filename);
-    }
-
-    /**
-     * Creates a url origin with the given URL object.
-     *
-     * @param url the url of this origin
-     * @return a new origin
-     * @since 1.3.0
-     */
-    public static ConfigOrigin newURL(URL url) {
-        return ConfigImpl.newURLOrigin(url);
-    }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigParseable.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigParseable.java
deleted file mode 100644
index 5296d47..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigParseable.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-/**
- * An opaque handle to something that can be parsed, obtained from
- * {@link ConfigIncludeContext}.
- *
- * <p>
- * <em>Do not implement this interface</em>; it should only be implemented by
- * the config library. Arbitrary implementations will not work because the
- * library internals assume a specific concrete implementation. Also, this
- * interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigParseable {
-    /**
-     * Parse whatever it is. The options should come from
-     * {@link ConfigParseable#options options()} but you could tweak them if you
-     * like.
-     *
-     * @param options parse options, should be based on the ones from
-     *                {@link ConfigParseable#options options()}
-     * @return the parsed object
-     */
-    ConfigObject parse(ConfigParseOptions options);
-
-    /**
-     * Returns a {@link ConfigOrigin} describing the origin of the parseable
-     * item.
-     *
-     * @return the origin of the parseable item
-     */
-    ConfigOrigin origin();
-
-    /**
-     * Get the initial options, which can be modified then passed to parse().
-     * These options will have the right description, includer, and other
-     * parameters already set up.
-     *
-     * @return the initial options
-     */
-    ConfigParseOptions options();
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigRenderOptions.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigRenderOptions.java
deleted file mode 100644
index c3e311f..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigRenderOptions.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-/**
- * <p>
- * A set of options related to rendering a {@link ConfigValue}. Passed to
- * {@link ConfigValue#render(ConfigRenderOptions)}.
- *
- * <p>
- * Here is an example of creating a {@code ConfigRenderOptions}:
- *
- * <pre>
- *     ConfigRenderOptions options =
- *         ConfigRenderOptions.defaults().setComments(false)
- * </pre>
- */
-public final class ConfigRenderOptions {
-    private final boolean originComments;
-    private final boolean comments;
-    private final boolean formatted;
-    private final boolean json;
-
-    private ConfigRenderOptions(boolean originComments, boolean comments, boolean formatted,
-                                boolean json) {
-        this.originComments = originComments;
-        this.comments = comments;
-        this.formatted = formatted;
-        this.json = json;
-    }
-
-    /**
-     * Returns the default render options which are verbose (commented and
-     * formatted). See {@link ConfigRenderOptions#concise} for stripped-down
-     * options. This rendering will not be valid JSON since it has comments.
-     *
-     * @return the default render options
-     */
-    public static ConfigRenderOptions defaults() {
-        return new ConfigRenderOptions(true, true, true, true);
-    }
-
-    /**
-     * Returns concise render options (no whitespace or comments). For a
-     * resolved {@link Config}, the concise rendering will be valid JSON.
-     *
-     * @return the concise render options
-     */
-    public static ConfigRenderOptions concise() {
-        return new ConfigRenderOptions(false, false, false, true);
-    }
-
-    /**
-     * Returns options with comments toggled. This controls human-written
-     * comments but not the autogenerated "origin of this setting" comments,
-     * which are controlled by {@link ConfigRenderOptions#setOriginComments}.
-     *
-     * @param value true to include comments in the render
-     * @return options with requested setting for comments
-     */
-    public ConfigRenderOptions setComments(boolean value) {
-        if (value == comments) {
-            return this;
-        }
-        return new ConfigRenderOptions(originComments, value, formatted, json);
-    }
-
-    /**
-     * Returns whether the options enable comments. This method is mostly used
-     * by the config lib internally, not by applications.
-     *
-     * @return true if comments should be rendered
-     */
-    public boolean getComments() {
-        return comments;
-    }
-
-    /**
-     * Returns options with origin comments toggled. If this is enabled, the
-     * library generates comments for each setting based on the
-     * {@link ConfigValue#origin} of that setting's value. For example these
-     * comments might tell you which file a setting comes from.
-     *
-     * <p>
-     * {@code setOriginComments()} controls only these autogenerated
-     * "origin of this setting" comments, to toggle regular comments use
-     * {@link ConfigRenderOptions#setComments}.
-     *
-     * @param value true to include autogenerated setting-origin comments in the
-     *              render
-     * @return options with origin comments toggled
-     */
-    public ConfigRenderOptions setOriginComments(boolean value) {
-        if (value == originComments) {
-            return this;
-        }
-        return new ConfigRenderOptions(value, comments, formatted, json);
-    }
-
-    /**
-     * Returns whether the options enable automated origin comments. This method
-     * is mostly used by the config lib internally, not by applications.
-     *
-     * @return true if origin comments should be rendered
-     */
-    public boolean getOriginComments() {
-        return originComments;
-    }
-
-    /**
-     * Returns options with formatting toggled. Formatting means indentation and
-     * whitespace, enabling formatting makes things prettier but larger.
-     *
-     * @param value true to enable formatting
-     * @return options with requested setting for formatting
-     */
-    public ConfigRenderOptions setFormatted(boolean value) {
-        if (value == formatted) {
-            return this;
-        }
-        return new ConfigRenderOptions(originComments, comments, value, json);
-    }
-
-    /**
-     * Returns whether the options enable formatting. This method is mostly used
-     * by the config lib internally, not by applications.
-     *
-     * @return true if the options enable formatting
-     */
-    public boolean getFormatted() {
-        return formatted;
-    }
-
-    /**
-     * Returns options with JSON toggled. JSON means that HOCON extensions
-     * (omitting commas, quotes for example) won't be used. However, whether to
-     * use comments is controlled by the separate {@link #setComments(boolean)}
-     * and {@link #setOriginComments(boolean)} options. So if you enable
-     * comments you will get invalid JSON despite setting this to true.
-     *
-     * @param value true to include non-JSON extensions in the render
-     * @return options with requested setting for JSON
-     */
-    public ConfigRenderOptions setJson(boolean value) {
-        if (value == json) {
-            return this;
-        }
-        return new ConfigRenderOptions(originComments, comments, formatted, value);
-    }
-
-    /**
-     * Returns whether the options enable JSON. This method is mostly used by
-     * the config lib internally, not by applications.
-     *
-     * @return true if only JSON should be rendered
-     */
-    public boolean getJson() {
-        return json;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("ConfigRenderOptions(");
-        if (originComments) {
-            sb.append("originComments,");
-        }
-        if (comments) {
-            sb.append("comments,");
-        }
-        if (formatted) {
-            sb.append("formatted,");
-        }
-        if (json) {
-            sb.append("json,");
-        }
-        if (sb.charAt(sb.length() - 1) == ',') {
-            sb.setLength(sb.length() - 1);
-        }
-        sb.append(")");
-        return sb.toString();
-    }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigResolveOptions.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigResolveOptions.java
deleted file mode 100644
index eaa0022..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigResolveOptions.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-/**
- * A set of options related to resolving substitutions. Substitutions use the
- * <code>${foo.bar}</code> syntax and are documented in the <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">HOCON</a>
- * spec.
- * <p>
- * Typically this class would be used with the method
- * {@link Config#resolve(ConfigResolveOptions)}.
- * <p>
- * This object is immutable, so the "setters" return a new object.
- * <p>
- * Here is an example of creating a custom {@code ConfigResolveOptions}:
- *
- * <pre>
- *     ConfigResolveOptions options = ConfigResolveOptions.defaults()
- *         .setUseSystemEnvironment(false)
- * </pre>
- * <p>
- * In addition to {@link ConfigResolveOptions#defaults}, there's a prebuilt
- * {@link ConfigResolveOptions#noSystem} which avoids looking at any system
- * environment variables or other external system information. (Right now,
- * environment variables are the only example.)
- */
-public final class ConfigResolveOptions {
-    private final boolean useSystemEnvironment;
-    private final boolean allowUnresolved;
-    private final ConfigResolver resolver;
-
-    private ConfigResolveOptions(boolean useSystemEnvironment, boolean allowUnresolved,
-                                 ConfigResolver resolver) {
-        this.useSystemEnvironment = useSystemEnvironment;
-        this.allowUnresolved = allowUnresolved;
-        this.resolver = resolver;
-    }
-
-    /**
-     * Returns the default resolve options. By default the system environment
-     * will be used and unresolved substitutions are not allowed.
-     *
-     * @return the default resolve options
-     */
-    public static ConfigResolveOptions defaults() {
-        return new ConfigResolveOptions(true, false, NULL_RESOLVER);
-    }
-
-    /**
-     * Returns resolve options that disable any reference to "system" data
-     * (currently, this means environment variables).
-     *
-     * @return the resolve options with env variables disabled
-     */
-    public static ConfigResolveOptions noSystem() {
-        return defaults().setUseSystemEnvironment(false);
-    }
-
-    /**
-     * Returns options with use of environment variables set to the given value.
-     *
-     * @param value true to resolve substitutions falling back to environment
-     *              variables.
-     * @return options with requested setting for use of environment variables
-     */
-    public ConfigResolveOptions setUseSystemEnvironment(boolean value) {
-        return new ConfigResolveOptions(value, allowUnresolved, resolver);
-    }
-
-    /**
-     * Returns whether the options enable use of system environment variables.
-     * This method is mostly used by the config lib internally, not by
-     * applications.
-     *
-     * @return true if environment variables should be used
-     */
-    public boolean getUseSystemEnvironment() {
-        return useSystemEnvironment;
-    }
-
-    /**
-     * Returns options with "allow unresolved" set to the given value. By
-     * default, unresolved substitutions are an error. If unresolved
-     * substitutions are allowed, then a future attempt to use the unresolved
-     * value may fail, but {@link Config#resolve(ConfigResolveOptions)} itself
-     * will not throw.
-     *
-     * @param value true to silently ignore unresolved substitutions.
-     * @return options with requested setting for whether to allow substitutions
-     * @since 1.2.0
-     */
-    public ConfigResolveOptions setAllowUnresolved(boolean value) {
-        return new ConfigResolveOptions(useSystemEnvironment, value, resolver);
-    }
-
-    /**
-     * Returns options where the given resolver used as a fallback if a
-     * reference cannot be otherwise resolved. This resolver will only be called
-     * after resolution has failed to substitute with a value from within the
-     * config itself and with any other resolvers that have been appended before
-     * this one. Multiple resolvers can be added using,
-     *
-     * <pre>
-     *     ConfigResolveOptions options = ConfigResolveOptions.defaults()
-     *         .appendResolver(primary)
-     *         .appendResolver(secondary)
-     *         .appendResolver(tertiary);
-     * </pre>
-     * <p>
-     * With this config unresolved references will first be resolved with the
-     * primary resolver, if that fails then the secondary, and finally if that
-     * also fails the tertiary.
-     * <p>
-     * If all fallbacks fail to return a substitution "allow unresolved"
-     * determines whether resolution fails or continues.
-     * `
-     *
-     * @param value the resolver to fall back to
-     * @return options that use the given resolver as a fallback
-     * @since 1.3.2
-     */
-    public ConfigResolveOptions appendResolver(ConfigResolver value) {
-        if (value == null) {
-            throw new ConfigException.BugOrBroken("null resolver passed to appendResolver");
-        } else if (value == this.resolver) {
-            return this;
-        }
-        return new ConfigResolveOptions(useSystemEnvironment, allowUnresolved,
-                this.resolver.withFallback(value));
-    }
-
-    /**
-     * Returns the resolver to use as a fallback if a substitution cannot be
-     * otherwise resolved. Never returns null. This method is mostly used by the
-     * config lib internally, not by applications.
-     *
-     * @return the non-null fallback resolver
-     * @since 1.3.2
-     */
-    public ConfigResolver getResolver() {
-        return this.resolver;
-    }
-
-    /**
-     * Returns whether the options allow unresolved substitutions. This method
-     * is mostly used by the config lib internally, not by applications.
-     *
-     * @return true if unresolved substitutions are allowed
-     * @since 1.2.0
-     */
-    public boolean getAllowUnresolved() {
-        return allowUnresolved;
-    }
-
-    /**
-     * Singleton resolver that never resolves paths.
-     */
-    private static final ConfigResolver NULL_RESOLVER = new ConfigResolver() {
-
-        @Override
-        public ConfigValue lookup(String path) {
-            return null;
-        }
-
-        @Override
-        public ConfigResolver withFallback(ConfigResolver fallback) {
-            return fallback;
-        }
-
-    };
-
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigResolver.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigResolver.java
deleted file mode 100644
index fe68f41..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigResolver.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-/**
- * Implement this interface and provide an instance to
- * {@link ConfigResolveOptions#appendResolver ConfigResolveOptions.appendResolver()}
- * to provide custom behavior when unresolved substitutions are encountered
- * during resolution.
- *
- * @since 1.3.2
- */
-public interface ConfigResolver {
-
-    /**
-     * Returns the value to substitute for the given unresolved path. To get the
-     * components of the path use {@link ConfigUtil#splitPath(String)}. If a
-     * non-null value is returned that value will be substituted, otherwise
-     * resolution will continue to consider the substitution as still
-     * unresolved.
-     *
-     * @param path the unresolved path
-     * @return the value to use as a substitution or null
-     */
-    public ConfigValue lookup(String path);
-
-    /**
-     * Returns a new resolver that falls back to the given resolver if this
-     * one doesn't provide a substitution itself.
-     * <p>
-     * It's important to handle the case where you already have the fallback
-     * with a "return this", i.e. this method should not create a new object if
-     * the fallback is the same one you already have. The same fallback may be
-     * added repeatedly.
-     *
-     * @param fallback the previous includer for chaining
-     * @return a new resolver
-     */
-    public ConfigResolver withFallback(ConfigResolver fallback);
-
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigSyntax.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigSyntax.java
deleted file mode 100644
index 6a5688e..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigSyntax.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-/**
- * The syntax of a character stream (<a href="http://json.org">JSON</a>, <a
- * href="https://github.com/lightbend/config/blob/master/HOCON.md">HOCON</a>
- * aka ".conf", or <a href=
- * "http://download.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.Reader%29"
- * >Java properties</a>).
- */
-public enum ConfigSyntax {
-    /**
-     * Pedantically strict <a href="http://json.org">JSON</a> format; no
-     * comments, no unexpected commas, no duplicate keys in the same object.
-     * Associated with the <code>.json</code> file extension and
-     * <code>application/json</code> Content-Type.
-     */
-    JSON,
-    /**
-     * The JSON-superset <a
-     * href="https://github.com/lightbend/config/blob/master/HOCON.md"
-     * >HOCON</a> format. Associated with the <code>.conf</code> file extension
-     * and <code>application/hocon</code> Content-Type.
-     */
-    CONF,
-    /**
-     * Standard <a href=
-     * "http://download.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.Reader%29"
-     * >Java properties</a> format. Associated with the <code>.properties</code>
-     * file extension and <code>text/x-java-properties</code> Content-Type.
-     */
-    PROPERTIES;
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigUtil.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigUtil.java
deleted file mode 100644
index dacdefe..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigUtil.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import org.apache.seatunnel.config.impl.ConfigImplUtil;
-
-import java.util.List;
-
-/**
- * Contains static utility methods.
- */
-public final class ConfigUtil {
-    private ConfigUtil() {
-
-    }
-
-    /**
-     * Quotes and escapes a string, as in the JSON specification.
-     *
-     * @param s a string
-     * @return the string quoted and escaped
-     */
-    public static String quoteString(String s) {
-        return ConfigImplUtil.renderJsonString(s);
-    }
-
-    /**
-     * Converts a list of keys to a path expression, by quoting the path
-     * elements as needed and then joining them separated by a period. A path
-     * expression is usable with a {@link Config}, while individual path
-     * elements are usable with a {@link ConfigObject}.
-     * <p>
-     * See the overview documentation for {@link Config} for more detail on path
-     * expressions vs. keys.
-     *
-     * @param elements the keys in the path
-     * @return a path expression
-     * @throws ConfigException if there are no elements
-     */
-    public static String joinPath(String... elements) {
-        return ConfigImplUtil.joinPath(elements);
-    }
-
-    /**
-     * Converts a list of strings to a path expression, by quoting the path
-     * elements as needed and then joining them separated by a period. A path
-     * expression is usable with a {@link Config}, while individual path
-     * elements are usable with a {@link ConfigObject}.
-     * <p>
-     * See the overview documentation for {@link Config} for more detail on path
-     * expressions vs. keys.
-     *
-     * @param elements the keys in the path
-     * @return a path expression
-     * @throws ConfigException if the list is empty
-     */
-    public static String joinPath(List<String> elements) {
-        return ConfigImplUtil.joinPath(elements);
-    }
-
-    /**
-     * Converts a path expression into a list of keys, by splitting on period
-     * and unquoting the individual path elements. A path expression is usable
-     * with a {@link Config}, while individual path elements are usable with a
-     * {@link ConfigObject}.
-     * <p>
-     * See the overview documentation for {@link Config} for more detail on path
-     * expressions vs. keys.
-     *
-     * @param path a path expression
-     * @return the individual keys in the path
-     * @throws ConfigException if the path expression is invalid
-     */
-    public static List<String> splitPath(String path) {
-        return ConfigImplUtil.splitPath(path);
-    }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValue.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValue.java
deleted file mode 100644
index b5c3152..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValue.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-/**
- * An immutable value, following the <a href="http://json.org">JSON</a> type
- * schema.
- *
- * <p>
- * Because this object is immutable, it is safe to use from multiple threads and
- * there's no need for "defensive copies."
- *
- * <p>
- * <em>Do not implement interface {@code ConfigValue}</em>; it should only be
- * implemented by the config library. Arbitrary implementations will not work
- * because the library internals assume a specific concrete implementation.
- * Also, this interface is likely to grow new methods over time, so third-party
- * implementations will break.
- */
-public interface ConfigValue extends ConfigMergeable {
-    /**
-     * The origin of the value (file, line number, etc.), for debugging and
-     * error messages.
-     *
-     * @return where the value came from
-     */
-    ConfigOrigin origin();
-
-    /**
-     * The {@link ConfigValueType} of the value; matches the JSON type schema.
-     *
-     * @return value's type
-     */
-    ConfigValueType valueType();
-
-    /**
-     * Returns the value as a plain Java boxed value, that is, a {@code String},
-     * {@code Number}, {@code Boolean}, {@code Map<String,Object>},
-     * {@code List<Object>}, or {@code null}, matching the {@link #valueType()}
-     * of this {@code ConfigValue}. If the value is a {@link ConfigObject} or
-     * {@link ConfigList}, it is recursively unwrapped.
-     *
-     * @return a plain Java value corresponding to this ConfigValue
-     */
-    Object unwrapped();
-
-    /**
-     * Renders the config value as a HOCON string. This method is primarily
-     * intended for debugging, so it tries to add helpful comments and
-     * whitespace.
-     *
-     * <p>
-     * If the config value has not been resolved (see {@link Config#resolve}),
-     * it's possible that it can't be rendered as valid HOCON. In that case the
-     * rendering should still be useful for debugging but you might not be able
-     * to parse it. If the value has been resolved, it will always be parseable.
-     *
-     * <p>
-     * This method is equivalent to
-     * {@code render(ConfigRenderOptions.defaults())}.
-     *
-     * @return the rendered value
-     */
-    String render();
-
-    /**
-     * Renders the config value to a string, using the provided options.
-     *
-     * <p>
-     * If the config value has not been resolved (see {@link Config#resolve}),
-     * it's possible that it can't be rendered as valid HOCON. In that case the
-     * rendering should still be useful for debugging but you might not be able
-     * to parse it. If the value has been resolved, it will always be parseable.
-     *
-     * <p>
-     * If the config value has been resolved and the options disable all
-     * HOCON-specific features (such as comments), the rendering will be valid
-     * JSON. If you enable HOCON-only features such as comments, the rendering
-     * will not be valid JSON.
-     *
-     * @param options the rendering options
-     * @return the rendered value
-     */
-    String render(ConfigRenderOptions options);
-
-    @Override
-    ConfigValue withFallback(ConfigMergeable other);
-
-    /**
-     * Places the value inside a {@link Config} at the given path. See also
-     * {@link ConfigValue#atKey(String)}.
-     *
-     * @param path path to store this value at.
-     * @return a {@code Config} instance containing this value at the given
-     * path.
-     */
-    Config atPath(String path);
-
-    /**
-     * Places the value inside a {@link Config} at the given key. See also
-     * {@link ConfigValue#atPath(String)}.
-     *
-     * @param key key to store this value at.
-     * @return a {@code Config} instance containing this value at the given key.
-     */
-    Config atKey(String key);
-
-    /**
-     * Returns a {@code ConfigValue} based on this one, but with the given
-     * origin. This is useful when you are parsing a new format of file or setting
-     * comments for a single ConfigValue.
-     *
-     * @param origin the origin set on the returned value
-     * @return the new ConfigValue with the given origin
-     * @since 1.3.0
-     */
-    ConfigValue withOrigin(ConfigOrigin origin);
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValueFactory.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValueFactory.java
deleted file mode 100644
index cd33591..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValueFactory.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import org.apache.seatunnel.config.impl.ConfigImpl;
-
-import java.util.Map;
-
-/**
- * This class holds some static factory methods for building {@link ConfigValue}
- * instances. See also {@link ConfigFactory} which has methods for parsing files
- * and certain in-memory data structures.
- */
-public final class ConfigValueFactory {
-    private ConfigValueFactory() {
-    }
-
-    /**
-     * Creates a {@link ConfigValue} from a plain Java boxed value, which may be
-     * a <code>Boolean</code>, <code>Number</code>, <code>String</code>,
-     * <code>Map</code>, <code>Iterable</code>, or <code>null</code>. A
-     * <code>Map</code> must be a <code>Map</code> from String to more values
-     * that can be supplied to <code>fromAnyRef()</code>. An
-     * <code>Iterable</code> must iterate over more values that can be supplied
-     * to <code>fromAnyRef()</code>. A <code>Map</code> will become a
-     * {@link ConfigObject} and an <code>Iterable</code> will become a
-     * {@link ConfigList}. If the <code>Iterable</code> is not an ordered
-     * collection, results could be strange, since <code>ConfigList</code> is
-     * ordered.
-     *
-     * <p>
-     * In a <code>Map</code> passed to <code>fromAnyRef()</code>, the map's keys
-     * are plain keys, not path expressions. So if your <code>Map</code> has a
-     * key "foo.bar" then you will get one object with a key called "foo.bar",
-     * rather than an object with a key "foo" containing another object with a
-     * key "bar".
-     *
-     * <p>
-     * The originDescription will be used to set the origin() field on the
-     * ConfigValue. It should normally be the name of the file the values came
-     * from, or something short describing the value such as "default settings".
-     * The originDescription is prefixed to error messages so users can tell
-     * where problematic values are coming from.
-     *
-     * <p>
-     * Supplying the result of ConfigValue.unwrapped() to this function is
-     * guaranteed to work and should give you back a ConfigValue that matches
-     * the one you unwrapped. The re-wrapped ConfigValue will lose some
-     * information that was present in the original such as its origin, but it
-     * will have matching values.
-     *
-     * <p>
-     * If you pass in a <code>ConfigValue</code> to this
-     * function, it will be returned unmodified. (The
-     * <code>originDescription</code> will be ignored in this
-     * case.)
-     *
-     * <p>
-     * This function throws if you supply a value that cannot be converted to a
-     * ConfigValue, but supplying such a value is a bug in your program, so you
-     * should never handle the exception. Just fix your program (or report a bug
-     * against this library).
-     *
-     * @param object            object to convert to ConfigValue
-     * @param originDescription name of origin file or brief description of what the value is
-     * @return a new value
-     */
-    public static ConfigValue fromAnyRef(Object object, String originDescription) {
-        return ConfigImpl.fromAnyRef(object, originDescription);
-    }
-
-    /**
-     * See the {@link #fromAnyRef(Object, String)} documentation for details.
-     * This is a typesafe wrapper that only works on {@link java.util.Map} and
-     * returns {@link ConfigObject} rather than {@link ConfigValue}.
-     *
-     * <p>
-     * If your <code>Map</code> has a key "foo.bar" then you will get one object
-     * with a key called "foo.bar", rather than an object with a key "foo"
-     * containing another object with a key "bar". The keys in the map are keys;
-     * not path expressions. That is, the <code>Map</code> corresponds exactly
-     * to a single {@code ConfigObject}. The keys will not be parsed or
-     * modified, and the values are wrapped in ConfigValue. To get nested
-     * {@code ConfigObject}, some of the values in the map would have to be more
-     * maps.
-     *
-     * <p>
-     * See also {@link ConfigFactory#parseMap(Map, String)} which interprets the
-     * keys in the map as path expressions.
-     *
-     * @param values            map from keys to plain Java values
-     * @param originDescription description to use in {@link ConfigOrigin} of created values
-     * @return a new {@link ConfigObject} value
-     */
-    public static ConfigObject fromMap(Map<String, ? extends Object> values,
-                                       String originDescription) {
-        return (ConfigObject) fromAnyRef(values, originDescription);
-    }
-
-    /**
-     * See the {@link #fromAnyRef(Object, String)} documentation for details.
-     * This is a typesafe wrapper that only works on {@link java.lang.Iterable}
-     * and returns {@link ConfigList} rather than {@link ConfigValue}.
-     *
-     * @param values            list of plain Java values
-     * @param originDescription description to use in {@link ConfigOrigin} of created values
-     * @return a new {@link ConfigList} value
-     */
-    public static ConfigList fromIterable(Iterable<? extends Object> values,
-                                          String originDescription) {
-        return (ConfigList) fromAnyRef(values, originDescription);
-    }
-
-    /**
-     * See the other overload {@link #fromAnyRef(Object, String)} for details,
-     * this one just uses a default origin description.
-     *
-     * @param object a plain Java value
-     * @return a new {@link ConfigValue}
-     */
-    public static ConfigValue fromAnyRef(Object object) {
-        return fromAnyRef(object, null);
-    }
-
-    /**
-     * See the other overload {@link #fromMap(Map, String)} for details, this one
-     * just uses a default origin description.
-     *
-     * <p>
-     * See also {@link ConfigFactory#parseMap(Map)} which interprets the keys in
-     * the map as path expressions.
-     *
-     * @param values map from keys to plain Java values
-     * @return a new {@link ConfigObject}
-     */
-    public static ConfigObject fromMap(Map<String, ? extends Object> values) {
-        return fromMap(values, null);
-    }
-
-    /**
-     * See the other overload of {@link #fromIterable(Iterable, String)} for
-     * details, this one just uses a default origin description.
-     *
-     * @param values list of plain Java values
-     * @return a new {@link ConfigList}
-     */
-    public static ConfigList fromIterable(Iterable<? extends Object> values) {
-        return fromIterable(values, null);
-    }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValueType.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValueType.java
deleted file mode 100644
index b32d771..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/ConfigValueType.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-/**
- * The type of a configuration value (following the <a
- * href="http://json.org">JSON</a> type schema).
- */
-public enum ConfigValueType {
-    OBJECT, LIST, NUMBER, BOOLEAN, NULL, STRING
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/DefaultConfigLoadingStrategy.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/DefaultConfigLoadingStrategy.java
deleted file mode 100644
index 583d43e..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/DefaultConfigLoadingStrategy.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * Default config loading strategy. Able to load resource, file or URL.
- * Behavior may be altered by defining one of VM properties
- * {@code config.resource}, {@code config.file} or {@code config.url}
- */
-public class DefaultConfigLoadingStrategy implements ConfigLoadingStrategy {
-    @Override
-    public Config parseApplicationConfig(ConfigParseOptions parseOptions) {
-        ClassLoader loader = parseOptions.getClassLoader();
-        if (loader == null) {
-            throw new ConfigException.BugOrBroken(
-                    "ClassLoader should have been set here; bug in ConfigFactory. " + "(You can probably work around this bug by passing in a class loader or calling currentThread().setContextClassLoader() though.)");
-        }
-
-        int specified = 0;
-
-        // override application.conf with config.file, config.resource,
-        // config.url if requested.
-        String resource = System.getProperty("config.resource");
-        if (resource != null) {
-            specified += 1;
-        }
-        String file = System.getProperty("config.file");
-        if (file != null) {
-            specified += 1;
-        }
-        String url = System.getProperty("config.url");
-        if (url != null) {
-            specified += 1;
-        }
-
-        if (specified == 0) {
-            return ConfigFactory.parseResourcesAnySyntax("application", parseOptions);
-        } else if (specified > 1) {
-            throw new ConfigException.Generic("You set more than one of config.file='"
-                    + file + "', config.url='"
-                    + url + "', config.resource='"
-                    + resource + "'; don't know which one to use!");
-        }
-        // the override file/url/resource MUST be present or it's an error
-        ConfigParseOptions overrideOptions = parseOptions.setAllowMissing(false);
-        if (resource != null) {
-            if (resource.startsWith("/")) {
-                resource = resource.substring(1);
-            }
-            // this deliberately does not parseResourcesAnySyntax; if
-            // people want that they can use an include statement.
-            return ConfigFactory.parseResources(loader, resource, overrideOptions);
-        } else if (file != null) {
-            return ConfigFactory.parseFile(new File(file), overrideOptions);
-        }
-        try {
-            return ConfigFactory.parseURL(new URL(url), overrideOptions);
-        } catch (MalformedURLException e) {
-            throw new ConfigException.Generic("Bad URL in config.url system property: '"
-                    + url + "': " + e.getMessage(), e);
-        }
-    }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/Optional.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/Optional.java
deleted file mode 100644
index ab16a1a..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/Optional.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.seatunnel.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Allows an config property to be {@code null}.
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Optional {
-
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigNode.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigNode.java
deleted file mode 100644
index d20026b..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigNode.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.parser.ConfigNode;
-
-import java.util.Collection;
-
-abstract class AbstractConfigNode implements ConfigNode {
-    abstract Collection<Token> tokens();
-
-    @Override
-    public final String render() {
-        StringBuilder origText = new StringBuilder();
-        Iterable<Token> tokens = tokens();
-        for (Token t : tokens) {
-            origText.append(t.tokenText());
-        }
-        return origText.toString();
-    }
-
-    @Override
-    public final boolean equals(Object other) {
-        return other instanceof AbstractConfigNode && render().equals(((AbstractConfigNode) other).render());
-    }
-
-    @Override
-    public final int hashCode() {
-        return render().hashCode();
-    }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigNodeValue.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigNodeValue.java
deleted file mode 100644
index 898a03b..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigNodeValue.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.seatunnel.config.impl;
-
-// This is required if we want
-// to be referencing the AbstractConfigNode class in implementation rather than the
-// ConfigNode interface, as we can't cast an AbstractConfigNode to an interface
-abstract class AbstractConfigNodeValue extends AbstractConfigNode {
-
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigObject.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigObject.java
deleted file mode 100644
index ec95a65..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigObject.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * 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.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.ConfigException.BugOrBroken;
-import org.apache.seatunnel.config.ConfigException.NotResolved;
-import org.apache.seatunnel.config.ConfigMergeable;
-import org.apache.seatunnel.config.ConfigObject;
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigRenderOptions;
-import org.apache.seatunnel.config.ConfigValue;
-import org.apache.seatunnel.config.ConfigValueType;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-abstract class AbstractConfigObject extends AbstractConfigValue implements ConfigObject, Container {
-    private final SimpleConfig config;
-
-    protected AbstractConfigObject(ConfigOrigin origin) {
-        super(origin);
-        this.config = new SimpleConfig(this);
-    }
-
-    @Override
-    public SimpleConfig toConfig() {
-        return config;
-    }
-
-    @Override
-    public AbstractConfigObject toFallbackValue() {
-        return this;
-    }
-
-    @Override
-    public abstract AbstractConfigObject withOnlyKey(String key);
-
-    @Override
-    public abstract AbstractConfigObject withoutKey(String key);
-
-    @Override
-    public abstract AbstractConfigObject withValue(String key, ConfigValue value);
-
-    protected abstract AbstractConfigObject withOnlyPathOrNull(Path path);
-
-    abstract AbstractConfigObject withOnlyPath(Path path);
-
-    abstract AbstractConfigObject withoutPath(Path path);
-
-    abstract AbstractConfigObject withValue(Path path, ConfigValue value);
-
-    /**
-     * This looks up the key with no transformation or type conversion of any
-     * kind, and returns null if the key is not present. The object must be
-     * resolved along the nodes needed to get the key or
-     * ConfigException.NotResolved will be thrown.
-     *
-     * @param key key
-     * @return the unmodified raw value or null
-     */
-    protected final AbstractConfigValue peekAssumingResolved(String key, Path originalPath) {
-        try {
-            return attemptPeekWithPartialResolve(key);
-        } catch (NotResolved e) {
-            throw ConfigImpl.improveNotResolved(originalPath, e);
-        }
-    }
-
-    /**
-     * Look up the key on an only-partially-resolved object, with no
-     * transformation or type conversion of any kind; if 'this' is not resolved
-     * then try to look up the key anyway if possible.
-     *
-     * @param key key to look up
-     * @return the value of the key, or null if known not to exist
-     * @throws NotResolved if can't figure out key's value (or existence) without more
-     *                                     resolving
-     */
-    abstract AbstractConfigValue attemptPeekWithPartialResolve(String key);
-
-    /**
-     * Looks up the path with no transformation or type conversion. Returns null
-     * if the path is not found; throws ConfigException.NotResolved if we need
-     * to go through an unresolved node to look up the path.
-     */
-    protected AbstractConfigValue peekPath(Path path) {
-        return peekPath(this, path);
-    }
-
-    private static AbstractConfigValue peekPath(AbstractConfigObject self, Path path) {
-        try {
-            // we'll fail if anything along the path can't
-            // be looked at without resolving.
-            Path next = path.remainder();
-            AbstractConfigValue v = self.attemptPeekWithPartialResolve(path.first());
-
-            if (next == null) {
-                return v;
-            }
-            if (v instanceof AbstractConfigObject) {
-                return peekPath((AbstractConfigObject) v, next);
-            }
-            return null;
-        } catch (NotResolved e) {
-            throw ConfigImpl.improveNotResolved(path, e);
-        }
-    }
-
-    @Override
-    public ConfigValueType valueType() {
-        return ConfigValueType.OBJECT;
-    }
-
-    protected abstract AbstractConfigObject newCopy(ResolveStatus status, ConfigOrigin origin);
-
-    @Override
-    protected AbstractConfigObject newCopy(ConfigOrigin origin) {
-        return newCopy(resolveStatus(), origin);
-    }
-
-    @Override
-    protected AbstractConfigObject constructDelayedMerge(ConfigOrigin origin,
-                                                         List<AbstractConfigValue> stack) {
-        return new ConfigDelayedMergeObject(origin, stack);
-    }
-
-    @Override
-    protected abstract AbstractConfigObject mergedWithObject(AbstractConfigObject fallback);
-
-    @Override
-    public AbstractConfigObject withFallback(ConfigMergeable mergeable) {
-        return (AbstractConfigObject) super.withFallback(mergeable);
-    }
-
-    static ConfigOrigin mergeOrigins(
-            Collection<? extends AbstractConfigValue> stack) {
-        if (stack.isEmpty()) {
-            throw new BugOrBroken(
-                    "can't merge origins on empty list");
-        }
-        List<ConfigOrigin> origins = new ArrayList<ConfigOrigin>();
-        ConfigOrigin firstOrigin = null;
-        int numMerged = 0;
-        for (AbstractConfigValue v : stack) {
-            if (firstOrigin == null) {
-                firstOrigin = v.origin();
-            }
-
-            if (v instanceof AbstractConfigObject
-                    && ((AbstractConfigObject) v).resolveStatus() == ResolveStatus.RESOLVED
-                    && ((ConfigObject) v).isEmpty()) {
-                // don't include empty files or the .empty()
-                // config in the description, since they are
-                // likely to be "implementation details"
-            } else {
-                origins.add(v.origin());
-                numMerged += 1;
-            }
-        }
-
-        if (numMerged == 0) {
-            // the configs were all empty, so just use the first one
-            origins.add(firstOrigin);
-        }
-
-        return SimpleConfigOrigin.mergeOrigins(origins);
-    }
-
-    static ConfigOrigin mergeOrigins(AbstractConfigObject... stack) {
-        return mergeOrigins(Arrays.asList(stack));
-    }
-
-    @Override
-    abstract ResolveResult<? extends AbstractConfigObject> resolveSubstitutions(ResolveContext context,
-                                                                                ResolveSource source)
-            throws NotPossibleToResolve;
-
-    @Override
-    abstract AbstractConfigObject relativized(final Path prefix);
-
-    @Override
-    public abstract AbstractConfigValue get(Object key);
-
-    @Override
-    protected abstract void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options);
-
-    private static UnsupportedOperationException weAreImmutable(String method) {
-        return new UnsupportedOperationException("ConfigObject is immutable, you can't call Map." + method);
-    }
-
-    @Override
-    public void clear() {
-        throw weAreImmutable("clear");
-    }
-
-    @Override
-    public ConfigValue put(String arg0, ConfigValue arg1) {
-        throw weAreImmutable("put");
-    }
-
-    @Override
-    public void putAll(Map<? extends String, ? extends ConfigValue> arg0) {
-        throw weAreImmutable("putAll");
-    }
-
-    @Override
-    public ConfigValue remove(Object arg0) {
-        throw weAreImmutable("remove");
-    }
-
-    @Override
-    public AbstractConfigObject withOrigin(ConfigOrigin origin) {
-        return (AbstractConfigObject) super.withOrigin(origin);
-    }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigValue.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigValue.java
deleted file mode 100644
index 866bfa7..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/AbstractConfigValue.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * 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.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.ConfigException.BugOrBroken;
-import org.apache.seatunnel.config.ConfigMergeable;
-import org.apache.seatunnel.config.ConfigObject;
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigRenderOptions;
-import org.apache.seatunnel.config.ConfigValue;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Trying very hard to avoid a parent reference in config values; when you have
- * a tree like this, the availability of parent() tends to result in a lot of
- * improperly-factored and non-modular code. Please don't add parent().
- */
-abstract class AbstractConfigValue implements ConfigValue, MergeableValue {
-
-    private final SimpleConfigOrigin origin;
-
-    AbstractConfigValue(ConfigOrigin origin) {
-        this.origin = (SimpleConfigOrigin) origin;
-    }
-
-    @Override
-    public SimpleConfigOrigin origin() {
-        return this.origin;
-    }
-
-    /**
-     * This exception means that a value is inherently not resolveable, at the
-     * moment the only known cause is a cycle of substitutions. This is a
-     * checked exception since it's internal to the library and we want to be
-     * sure we handle it before passing it out to public API. This is only
-     * supposed to be thrown by the target of a cyclic reference and it's
-     * supposed to be caught by the ConfigReference looking up that reference,
-     * so it should be impossible for an outermost resolve() to throw this.
-     * <p>
-     * Contrast with ConfigException.NotResolved which just means nobody called
-     * resolve().
-     */
-    static class NotPossibleToResolve extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        private final String traceString;
-
-        NotPossibleToResolve(ResolveContext context) {
-            super("was not possible to resolve");
-            this.traceString = context.traceString();
-        }
-
-        String traceString() {
-            return traceString;
-        }
-    }
-
-    /**
-     * Called only by ResolveContext.resolve().
-     *
-     * @param context state of the current resolve
-     * @param source  where to look up values
-     * @return a new value if there were changes, or this if no changes
-     */
-    ResolveResult<? extends AbstractConfigValue> resolveSubstitutions(ResolveContext context, ResolveSource source)
-            throws NotPossibleToResolve {
-        return ResolveResult.make(context, this);
-    }
-
-    ResolveStatus resolveStatus() {
-        return ResolveStatus.RESOLVED;
-    }
-
-    protected static List<AbstractConfigValue> replaceChildInList(List<AbstractConfigValue> list,
-                                                                  AbstractConfigValue child, AbstractConfigValue replacement) {
-        int i = 0;
-        while (i < list.size() && list.get(i) != child) {
-            ++i;
-        }
-        if (i == list.size()) {
-            throw new BugOrBroken("tried to replace " + child + " which is not in " + list);
-        }
-        List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>(list);
-        if (replacement != null) {
-            newStack.set(i, replacement);
-        } else {
-            newStack.remove(i);
-        }
-
-        if (newStack.isEmpty()) {
-            return null;
-        }
-        return newStack;
-    }
-
-    protected static boolean hasDescendantInList(List<AbstractConfigValue> list, AbstractConfigValue descendant) {
-        for (AbstractConfigValue v : list) {
-            if (v == descendant) {
-                return true;
-            }
-        }
-        // now the expensive traversal
-        for (AbstractConfigValue v : list) {
-            if (v instanceof Container && ((Container) v).hasDescendant(descendant)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * This is used when including one file in another; the included file is
-     * relativized to the path it's included into in the parent file. The point
-     * is that if you include a file at foo.bar in the parent, and the included
-     * file as a substitution ${a.b.c}, the included substitution now needs to
-     * be ${foo.bar.a.b.c} because we resolve substitutions globally only after
-     * parsing everything.
-     *
-     * @param prefix prefix
-     * @return value relativized to the given path or the same value if nothing
-     * to do
-     */
-    AbstractConfigValue relativized(Path prefix) {
-        return this;
-    }
-
-    protected interface Modifier {
-        // keyOrNull is null for non-objects
-        AbstractConfigValue modifyChildMayThrow(String keyOrNull, AbstractConfigValue v)
-                throws Exception;
-    }
-
-    protected abstract class NoExceptionsModifier implements Modifier {
-        @Override
-        public final AbstractConfigValue modifyChildMayThrow(String keyOrNull, AbstractConfigValue v)
-                throws Exception {
-            try {
-                return modifyChild(keyOrNull, v);
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new BugOrBroken("Unexpected exception", e);
-            }
-        }
-
-        abstract AbstractConfigValue modifyChild(String keyOrNull, AbstractConfigValue v);
-    }
-
-    @Override
-    public AbstractConfigValue toFallbackValue() {
-        return this;
-    }
-
-    protected abstract AbstractConfigValue newCopy(ConfigOrigin origin);
-
-    // this is virtualized rather than a field because only some subclasses
-    // really need to store the boolean, and they may be able to pack it
-    // with another boolean to save space.
-    protected boolean ignoresFallbacks() {
-        // if we are not resolved, then somewhere in this value there's
-        // a substitution that may need to look at the fallbacks.
-        return resolveStatus() == ResolveStatus.RESOLVED;
-    }
-
-    protected AbstractConfigValue withFallbacksIgnored() {
-        if (ignoresFallbacks()) {
-            return this;
-        }
-        throw new BugOrBroken(
-                "value class doesn't implement forced fallback-ignoring " + this);
-    }
-
-    // the withFallback() implementation is supposed to avoid calling
-    // mergedWith* if we're ignoring fallbacks.
-    protected final void requireNotIgnoringFallbacks() {
-        if (ignoresFallbacks()) {
-            throw new BugOrBroken(
-                    "method should not have been called with ignoresFallbacks=true " + getClass().getSimpleName());
-        }
-    }
-
-    protected AbstractConfigValue constructDelayedMerge(ConfigOrigin origin,
-                                                        List<AbstractConfigValue> stack) {
-        return new ConfigDelayedMerge(origin, stack);
-    }
-
-    protected final AbstractConfigValue mergedWithTheUnmergeable(
-            Collection<AbstractConfigValue> stack, Unmergeable fallback) {
-        requireNotIgnoringFallbacks();
-
-        // if we turn out to be an object, and the fallback also does,
-        // then a merge may be required; delay until we resolve.
-        List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>();
-        newStack.addAll(stack);
-        newStack.addAll(fallback.unmergedValues());
-        return constructDelayedMerge(AbstractConfigObject.mergeOrigins(newStack), newStack);
-    }
-
-    private final AbstractConfigValue delayMerge(Collection<AbstractConfigValue> stack,
-                                                 AbstractConfigValue fallback) {
-        // if we turn out to be an object, and the fallback also does,
-        // then a merge may be required.
-        // if we contain a substitution, resolving it may need to look
-        // back to the fallback.
-        List<AbstractConfigValue> newStack = new ArrayList<AbstractConfigValue>();
-        newStack.addAll(stack);
-        newStack.add(fallback);
-        return constructDelayedMerge(AbstractConfigObject.mergeOrigins(newStack), newStack);
-    }
-
-    protected final AbstractConfigValue mergedWithObject(Collection<AbstractConfigValue> stack,
-                                                         AbstractConfigObject fallback) {
-        requireNotIgnoringFallbacks();
-
-        if (this instanceof AbstractConfigObject) {
-            throw new BugOrBroken("Objects must reimplement mergedWithObject");
-        }
-
-        return mergedWithNonObject(stack, fallback);
-    }
-
-    protected final AbstractConfigValue mergedWithNonObject(Collection<AbstractConfigValue> stack,
-                                                            AbstractConfigValue fallback) {
-        requireNotIgnoringFallbacks();
-
-        if (resolveStatus() == ResolveStatus.RESOLVED) {
-            // falling back to a non-object doesn't merge anything, and also
-            // prohibits merging any objects that we fall back to later.
-            // so we have to switch to ignoresFallbacks mode.
-            return withFallbacksIgnored();
-        }
-        // if unresolved, we may have to look back to fallbacks as part of
-        // the resolution process, so always delay
-        return delayMerge(stack, fallback);
-    }
-
-    protected AbstractConfigValue mergedWithTheUnmergeable(Unmergeable fallback) {
-        requireNotIgnoringFallbacks();
-
-        return mergedWithTheUnmergeable(Collections.singletonList(this), fallback);
-    }
-
-    protected AbstractConfigValue mergedWithObject(AbstractConfigObject fallback) {
-        requireNotIgnoringFallbacks();
-
-        return mergedWithObject(Collections.singletonList(this), fallback);
-    }
-
-    protected AbstractConfigValue mergedWithNonObject(AbstractConfigValue fallback) {
-        requireNotIgnoringFallbacks();
-
-        return mergedWithNonObject(Collections.singletonList(this), fallback);
-    }
-
-    @Override
-    public AbstractConfigValue withOrigin(ConfigOrigin origin) {
-        if (this.origin == origin) {
-            return this;
-        }
-        return newCopy(origin);
-    }
-
-    // this is only overridden to change the return type
-    @Override
-    public AbstractConfigValue withFallback(ConfigMergeable mergeable) {
-        if (ignoresFallbacks()) {
-            return this;
-        }
-        ConfigValue other = ((MergeableValue) mergeable).toFallbackValue();
-        if (other instanceof Unmergeable) {
-            return mergedWithTheUnmergeable((Unmergeable) other);
-        } else if (other instanceof AbstractConfigObject) {
-            return mergedWithObject((AbstractConfigObject) other);
-        }
-        return mergedWithNonObject((AbstractConfigValue) other);
-    }
-
-    protected boolean canEqual(Object other) {
-        return other instanceof ConfigValue;
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        // note that "origin" is deliberately NOT part of equality
-        if (other instanceof ConfigValue) {
-            return canEqual(other)
-                    && (this.valueType() ==
-                    ((ConfigValue) other).valueType())
-                    && ConfigImplUtil.equalsHandlingNull(this.unwrapped(),
-                    ((ConfigValue) other).unwrapped());
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        // note that "origin" is deliberately NOT part of equality
-        Object o = this.unwrapped();
-        if (o == null) {
-            return 0;
-        }
-        return o.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        render(sb, 0, true /* atRoot */, null /* atKey */, ConfigRenderOptions.concise());
-        return getClass().getSimpleName() + "(" + sb.toString() + ")";
-    }
-
-    protected static void indent(StringBuilder sb, int indent, ConfigRenderOptions options) {
-        if (options.getFormatted()) {
-            int remaining = indent;
-            while (remaining > 0) {
-                sb.append("    ");
-                --remaining;
-            }
-        }
-    }
-
-    protected void render(StringBuilder sb, int indent, boolean atRoot, String atKey, ConfigRenderOptions options) {
-        if (atKey != null) {
-            String renderedKey;
-            if (options.getJson()) {
-                renderedKey = ConfigImplUtil.renderJsonString(atKey);
-            } else {
-                renderedKey = ConfigImplUtil.renderStringUnquotedIfPossible(atKey);
-            }
-
-            sb.append(renderedKey);
-
-            if (options.getJson()) {
-                if (options.getFormatted()) {
-                    sb.append(" : ");
-                } else {
-                    sb.append(":");
-                }
-            } else {
-                // in non-JSON we can omit the colon or equals before an object
-                if (this instanceof ConfigObject) {
-                    if (options.getFormatted()) {
-                        sb.append(' ');
-                    }
-                } else {
-                    sb.append("=");
-                }
-            }
-        }
-        render(sb, indent, atRoot, options);
-    }
-
-    protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
-        Object u = unwrapped();
-        sb.append(u.toString());
-    }
-
-    @Override
-    public final String render() {
-        return render(ConfigRenderOptions.defaults());
-    }
-
-    @Override
-    public final String render(ConfigRenderOptions options) {
-        StringBuilder sb = new StringBuilder();
-        render(sb, 0, true, null, options);
-        return sb.toString();
-    }
-
-    // toString() is a debugging-oriented string but this is defined
-    // to create a string that would parse back to the value in JSON.
-    // It only works for primitive values (that would be a single token)
-    // which are auto-converted to strings when concatenating with
-    // other strings or by the DefaultTransformer.
-    String transformToString() {
-        return null;
-    }
-
-    SimpleConfig atKey(ConfigOrigin origin, String key) {
-        Map<String, AbstractConfigValue> m = Collections.singletonMap(key, this);
-        return (new SimpleConfigObject(origin, m)).toConfig();
-    }
-
-    @Override
-    public SimpleConfig atKey(String key) {
-        return atKey(SimpleConfigOrigin.newSimple("atKey(" + key + ")"), key);
-    }
-
-    SimpleConfig atPath(ConfigOrigin origin, Path path) {
-        Path parent = path.parent();
-        SimpleConfig result = atKey(origin, path.last());
-        while (parent != null) {
-            String key = parent.last();
-            result = result.atKey(origin, key);
-            parent = parent.parent();
-        }
-        return result;
-    }
-
-    @Override
-    public SimpleConfig atPath(String pathExpression) {
-        SimpleConfigOrigin origin = SimpleConfigOrigin.newSimple("atPath(" + pathExpression + ")");
-        return atPath(origin, Path.newPath(pathExpression));
-    }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigBeanImpl.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigBeanImpl.java
deleted file mode 100644
index 1cb7be7..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigBeanImpl.java
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * 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.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.Config;
-import org.apache.seatunnel.config.ConfigException.BadBean;
-import org.apache.seatunnel.config.ConfigException.Missing;
-import org.apache.seatunnel.config.ConfigException.NotResolved;
-import org.apache.seatunnel.config.ConfigException.ValidationFailed;
-import org.apache.seatunnel.config.ConfigException.ValidationProblem;
-import org.apache.seatunnel.config.ConfigList;
-import org.apache.seatunnel.config.ConfigMemorySize;
-import org.apache.seatunnel.config.ConfigObject;
-import org.apache.seatunnel.config.ConfigValue;
-import org.apache.seatunnel.config.ConfigValueType;
-import org.apache.seatunnel.config.Optional;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Internal implementation detail, not ABI stable, do not touch.
- * For use only by the {@link org.apache.seatunnel.config} package.
- */
-public class ConfigBeanImpl {
-
-    /**
-     * This is public ONLY for use by the "config" package, DO NOT USE this ABI
-     * may change.
-     *
-     * @param <T>    type of the bean
-     * @param config config to use
-     * @param clazz  class of the bean
-     * @return the bean instance
-     */
-    public static <T> T createInternal(Config config, Class<T> clazz) {
-        if (((SimpleConfig) config).root().resolveStatus() != ResolveStatus.RESOLVED) {
-            throw new NotResolved(
-                    "need to Config#resolve() a config before using it to initialize a bean, see the API docs for Config#resolve()");
-        }
-
-        Map<String, AbstractConfigValue> configProps = new HashMap<String, AbstractConfigValue>();
-        Map<String, String> originalNames = new HashMap<String, String>();
-        for (Map.Entry<String, ConfigValue> configProp : config.root().entrySet()) {
-            String originalName = configProp.getKey();
-            String camelName = ConfigImplUtil.toCamelCase(originalName);
-            // if a setting is in there both as some hyphen name and the camel name,
-            // the camel one wins
-            if (originalNames.containsKey(camelName) && !originalName.equals(camelName)) {
-                // if we aren't a camel name to start with, we lose.
-                // if we are or we are the first matching key, we win.
-            } else {
-                configProps.put(camelName, (AbstractConfigValue) configProp.getValue());
-                originalNames.put(camelName, originalName);
-            }
-        }
-
-        BeanInfo beanInfo = null;
-        try {
-            beanInfo = Introspector.getBeanInfo(clazz);
-        } catch (IntrospectionException e) {
-            throw new BadBean("Could not get bean information for class " + clazz.getName(), e);
-        }
-
-        try {
-            List<PropertyDescriptor> beanProps = new ArrayList<PropertyDescriptor>();
-            for (PropertyDescriptor beanProp : beanInfo.getPropertyDescriptors()) {
-                if (beanProp.getReadMethod() == null || beanProp.getWriteMethod() == null) {
-                    continue;
-                }
-                beanProps.add(beanProp);
-            }
-
-            // Try to throw all validation issues at once (this does not comprehensively
-            // find every issue, but it should find common ones).
-            List<ValidationProblem> problems = new ArrayList<ValidationProblem>();
-            for (PropertyDescriptor beanProp : beanProps) {
-                Method setter = beanProp.getWriteMethod();
-                Class<?> parameterClass = setter.getParameterTypes()[0];
-
-                ConfigValueType expectedType = getValueTypeOrNull(parameterClass);
-                if (expectedType != null) {
-                    String name = originalNames.get(beanProp.getName());
-                    if (name == null) {
-                        name = beanProp.getName();
-                    }
-                    Path path = Path.newKey(name);
-                    AbstractConfigValue configValue = configProps.get(beanProp.getName());
-                    if (configValue != null) {
-                        SimpleConfig.checkValid(path, expectedType, configValue, problems);
-                    } else {
-                        if (!isOptionalProperty(clazz, beanProp)) {
-                            SimpleConfig.addMissing(problems, expectedType, path, config.origin());
-                        }
-                    }
-                }
-            }
-
-            if (!problems.isEmpty()) {
-                throw new ValidationFailed(problems);
-            }
-
-            // Fill in the bean instance
-            T bean = clazz.newInstance();
-            for (PropertyDescriptor beanProp : beanProps) {
-                Method setter = beanProp.getWriteMethod();
-                Type parameterType = setter.getGenericParameterTypes()[0];
-                Class<?> parameterClass = setter.getParameterTypes()[0];
-                String configPropName = originalNames.get(beanProp.getName());
-                // Is the property key missing in the config?
-                if (configPropName == null) {
-                    // If so, continue if the field is marked as @{link Optional}
-                    if (isOptionalProperty(clazz, beanProp)) {
-                        continue;
-                    }
-                    // Otherwise, raise a {@link Missing} exception right here
-                    throw new Missing(beanProp.getName());
-                }
-                Object unwrapped = getValue(clazz, parameterType, parameterClass, config, configPropName);
-                setter.invoke(bean, unwrapped);
-            }
-            return bean;
-        } catch (InstantiationException e) {
-            throw new BadBean(clazz.getName()
-                    + " needs a public no-args constructor to be used as a bean", e);
-        } catch (IllegalAccessException e) {
-            throw new BadBean(clazz.getName()
-                    + " getters and setters are not accessible, they must be for use as a bean", e);
-        } catch (InvocationTargetException e) {
-            throw new BadBean("Calling bean method on "
-                    + clazz.getName() + " caused an exception", e);
-        }
-    }
-
-    // we could magically make this work in many cases by doing
-    // getAnyRef() (or getValue().unwrapped()), but anytime we
-    // rely on that, we aren't doing the type conversions Config
-    // usually does, and we will throw ClassCastException instead
-    // of a nicer error message giving the name of the bad
-    // setting. So, instead, we only support a limited number of
-    // types plus you can always use Object, ConfigValue, Config,
-    // ConfigObject, etc.  as an escape hatch.
-    private static Object getValue(Class<?> beanClass, Type parameterType, Class<?> parameterClass, Config config,
-                                   String configPropName) {
-        if (parameterClass == Boolean.class || parameterClass == boolean.class) {
-            return config.getBoolean(configPropName);
-        } else if (parameterClass == Integer.class || parameterClass == int.class) {
-            return config.getInt(configPropName);
-        } else if (parameterClass == Double.class || parameterClass == double.class) {
-            return config.getDouble(configPropName);
-        } else if (parameterClass == Long.class || parameterClass == long.class) {
-            return config.getLong(configPropName);
-        } else if (parameterClass == String.class) {
-            return config.getString(configPropName);
-        } else if (parameterClass == Duration.class) {
-            return config.getDuration(configPropName);
-        } else if (parameterClass == ConfigMemorySize.class) {
-            return config.getMemorySize(configPropName);
-        } else if (parameterClass == Object.class) {
-            return config.getAnyRef(configPropName);
-        } else if (parameterClass == List.class) {
-            return getListValue(beanClass, parameterType, parameterClass, config, configPropName);
-        } else if (parameterClass == Set.class) {
-            return getSetValue(beanClass, parameterType, parameterClass, config, configPropName);
-        } else if (parameterClass == Map.class) {
-            // we could do better here, but right now we don't.
-            Type[] typeArgs = ((ParameterizedType) parameterType).getActualTypeArguments();
-            if (typeArgs[0] != String.class || typeArgs[1] != Object.class) {
-                throw new BadBean("Bean property '"
-                        + configPropName + "' of class "
-                        + beanClass.getName()
-                        + " has unsupported Map<"
-                        + typeArgs[0] + "," + typeArgs[1]
-                        + ">, only Map<String,Object> is supported right now");
-            }
-            return config.getObject(configPropName).unwrapped();
-        } else if (parameterClass == Config.class) {
-            return config.getConfig(configPropName);
-        } else if (parameterClass == ConfigObject.class) {
-            return config.getObject(configPropName);
-        } else if (parameterClass == ConfigValue.class) {
-            return config.getValue(configPropName);
-        } else if (parameterClass == ConfigList.class) {
-            return config.getList(configPropName);
-        } else if (parameterClass.isEnum()) {
-            @SuppressWarnings("unchecked")
-            Enum enumValue = config.getEnum((Class<Enum>) parameterClass, configPropName);
-            return enumValue;
-        } else if (hasAtLeastOneBeanProperty(parameterClass)) {
-            return createInternal(config.getConfig(configPropName), parameterClass);
-        }
-        throw new BadBean("Bean property "
-                + configPropName + " of class "
-                + beanClass.getName()
-                + " has unsupported type "
-                + parameterType);
-    }
-
-    private static Object getSetValue(Class<?> beanClass, Type parameterType, Class<?> parameterClass, Config config, String configPropName) {
-        return new HashSet((List) getListValue(beanClass, parameterType, parameterClass, config, configPropName));
-    }
-
-    private static Object getListValue(Class<?> beanClass, Type parameterType, Class<?> parameterClass, Config config, String configPropName) {
-        Type elementType = ((ParameterizedType) parameterType).getActualTypeArguments()[0];
-
-        if (elementType == Boolean.class) {
-            return config.getBooleanList(configPropName);
-        } else if (elementType == Integer.class) {
-            return config.getIntList(configPropName);
-        } else if (elementType == Double.class) {
-            return config.getDoubleList(configPropName);
-        } else if (elementType == Long.class) {
-            return config.getLongList(configPropName);
-        } else if (elementType == String.class) {
-            return config.getStringList(configPropName);
-        } else if (elementType == Duration.class) {
-            return config.getDurationList(configPropName);
-        } else if (elementType == ConfigMemorySize.class) {
-            return config.getMemorySizeList(configPropName);
-        } else if (elementType == Object.class) {
-            return config.getAnyRefList(configPropName);
-        } else if (elementType == Config.class) {
-            return config.getConfigList(configPropName);
-        } else if (elementType == ConfigObject.class) {
-            return config.getObjectList(configPropName);
-        } else if (elementType == ConfigValue.class) {
-            return config.getList(configPropName);
-        } else if (((Class<?>) elementType).isEnum()) {
-            @SuppressWarnings("unchecked")
-            List<Enum> enumValues = config.getEnumList((Class<Enum>) elementType, configPropName);
-            return enumValues;
-        } else if (hasAtLeastOneBeanProperty((Class<?>) elementType)) {
-            List<Object> beanList = new ArrayList<Object>();
-            List<? extends Config> configList = config.getConfigList(configPropName);
-            for (Config listMember : configList) {
-                beanList.add(createInternal(listMember, (Class<?>) elementType));
-            }
-            return beanList;
-        }
-        throw new BadBean("Bean property '"
-                + configPropName + "' of class "
-                + beanClass.getName()
-                + " has unsupported list element type "
-                + elementType);
-    }
-
-    // null if we can't easily say; this is heuristic/best-effort
-    private static ConfigValueType getValueTypeOrNull(Class<?> parameterClass) {
-        if (parameterClass == Boolean.class || parameterClass == boolean.class) {
-            return ConfigValueType.BOOLEAN;
-        } else if (parameterClass == Integer.class || parameterClass == int.class) {
-            return ConfigValueType.NUMBER;
-        } else if (parameterClass == Double.class || parameterClass == double.class) {
-            return ConfigValueType.NUMBER;
-        } else if (parameterClass == Long.class || parameterClass == long.class) {
-            return ConfigValueType.NUMBER;
-        } else if (parameterClass == String.class) {
-            return ConfigValueType.STRING;
-        } else if (parameterClass == Duration.class) {
-            return null;
-        } else if (parameterClass == ConfigMemorySize.class) {
-            return null;
-        } else if (parameterClass == List.class) {
-            return ConfigValueType.LIST;
-        } else if (parameterClass == Map.class) {
-            return ConfigValueType.OBJECT;
-        } else if (parameterClass == Config.class) {
-            return ConfigValueType.OBJECT;
-        } else if (parameterClass == ConfigObject.class) {
-            return ConfigValueType.OBJECT;
-        } else if (parameterClass == ConfigList.class) {
-            return ConfigValueType.LIST;
-        }
-        return null;
-    }
-
-    private static boolean hasAtLeastOneBeanProperty(Class<?> clazz) {
-        BeanInfo beanInfo = null;
-        try {
-            beanInfo = Introspector.getBeanInfo(clazz);
-        } catch (IntrospectionException e) {
-            return false;
-        }
-
-        for (PropertyDescriptor beanProp : beanInfo.getPropertyDescriptors()) {
-            if (beanProp.getReadMethod() != null && beanProp.getWriteMethod() != null) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static boolean isOptionalProperty(Class beanClass, PropertyDescriptor beanProp) {
-        Field field = getField(beanClass, beanProp.getName());
-        return field != null && (field.getAnnotationsByType(Optional.class).length > 0);
-    }
-
-    private static Field getField(Class beanClass, String fieldName) {
-        try {
-            Field field = beanClass.getDeclaredField(fieldName);
-            field.setAccessible(true);
-            return field;
-        } catch (NoSuchFieldException e) {
-            // Don't give up yet. Try to look for field in super class, if any.
-        }
-        beanClass = beanClass.getSuperclass();
-        if (beanClass == null) {
-            return null;
-        }
-        return getField(beanClass, fieldName);
-    }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigBoolean.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigBoolean.java
deleted file mode 100644
index 9d4cd30..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigBoolean.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigValueType;
-
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-
-final class ConfigBoolean extends AbstractConfigValue implements Serializable {
-
-    private static final long serialVersionUID = 2L;
-
-    private final boolean value;
-
-    ConfigBoolean(ConfigOrigin origin, boolean value) {
-        super(origin);
-        this.value = value;
-    }
-
-    @Override
-    public ConfigValueType valueType() {
-        return ConfigValueType.BOOLEAN;
-    }
-
-    @Override
-    public Boolean unwrapped() {
-        return value;
-    }
-
-    @Override
-    String transformToString() {
-        return value ? "true" : "false";
-    }
-
-    @Override
-    protected ConfigBoolean newCopy(ConfigOrigin origin) {
-        return new ConfigBoolean(origin, value);
-    }
-
-    // serialization all goes through SerializedConfigValue
-    private Object writeReplace() throws ObjectStreamException {
-        return new SerializedConfigValue(this);
-    }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigConcatenation.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigConcatenation.java
deleted file mode 100644
index c12306d..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigConcatenation.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * 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.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.ConfigException.BugOrBroken;
-import org.apache.seatunnel.config.ConfigException.NotResolved;
-import org.apache.seatunnel.config.ConfigException.WrongType;
-import org.apache.seatunnel.config.ConfigObject;
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigRenderOptions;
-import org.apache.seatunnel.config.ConfigValueType;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A ConfigConcatenation represents a list of values to be concatenated (see the
- * spec). It only has to exist if at least one value is an unresolved
- * substitution, otherwise we could go ahead and collapse the list into a single
- * value.
- * <p>
- * Right now this is always a list of strings and ${} references, but in the
- * future should support a list of ConfigList. We may also support
- * concatenations of objects, but ConfigDelayedMerge should be used for that
- * since a concat of objects really will merge, not concatenate.
- */
-final class ConfigConcatenation extends AbstractConfigValue implements Unmergeable, Container {
-
-    private final List<AbstractConfigValue> pieces;
-
-    ConfigConcatenation(ConfigOrigin origin, List<AbstractConfigValue> pieces) {
-        super(origin);
-        this.pieces = pieces;
-
-        if (pieces.size() < 2) {
-            throw new BugOrBroken("Created concatenation with less than 2 items: " + this);
-        }
-
-        boolean hadUnmergeable = false;
-        for (AbstractConfigValue p : pieces) {
-            if (p instanceof ConfigConcatenation) {
-                throw new BugOrBroken(
-                        "ConfigConcatenation should never be nested: " + this);
-            }
-            if (p instanceof Unmergeable) {
-                hadUnmergeable = true;
-            }
-        }
-        if (!hadUnmergeable) {
-            throw new BugOrBroken(
-                    "Created concatenation without an unmergeable in it: " + this);
-        }
-    }
-
-    private NotResolved notResolved() {
-        return new NotResolved(
-                "need to Config#resolve(), see the API docs for Config#resolve(); substitution not resolved: " + this);
-    }
-
-    @Override
-    public ConfigValueType valueType() {
-        throw notResolved();
-    }
-
-    @Override
-    public Object unwrapped() {
-        throw notResolved();
-    }
-
-    @Override
-    protected ConfigConcatenation newCopy(ConfigOrigin newOrigin) {
-        return new ConfigConcatenation(newOrigin, pieces);
-    }
-
-    @Override
-    protected boolean ignoresFallbacks() {
-        // we can never ignore fallbacks because if a child ConfigReference
-        // is self-referential we have to look lower in the merge stack
-        // for its value.
-        return false;
-    }
-
-    @Override
-    public Collection<ConfigConcatenation> unmergedValues() {
-        return Collections.singleton(this);
-    }
-
-    private static boolean isIgnoredWhitespace(AbstractConfigValue value) {
-        return (value instanceof ConfigString) && !((ConfigString) value).wasQuoted();
-    }
-
-    /**
-     * Add left and right, or their merger, to builder.
-     */
-    private static void join(ArrayList<AbstractConfigValue> builder, AbstractConfigValue origRight) {
-        AbstractConfigValue left = builder.get(builder.size() - 1);
-        AbstractConfigValue right = origRight;
-
-        // check for an object which can be converted to a list
-        // (this will be an object with numeric keys, like foo.0, foo.1)
-        if (left instanceof ConfigObject && right instanceof SimpleConfigList) {
-            left = DefaultTransformer.transform(left, ConfigValueType.LIST);
-        } else if (left instanceof SimpleConfigList && right instanceof ConfigObject) {
-            right = DefaultTransformer.transform(right, ConfigValueType.LIST);
-        }
-
-        // Since this depends on the type of two instances, I couldn't think
-        // of much alternative to an instanceof chain. Visitors are sometimes
-        // used for multiple dispatch but seems like overkill.
-        AbstractConfigValue joined = null;
-        if (left instanceof ConfigObject && right instanceof ConfigObject) {
-            joined = right.withFallback(left);
-        } else if (left instanceof SimpleConfigList && right instanceof SimpleConfigList) {
-            joined = ((SimpleConfigList) left).concatenate((SimpleConfigList) right);
-        } else if ((left instanceof SimpleConfigList || left instanceof ConfigObject) &&
-                isIgnoredWhitespace(right)) {
-            joined = left;
-            // it should be impossible that left is whitespace and right is a list or object
-        } else if (left instanceof ConfigConcatenation || right instanceof ConfigConcatenation) {
-            throw new BugOrBroken("unflattened ConfigConcatenation");
-        } else if (left instanceof Unmergeable || right instanceof Unmergeable) {
-            // leave joined=null, cannot join
-        } else {
-            // handle primitive type or primitive type mixed with object or list
-            String s1 = left.transformToString();
-            String s2 = right.transformToString();
-            if (s1 == null || s2 == null) {
-                throw new WrongType(left.origin(),
-                        "Cannot concatenate object or list with a non-object-or-list, " + left + " and " + right + " are not compatible");
-            } else {
-                ConfigOrigin joinedOrigin = SimpleConfigOrigin.mergeOrigins(left.origin(),
-                        right.origin());
-                joined = new ConfigString.Quoted(joinedOrigin, s1 + s2);
-            }
-        }
-
-        if (joined == null) {
-            builder.add(right);
-        } else {
-            builder.remove(builder.size() - 1);
-            builder.add(joined);
-        }
-    }
-
-    static List<AbstractConfigValue> consolidate(List<AbstractConfigValue> pieces) {
-        if (pieces.size() < 2) {
-            return pieces;
-        }
-        List<AbstractConfigValue> flattened = new ArrayList<AbstractConfigValue>(pieces.size());
-        for (AbstractConfigValue v : pieces) {
-            if (v instanceof ConfigConcatenation) {
-                flattened.addAll(((ConfigConcatenation) v).pieces);
-            } else {
-                flattened.add(v);
-            }
-        }
-
-        ArrayList<AbstractConfigValue> consolidated = new ArrayList<AbstractConfigValue>(
-                flattened.size());
-        for (AbstractConfigValue v : flattened) {
-            if (consolidated.isEmpty()) {
-                consolidated.add(v);
-            } else {
-                join(consolidated, v);
-            }
-        }
-
-        return consolidated;
-    }
-
-    static AbstractConfigValue concatenate(List<AbstractConfigValue> pieces) {
-        List<AbstractConfigValue> consolidated = consolidate(pieces);
-        if (consolidated.isEmpty()) {
-            return null;
-        } else if (consolidated.size() == 1) {
-            return consolidated.get(0);
-        }
-        ConfigOrigin mergedOrigin = SimpleConfigOrigin.mergeOrigins(consolidated);
-        return new ConfigConcatenation(mergedOrigin, consolidated);
-    }
-
-    @Override
-    ResolveResult<? extends AbstractConfigValue> resolveSubstitutions(ResolveContext context, ResolveSource source)
-            throws NotPossibleToResolve {
-        if (ConfigImpl.traceSubSituationsEnable()) {
-            int indent = context.depth() + 2;
-            ConfigImpl.trace(indent - 1, "concatenation has " + pieces.size() + " pieces:");
-            int count = 0;
-            for (AbstractConfigValue v : pieces) {
-                ConfigImpl.trace(indent, count + ": " + v);
-                count += 1;
-            }
-        }
-
-        // Right now there's no reason to pushParent here because the
-        // content of ConfigConcatenation should not need to replaceChild,
-        // but if it did we'd have to do this.
-        ResolveSource sourceWithParent = source; // .pushParent(this);
-        ResolveContext newContext = context;
-
-        List<AbstractConfigValue> resolved = new ArrayList<AbstractConfigValue>(pieces.size());
-        for (AbstractConfigValue p : pieces) {
-            // to concat into a string we have to do a full resolve,
-            // so unrestrict the context, then put restriction back afterward
-            Path restriction = newContext.restrictToChild();
-            ResolveResult<? extends AbstractConfigValue> result = newContext.unrestricted()
-                    .resolve(p, sourceWithParent);
-            AbstractConfigValue r = result.value;
-            newContext = result.context.restrict(restriction);
-            if (ConfigImpl.traceSubSituationsEnable()) {
-                ConfigImpl.trace(context.depth(), "resolved concat piece to " + r);
-            }
-            if (r == null) {
-                // it was optional... omit
-            } else {
-                resolved.add(r);
-            }
-        }
-
-        // now need to concat everything
-        List<AbstractConfigValue> joined = consolidate(resolved);
-        // if unresolved is allowed we can just become another
-        // ConfigConcatenation
-        if (joined.size() > 1 && context.options().getAllowUnresolved()) {
-            return ResolveResult.make(newContext, new ConfigConcatenation(this.origin(), joined));
-        } else if (joined.isEmpty()) {
-            // we had just a list of optional references using ${?}
-            return ResolveResult.make(newContext, null);
-        } else if (joined.size() == 1) {
-            return ResolveResult.make(newContext, joined.get(0));
-        }
-        throw new BugOrBroken("Bug in the library; resolved list was joined to too many values: " + joined);
-    }
-
-    @Override
-    ResolveStatus resolveStatus() {
-        return ResolveStatus.UNRESOLVED;
-    }
-
-    @Override
-    public ConfigConcatenation replaceChild(AbstractConfigValue child, AbstractConfigValue replacement) {
-        List<AbstractConfigValue> newPieces = replaceChildInList(pieces, child, replacement);
-        if (newPieces == null) {
-            return null;
-        }
-        return new ConfigConcatenation(origin(), newPieces);
-    }
-
-    @Override
-    public boolean hasDescendant(AbstractConfigValue descendant) {
-        return hasDescendantInList(pieces, descendant);
-    }
-
-    // when you graft a substitution into another object,
-    // you have to prefix it with the location in that object
-    // where you grafted it; but save prefixLength so
-    // system property and env variable lookups don't get
-    // broken.
-    @Override
-    ConfigConcatenation relativized(Path prefix) {
-        List<AbstractConfigValue> newPieces = new ArrayList<AbstractConfigValue>();
-        for (AbstractConfigValue p : pieces) {
-            newPieces.add(p.relativized(prefix));
-        }
-        return new ConfigConcatenation(origin(), newPieces);
-    }
-
-    @Override
-    protected boolean canEqual(Object other) {
-        return other instanceof ConfigConcatenation;
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        // note that "origin" is deliberately NOT part of equality
-        if (other instanceof ConfigConcatenation) {
-            return canEqual(other) && this.pieces.equals(((ConfigConcatenation) other).pieces);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        // note that "origin" is deliberately NOT part of equality
-        return pieces.hashCode();
-    }
-
-    @Override
-    protected void render(StringBuilder sb, int indent, boolean atRoot, ConfigRenderOptions options) {
-        for (AbstractConfigValue p : pieces) {
-            p.render(sb, indent, atRoot, options);
-        }
-    }
-}
diff --git a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigDelayedMerge.java b/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigDelayedMerge.java
deleted file mode 100644
index 8398c55..0000000
--- a/seatunnel-config/src/main/java/org/apache/seatunnel/config/impl/ConfigDelayedMerge.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * 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.seatunnel.config.impl;
-
-import org.apache.seatunnel.config.ConfigException.BugOrBroken;
-import org.apache.seatunnel.config.ConfigException.NotResolved;
-import org.apache.seatunnel.config.ConfigOrigin;
-import org.apache.seatunnel.config.ConfigRenderOptions;
-import org.apache.seatunnel.config.ConfigValueType;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * The issue here is that we want to first merge our stack of config files, and
- * then we want to evaluate substitutions. But if two substitutions both expand
- * to an object, we might need to merge those two objects. Thus, we can't ever
- * "override" a substitution when we do a merge; instead we have to save the
- * stack of values that should be merged, and resolve the merge when we evaluate
- * substitutions.
- */
-final class ConfigDelayedMerge extends AbstractConfigValue implements Unmergeable,
-        ReplaceableMergeStack {
-
-    // earlier items in the stack win
-    private final List<AbstractConfigValue> stack;
-
-    ConfigDelayedMerge(ConfigOrigin origin, List<AbstractConfigValue> stack) {
-        super(origin);
-        this.stack = stack;
-        if (stack.isEmpty()) {
-            throw new BugOrBroken(
-                    "creating empty delayed merge value");
-        }
-
-        for (AbstractConfigValue v : stack) {
-            if (v instanceof ConfigDelayedMerge || v instanceof ConfigDelayedMergeObject) {
-                throw new BugOrBroken(
-                        "placed nested DelayedMerge in a ConfigDelayedMerge, should have consolidated stack");
-            }
-        }
-    }
-
-    @Override
-    public ConfigValueType valueType() {
-        throw new NotResolved(
-                "called valueType() on value with unresolved substitutions, need to Config#resolve() first, see API docs");
-    }
-
-    @Override
-    public Object unwrapped() {
-        throw new NotResolved(
-                "called unwrapped() on value with unresolved substitutions, need to Config#resolve() first, see API docs");
-    }
-
-    @Override
-    ResolveResult<? extends AbstractConfigValue> resolveSubstitutions(ResolveContext context, ResolveSource source)
-            throws NotPossibleToResolve {
-        return resolveSubstitutions(this, stack, context, source);
-    }
-
-    // static method also used by ConfigDelayedMergeObject
-    static ResolveResult<? extends AbstractConfigValue> resolveSubstitutions(ReplaceableMergeStack replaceable,
-                                                                             List<AbstractConfigValue> stack,
-                                                                             ResolveContext context, ResolveSource source) throws NotPossibleToResolve {
-        if (ConfigImpl.traceSubSituationsEnable()) {
-            ConfigImpl.trace(context.depth(), "delayed merge stack has " + stack.size() + " items:");
-            int count = 0;
-            for (AbstractConfigValue v : stack) {
-                ConfigImpl.trace(context.depth() + 1, count + ": " + v);
-                count += 1;
-            }
-        }
-
-        // to resolve substitutions, we need to recursively resolve
-        // the stack of stuff to merge, and merge the stack so
-        // we won't be a delayed merge anymore. If restrictToChildOrNull
-        // is non-null, or resolve options allow partial resolves,
-        // we may remain a delayed merge though.
-
-        ResolveContext newContext = context;
-        int count = 0;
-        AbstractConfigValue merged = null;
-        for (AbstractConfigValue end : stack) {
-            // the end value may or may not be resolved already
-
-            ResolveSource sourceForEnd;
-
-            if (end instanceof ReplaceableMergeStack) {
-                throw new BugOrBroken("A delayed merge should not contain another one: " + replaceable);
-            } else if (end instanceof Unmergeable) {
-                // the remainder could be any kind of value, including another
-                // ConfigDelayedMerge
-                AbstractConfigValue remainder = replaceable.makeReplacement(context, count + 1);
-
-                if (ConfigImpl.traceSubSituationsEnable()) {
-                    ConfigImpl.trace(newContext.depth(), "remainder portion: " + remainder);
-                }
-
-                // If, while resolving 'end' we come back to the same
-                // merge stack, we only want to look _below_ 'end'
-                // in the stack. So we arrange to replace the
-                // ConfigDelayedMerge with a value that is only
-                // the remainder of the stack below this one.
-
-                if (ConfigImpl.traceSubSituationsEnable()) {
-                    ConfigImpl.trace(newContext.depth(), "building sourceForEnd");
-                }
-
-                // we resetParents() here because we'll be resolving "end"
-                // against a root which does NOT contain "end"
-                sourceForEnd = source.replaceWithinCurrentParent((AbstractConfigValue) replaceable, remainder);
-
-                if (ConfigImpl.traceSubSituationsEnable()) {
-                    ConfigImpl.trace(newContext.depth(), "  sourceForEnd before reset parents but after replace: " + sourceForEnd);
-                }
-
-                sourceForEnd = sourceForEnd.resetParents();
-            } else {
-                if (ConfigImpl.traceSubSituationsEnable()) {
-                    ConfigImpl.trace(newContext.depth(),
-                            "will resolve end against the original source with parent pushed");
-                }
-
-                sourceForEnd = source.pushParent(replaceable);
-            }
-
-            if (ConfigImpl.traceSubSituationsEnable()) {
-                ConfigImpl.trace(newContext.depth(), "sourceForEnd      =" + sourceForEnd);
-            }
-
-            if (ConfigImpl.traceSubSituationsEnable()) {
-                ConfigImpl.trace(newContext.depth(), "Resolving highest-priority item in delayed merge "
-                        + end + " against " + sourceForEnd
-                        + " endWasRemoved=" + (source != sourceForEnd));
-            }
-            ResolveResult<? extends AbstractConfigValue> result = newContext.resolve(end, sourceForEnd);
-            AbstractConfigValue resolvedEnd = result.value;
-            newContext = result.context;
-
... 16846 lines suppressed ...