Add pool metrics support for Derby/Sybase/SQLite/DB2/OceanBase jdbc URL format in URLParser (#687)

diff --git a/CHANGES.md b/CHANGES.md
index fcde635..6b6c759 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -10,6 +10,7 @@
 * Support for C3P0 connection pool tracing.
 * Use a daemon thread to flush logs.
 * Fix typos in `URLParser`.
+* Add support for `Derby`/`Sybase`/`SQLite`/`DB2`/`OceanBase` jdbc url format in `URLParser`.
 
 All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/213?closed=1)
 
diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
index 5364ff0..b7307eb 100755
--- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
+++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
@@ -247,4 +247,15 @@
 
     public static final OfficialComponent C3P0 = new OfficialComponent(152, "c3p0");
 
+    public static final OfficialComponent DERBY_JDBC_DRIVER = new OfficialComponent(153, "Derby-jdbc-driver");
+
+    public static final OfficialComponent SQLITE_JDBC_DRIVER = new OfficialComponent(154, "Sqlite-jdbc-driver");
+
+    public static final OfficialComponent DB2_JDBC_DRIVER = new OfficialComponent(155, "Db2-jdbc-driver");
+
+    public static final OfficialComponent SYBASE_JDBC_DRIVER = new OfficialComponent(156, "Sybase-jdbc-driver");
+
+    public static final OfficialComponent OCEANBASE_JDBC_DRIVER = new OfficialComponent(157, "OceanBase-jdbc-driver");
+
+
 }
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/Db2URLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/Db2URLParser.java
new file mode 100644
index 0000000..8fe2b36
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/Db2URLParser.java
@@ -0,0 +1,129 @@
+/*
+ * 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.skywalking.apm.plugin.jdbc.connectionurl.parser;
+
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+
+public class Db2URLParser extends AbstractURLParser {
+    private static final String DEFAULT_HOST = "localhost";
+    private static final int DEFAULT_PORT = 50000;
+    private static final String DB_TYPE = "DB2";
+    private static final String JDBC_PREFIX = "jdbc:db2:";
+
+    public Db2URLParser(String url) {
+        super(url);
+    }
+
+    @Override
+    protected URLLocation fetchDatabaseHostsIndexRange() {
+        int hostLabelStartIndex = url.indexOf("//");
+        if (hostLabelStartIndex == -1) {
+            return null;
+        }
+        int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
+        int hostLabelEndIndexWithParameter = url.indexOf(":", hostLabelEndIndex + 1);
+        if (hostLabelEndIndex == -1) {
+            hostLabelEndIndex = hostLabelEndIndexWithParameter;
+        }
+        if (hostLabelEndIndexWithParameter < hostLabelEndIndex && hostLabelEndIndexWithParameter != -1) {
+            hostLabelEndIndex = hostLabelEndIndexWithParameter;
+        }
+        if (hostLabelEndIndex == -1) {
+            hostLabelEndIndex = url.length();
+        }
+        return new URLLocation(hostLabelStartIndex + 2, hostLabelEndIndex);
+    }
+
+    protected String fetchDatabaseNameFromURL(int startSize) {
+        URLLocation hostsLocation = fetchDatabaseNameIndexRange(startSize);
+        if (hostsLocation == null) {
+            return "";
+        }
+        return url.substring(hostsLocation.startIndex(), hostsLocation.endIndex());
+    }
+
+    protected URLLocation fetchDatabaseNameIndexRange(int startSize) {
+        int databaseStartTag = url.indexOf("/", startSize);
+        int parameterStartTag = url.indexOf(":", startSize);
+        if (parameterStartTag < databaseStartTag && parameterStartTag != -1) {
+            return null;
+        }
+        if (databaseStartTag == -1) {
+            databaseStartTag = startSize - 1;
+        }
+        int databaseEndTag = url.indexOf(":", startSize);
+        if (databaseEndTag == -1) {
+            databaseEndTag = url.length();
+        }
+        return new URLLocation(databaseStartTag + 1, databaseEndTag);
+    }
+
+    @Override
+    protected URLLocation fetchDatabaseNameIndexRange() {
+        int databaseStartTag = url.lastIndexOf("/");
+        int databaseEndTag = url.indexOf(":", databaseStartTag);
+        if (databaseEndTag == -1) {
+            databaseEndTag = url.length();
+        }
+        return new URLLocation(databaseStartTag + 1, databaseEndTag);
+    }
+
+    @Override
+    public ConnectionInfo parse() {
+        URLLocation location = fetchDatabaseHostsIndexRange();
+        if (location == null) {
+            return new ConnectionInfo(
+                ComponentsDefine.DB2_JDBC_DRIVER, DB_TYPE, DEFAULT_HOST, DEFAULT_PORT,
+                fetchDatabaseNameFromURL(JDBC_PREFIX.length())
+            );
+        }
+        String hosts = url.substring(location.startIndex(), location.endIndex());
+        String[] hostSegment = hosts.split(",");
+        if (hostSegment.length > 1) {
+            StringBuilder sb = new StringBuilder();
+            for (String host : hostSegment) {
+                if (host.split(":").length == 1) {
+                    sb.append(host).append(":").append(DEFAULT_PORT).append(",");
+                } else {
+                    sb.append(host).append(",");
+                }
+            }
+            return new ConnectionInfo(
+                ComponentsDefine.DB2_JDBC_DRIVER, DB_TYPE, sb.substring(0, sb.length() - 1),
+                fetchDatabaseNameFromURL()
+            );
+        } else {
+            String[] hostAndPort = hostSegment[0].split(":");
+            if (hostAndPort.length != 1) {
+                return new ConnectionInfo(
+                    ComponentsDefine.DB2_JDBC_DRIVER, DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]),
+                    fetchDatabaseNameFromURL(location
+                                                 .endIndex())
+                );
+            } else {
+                return new ConnectionInfo(
+                    ComponentsDefine.DB2_JDBC_DRIVER, DB_TYPE, hostAndPort[0], DEFAULT_PORT,
+                    fetchDatabaseNameFromURL(location
+                                                 .endIndex())
+                );
+            }
+        }
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/DerbyURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/DerbyURLParser.java
new file mode 100644
index 0000000..dd96b8e
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/DerbyURLParser.java
@@ -0,0 +1,197 @@
+/*
+ * 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.skywalking.apm.plugin.jdbc.connectionurl.parser;
+
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+
+public class DerbyURLParser extends AbstractURLParser {
+
+    private static final String DEFAULT_HOST = "localhost";
+    private static final int DEFAULT_PORT = 1527;
+    private static final String DB_TYPE = "Derby";
+    private static final String DERBY_JDBC_URL_PREFIX = "jdbc:derby";
+    /**
+     * Flag that running with directory mode.
+     */
+    private static final String DIRECTORY_MODE_FLAG = "derby:directory";
+    /**
+     * Flag that running with memory mode.
+     */
+    private static final String MEMORY_MODE_FLAG = "derby:memory";
+    /**
+     * Flag that running with classpath mode.
+     */
+    private static final String CLASSPATH_MODE_FLAG = "derby:classpath";
+    /**
+     * Flag that running with jar mode.
+     */
+    private static final String JAR_MODE_FLAG = "derby:jar";
+
+    public DerbyURLParser(String url) {
+        super(url);
+    }
+
+    /**
+     * Fetch range index that the database name from connection url if Derby database running in client/server
+     * environment. eg: jdbc:derby://host[:port]/[databaseName][;attribute=value]*
+     *
+     * @return range index that the database name.
+     */
+    @Override
+    protected URLLocation fetchDatabaseHostsIndexRange() {
+        int hostLabelStartIndex = url.indexOf("//");
+        int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
+        return new URLLocation(hostLabelStartIndex + 2, hostLabelEndIndex);
+    }
+
+    @Override
+    protected URLLocation fetchDatabaseNameIndexRange() {
+        int databaseEndTag = url.indexOf(";");
+        if (databaseEndTag == -1) {
+            databaseEndTag = url.length();
+        }
+        int databaseStartTag = url.lastIndexOf("\\");
+        if (databaseStartTag == -1) {
+            databaseStartTag = url.lastIndexOf("/");
+        }
+        if (url.indexOf(":", databaseStartTag) != -1) {
+            databaseStartTag = url.indexOf(":", databaseStartTag);
+        }
+        return new URLLocation(databaseStartTag + 1, databaseEndTag);
+    }
+
+    @Override
+    public ConnectionInfo parse() {
+        int[] databaseNameRangeIndex = fetchDatabaseNameRangeIndexForSubProtocol(DIRECTORY_MODE_FLAG);
+        if (databaseNameRangeIndex != null) {
+            return defaultConnection(databaseNameRangeIndex);
+        }
+        databaseNameRangeIndex = fetchDatabaseNameRangeIndexForSubProtocol(MEMORY_MODE_FLAG);
+        if (databaseNameRangeIndex != null) {
+            return defaultConnection(databaseNameRangeIndex);
+        }
+        databaseNameRangeIndex = fetchDatabaseNameRangeIndexForSubProtocol(CLASSPATH_MODE_FLAG);
+        if (databaseNameRangeIndex != null) {
+            return defaultConnection(databaseNameRangeIndex);
+        }
+        databaseNameRangeIndex = fetchDatabaseNameRangeIndexForSubProtocol(JAR_MODE_FLAG);
+        if (databaseNameRangeIndex != null) {
+            return defaultConnection(databaseNameRangeIndex);
+        }
+        databaseNameRangeIndex = fetchDatabaseNameRangeIndexWithoutHosts();
+        if (databaseNameRangeIndex != null) {
+            return defaultConnection(databaseNameRangeIndex);
+        }
+        String[] hostAndPort = fetchDatabaseHostsFromURL().split(":");
+        if (hostAndPort.length == 1) {
+            return new ConnectionInfo(
+                ComponentsDefine.DERBY_JDBC_DRIVER, DB_TYPE, hostAndPort[0], DEFAULT_PORT, fetchDatabaseNameFromURL());
+        } else {
+            return new ConnectionInfo(
+                ComponentsDefine.DERBY_JDBC_DRIVER, DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]),
+                fetchDatabaseNameFromURL()
+            );
+        }
+    }
+
+    /**
+     * Fetch range index that the database name from connection url if Derby database running in embedded environment.
+     * eg: jdbc:derby:[databaseName][;attribute=value]*
+     *
+     * @return range index that the database name.
+     */
+    private int[] fetchDatabaseNameRangeIndexWithoutHosts() {
+        if (url.contains("//")) {
+            return null;
+        }
+        int fileLabelIndex = url.indexOf(DERBY_JDBC_URL_PREFIX);
+        int parameterLabelIndex = url.indexOf(";");
+        if (parameterLabelIndex == -1) {
+            parameterLabelIndex = url.length();
+        }
+
+        if (fileLabelIndex != -1) {
+            int pathLabelIndexForLinux = url.lastIndexOf("/");
+            if (pathLabelIndexForLinux != -1 && pathLabelIndexForLinux > fileLabelIndex) {
+                return new int[] {
+                    pathLabelIndexForLinux + 1,
+                    parameterLabelIndex
+                };
+            }
+            int pathLabelIndexForWin = url.lastIndexOf("\\");
+            if (pathLabelIndexForWin != -1 && pathLabelIndexForWin > fileLabelIndex) {
+                return new int[] {
+                    pathLabelIndexForWin + 1,
+                    parameterLabelIndex
+                };
+            }
+            return new int[] {
+                fileLabelIndex + DERBY_JDBC_URL_PREFIX.length() + 1,
+                parameterLabelIndex
+            };
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Fetch range index that the database name from connection url if Derby database running with subprotocol. eg:
+     * jdbc:derby:subprotocol:[databaseName][;attribute=value]*
+     *
+     * @return range index that the database name.
+     */
+    private int[] fetchDatabaseNameRangeIndexForSubProtocol(String mode) {
+        int fileLabelIndex = url.indexOf(mode);
+        int parameterLabelIndex = url.indexOf(";", fileLabelIndex);
+        if (parameterLabelIndex == -1) {
+            parameterLabelIndex = url.length();
+        }
+
+        if (fileLabelIndex != -1) {
+            int pathLabelIndexForLinux = url.lastIndexOf("/");
+            if (pathLabelIndexForLinux != -1 && pathLabelIndexForLinux > fileLabelIndex) {
+                return new int[] {
+                    pathLabelIndexForLinux + 1,
+                    parameterLabelIndex
+                };
+            }
+            int pathLabelIndexForWin = url.lastIndexOf("\\");
+            if (pathLabelIndexForWin != -1 && pathLabelIndexForWin > fileLabelIndex) {
+                return new int[] {
+                    pathLabelIndexForWin + 1,
+                    parameterLabelIndex
+                };
+            }
+            return new int[] {
+                fileLabelIndex + mode.length() + 1,
+                parameterLabelIndex
+            };
+        } else {
+            return null;
+        }
+    }
+
+    private ConnectionInfo defaultConnection(int[] databaseNameRangeIndex) {
+        return new ConnectionInfo(
+            ComponentsDefine.DERBY_JDBC_DRIVER, DB_TYPE, DEFAULT_HOST, -1,
+            fetchDatabaseNameFromURL(databaseNameRangeIndex)
+        );
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/OceanBaseURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/OceanBaseURLParser.java
new file mode 100644
index 0000000..f459c26
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/OceanBaseURLParser.java
@@ -0,0 +1,27 @@
+/*
+ * 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.skywalking.apm.plugin.jdbc.connectionurl.parser;
+
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+
+public class OceanBaseURLParser extends MysqlURLParser {
+    public OceanBaseURLParser(String url) {
+        super(url, "OceanBase", ComponentsDefine.OCEANBASE_JDBC_DRIVER, 2881);
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/SqliteURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/SqliteURLParser.java
new file mode 100644
index 0000000..21f4449
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/SqliteURLParser.java
@@ -0,0 +1,57 @@
+/*
+ * 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.skywalking.apm.plugin.jdbc.connectionurl.parser;
+
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+
+public class SqliteURLParser extends AbstractURLParser {
+    private static final String DEFAULT_HOST = "localhost";
+    private static final int DEFAULT_PORT = -1;
+    private static final String DB_TYPE = "Sqlite";
+
+    public SqliteURLParser(String url) {
+        super(url);
+    }
+
+    @Override
+    protected URLLocation fetchDatabaseHostsIndexRange() {
+        return null;
+    }
+
+    @Override
+    protected URLLocation fetchDatabaseNameIndexRange() {
+        int databaseStartTag = url.lastIndexOf("/");
+        if (databaseStartTag == -1) {
+            databaseStartTag = url.lastIndexOf(":");
+        }
+        int databaseEndTag = url.indexOf("?");
+        if (databaseEndTag == -1) {
+            databaseEndTag = url.length();
+        }
+
+        return new URLLocation(databaseStartTag + 1, databaseEndTag);
+    }
+
+    @Override
+    public ConnectionInfo parse() {
+        return new ConnectionInfo(
+            ComponentsDefine.SQLITE_JDBC_DRIVER, DB_TYPE, DEFAULT_HOST, DEFAULT_PORT, fetchDatabaseNameFromURL());
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/SybaseURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/SybaseURLParser.java
new file mode 100644
index 0000000..dfc8a57
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/SybaseURLParser.java
@@ -0,0 +1,114 @@
+/*
+ * 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.skywalking.apm.plugin.jdbc.connectionurl.parser;
+
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+
+public class SybaseURLParser extends AbstractURLParser {
+    private static final int DEFAULT_PORT = 5000;
+    private static final String DB_TYPE = "Sybase";
+    private static final String JDBC_PREFIX = "jdbc:sybase:Tds:";
+
+    public SybaseURLParser(String url) {
+        super(url);
+    }
+
+    @Override
+    protected URLLocation fetchDatabaseHostsIndexRange() {
+        int hostLabelStartIndex = JDBC_PREFIX.length();
+        int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex);
+        int hostLabelEndIndexWithParameter = url.indexOf("?", hostLabelStartIndex);
+        if (hostLabelEndIndex == -1) {
+            hostLabelEndIndex = hostLabelEndIndexWithParameter;
+        }
+        if (hostLabelEndIndexWithParameter < hostLabelEndIndex && hostLabelEndIndexWithParameter != -1) {
+            hostLabelEndIndex = hostLabelEndIndexWithParameter;
+        }
+        if (hostLabelEndIndex == -1) {
+            hostLabelEndIndex = url.length();
+        }
+        return new URLLocation(hostLabelStartIndex, hostLabelEndIndex);
+    }
+
+    protected String fetchDatabaseNameFromURL(int startSize) {
+        URLLocation hostsLocation = fetchDatabaseNameIndexRange(startSize);
+        if (hostsLocation == null) {
+            return "";
+        }
+        return url.substring(hostsLocation.startIndex(), hostsLocation.endIndex());
+    }
+
+    protected URLLocation fetchDatabaseNameIndexRange(int startSize) {
+        int databaseStartTag = url.indexOf("/", startSize);
+        int parameterStartTag = url.indexOf("?", startSize);
+        if (parameterStartTag < databaseStartTag && parameterStartTag != -1) {
+            return null;
+        }
+        if (databaseStartTag == -1) {
+            return null;
+        }
+        int databaseEndTag = url.indexOf("?", databaseStartTag);
+        if (databaseEndTag == -1) {
+            databaseEndTag = url.length();
+        }
+        return new URLLocation(databaseStartTag + 1, databaseEndTag);
+    }
+
+    @Override
+    protected URLLocation fetchDatabaseNameIndexRange() {
+        int databaseStartTag = url.lastIndexOf("/");
+        int databaseEndTag = url.indexOf("?", databaseStartTag);
+        if (databaseEndTag == -1) {
+            databaseEndTag = url.length();
+        }
+        return new URLLocation(databaseStartTag + 1, databaseEndTag);
+    }
+
+    @Override
+    public ConnectionInfo parse() {
+        URLLocation location = fetchDatabaseHostsIndexRange();
+        String hosts = url.substring(location.startIndex(), location.endIndex());
+        String[] hostSegment = hosts.split(",");
+        if (hostSegment.length > 1) {
+            StringBuilder sb = new StringBuilder();
+            for (String host : hostSegment) {
+                if (host.split(":").length == 1) {
+                    sb.append(host).append(":").append(DEFAULT_PORT).append(",");
+                } else {
+                    sb.append(host).append(",");
+                }
+            }
+            return new ConnectionInfo(ComponentsDefine.SYBASE_JDBC_DRIVER, DB_TYPE, sb.substring(0, sb.length() - 1), fetchDatabaseNameFromURL());
+        } else {
+            String[] hostAndPort = hostSegment[0].split(":");
+            if (hostAndPort.length != 1) {
+                return new ConnectionInfo(
+                    ComponentsDefine.SYBASE_JDBC_DRIVER, DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]),
+                    fetchDatabaseNameFromURL(location
+                                                 .endIndex())
+                );
+            } else {
+                return new ConnectionInfo(
+                    ComponentsDefine.SYBASE_JDBC_DRIVER, DB_TYPE, hostAndPort[0], DEFAULT_PORT, fetchDatabaseNameFromURL(location
+                                                                                                                             .endIndex()));
+            }
+        }
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java
index eab319f..cb79d58 100644
--- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java
@@ -36,6 +36,11 @@
     private static final String KYLIN_JDBC_URL_PREFIX = "jdbc:kylin";
     private static final String IMPALA_JDBC_URL_PREFIX = "jdbc:impala";
     private static final String CLICKHOUSE_JDBC_URL_PREFIX = "jdbc:clickhouse";
+    private static final String DERBY_JDBC_URL_PREFIX = "jdbc:derby:";
+    private static final String SQLITE_JDBC_URL_PREFIX = "jdbc:sqlite:";
+    private static final String DB2_JDBC_URL_PREFIIX = "jdbc:db2:";
+    private static final String SYBASE_JDBC_URL_PREFIX = "jdbc:sybase:tds:";
+    private static final String OCEANBASE_JDBC_URL_PREFIX = "jdbc:oceanbase:";
 
     public static ConnectionInfo parser(String url) {
         ConnectionURLParser parser = null;
@@ -60,6 +65,16 @@
             parser = new ImpalaJdbcURLParser(url);
         } else if (lowerCaseUrl.startsWith(CLICKHOUSE_JDBC_URL_PREFIX)) {
             parser = new ClickHouseURLParser(url);
+        } else if (lowerCaseUrl.startsWith(DERBY_JDBC_URL_PREFIX)) {
+            parser = new DerbyURLParser(url);
+        } else if (lowerCaseUrl.startsWith(SQLITE_JDBC_URL_PREFIX)) {
+            parser = new SqliteURLParser(url);
+        } else if (lowerCaseUrl.startsWith(DB2_JDBC_URL_PREFIIX)) {
+            parser = new Db2URLParser(url);
+        } else if (lowerCaseUrl.startsWith(SYBASE_JDBC_URL_PREFIX)) {
+            parser = new SybaseURLParser(url);
+        } else if (lowerCaseUrl.startsWith(OCEANBASE_JDBC_URL_PREFIX)) {
+            parser = new OceanBaseURLParser(url);
         }
         return parser.parse();
     }
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java
index f679f05..48715ad 100644
--- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java
@@ -280,4 +280,139 @@
         assertThat(connectionInfo.getDatabaseName(), is("testdb"));
         assertThat(connectionInfo.getDatabasePeer(), is("[2001:db8::1234]:5432,[2001:db8::1235]:5432"));
     }
-}
+
+    @Test
+    public void testParseOceanBaseJDBCURL() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:oceanbase://localhost:2881/mydb?user=root@sys&password=pass&pool=false&useBulkStmts=true&rewriteBatchedStatements=false&useServerPrepStmts=true");
+        assertThat(connectionInfo.getDBType(), is("OceanBase"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb"));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:2881"));
+    }
+
+    @Test
+    public void testParseOceanBaseJDBCURLWithMultiHosts() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:oceanbase://primaryhost:2888,secondaryhost1,secondaryhost2/mydb?user=root@sys&password=pass&pool=false&useBulkStmts=true&rewriteBatchedStatements=false&useServerPrepStmts=true");
+        assertThat(connectionInfo.getDBType(), is("OceanBase"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb"));
+        assertThat(connectionInfo.getDatabasePeer(), is("primaryhost:2888,secondaryhost1:2881,secondaryhost2:2881"));
+    }
+
+    @Test
+    public void testParseDerbyJDBCURLWithDirMode() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:derby:directory:mydb");
+        assertThat(connectionInfo.getDBType(), is("Derby"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb"));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
+    }
+
+    @Test
+    public void testParseDerbyJDBCURLWithMemMode() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:derby:memory:mydb;create=true");
+        assertThat(connectionInfo.getDBType(), is("Derby"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb"));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
+    }
+
+    @Test
+    public void testParseDerbyJDBCURLWithClassPathMode() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:derby:classpath:/test/mydb");
+        assertThat(connectionInfo.getDBType(), is("Derby"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb"));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
+    }
+
+    @Test
+    public void testParseDerbyJDBCURLWithJarMode() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:derby:jar:(C:/dbs.jar)test/mydb");
+        assertThat(connectionInfo.getDBType(), is("Derby"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb"));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
+    }
+
+    @Test
+    public void testParseDerbyJDBCURLWithEmbeddedMode() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:derby:test/mydb;create=true");
+        assertThat(connectionInfo.getDBType(), is("Derby"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb"));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
+    }
+
+    @Test
+    public void testParseDerbyJDBCURLWithMemModeAndClientServerMode() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:derby://localhost:1527/memory:/test/mydb;create=true");
+        assertThat(connectionInfo.getDBType(), is("Derby"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb"));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:1527"));
+    }
+
+    @Test
+    public void testParseDerbyJDBCURLWithClientServerMode() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:derby://localhost:1527/mydb;create=true;user=root;password=pass");
+        assertThat(connectionInfo.getDBType(), is("Derby"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb"));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:1527"));
+    }
+
+    @Test
+    public void testParseDB2JDBCURL() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:db2://localhost:50000/mydb:user=root;password=pass");
+        assertThat(connectionInfo.getDBType(), is("DB2"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb"));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:50000"));
+    }
+
+    @Test
+    public void testParseDB2JDBCURLWithoutHost() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:db2:mydb:user=root;password=pass");
+        assertThat(connectionInfo.getDBType(), is("DB2"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb"));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:50000"));
+    }
+
+    @Test
+    public void testParseSqliteJDBCURL() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:sqlite:C/test/mydb.db");
+        assertThat(connectionInfo.getDBType(), is("Sqlite"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb.db"));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
+    }
+
+    @Test
+    public void testParseSqliteJDBCURLWithMem() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:sqlite::memory:?jdbc.explicit_readonly=true");
+        assertThat(connectionInfo.getDBType(), is("Sqlite"));
+        assertThat(connectionInfo.getDatabaseName(), is(""));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
+    }
+
+    @Test
+    public void testParseSqliteJDBCURLWithResource() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:sqlite::resource:org/test/mydb.db");
+        assertThat(connectionInfo.getDBType(), is("Sqlite"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb.db"));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
+    }
+
+    @Test
+    public void testParseSybaseJDBCURL() {
+        ConnectionInfo connectionInfo = new URLParser().parser(
+            "jdbc:sybase:Tds:localhost:5000/mydb?charset=utf-8");
+        assertThat(connectionInfo.getDBType(), is("Sybase"));
+        assertThat(connectionInfo.getDatabaseName(), is("mydb"));
+        assertThat(connectionInfo.getDatabasePeer(), is("localhost:5000"));
+    }
+}
\ No newline at end of file
diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md
index a51d267..9b21ea1 100644
--- a/docs/en/setup/service-agent/java-agent/Supported-list.md
+++ b/docs/en/setup/service-agent/java-agent/Supported-list.md
@@ -168,10 +168,27 @@
   * [Jetty](https://github.com/eclipse/jetty.project) 9.1.x -> 11.x
   * [Grizzly](https://github.com/eclipse-ee4j/grizzly) 2.3.x -> 4.x
 * Connection Pool
-  * [Apache Commons DBCP](https://github.com/apache/commons-dbcp) 2.x
-  * [Alibaba Druid](https://github.com/alibaba/druid) 1.x
-  * [HikariCP](https://github.com/brettwooldridge/HikariCP) 3.x -> 4.x
-  * [C3P0](https://github.com/swaldman/c3p0) 0.9.0 -> 0.10.0
+  * Supported JDBC drviers
+    * [MySQL](https://www.mysql.com/)
+    * [Oracle](https://www.oracle.com/)
+    * [H2](https://h2database.com/html/main.html)
+    * [PostgreSQL](https://www.postgresql.org/)
+    * [MariaDB](https://mariadb.org/)
+    * [SQL Server](https://www.microsoft.com/en-us/sql-server/)
+    * [Apache Kylin](https://kylin.apache.org/)
+    * [Impala](https://impala.apache.org/)
+    * [ClickHouse](https://clickhouse.com/)
+    * [Derby](https://db.apache.org/derby/)
+    * [SQLite](https://www.sqlite.org/index.html)
+    * [DB2](https://www.ibm.com/products/db2/database)
+    * Sybase
+    * [OceanBase](https://www.oceanbase.com/)
+  * Supported Connection Pool Frameworks
+    * [Apache Commons DBCP](https://github.com/apache/commons-dbcp) 2.x
+    * [Alibaba Druid](https://github.com/alibaba/druid) 1.x
+    * [HikariCP](https://github.com/brettwooldridge/HikariCP) 3.x -> 4.x    
+    * [C3P0](https://github.com/swaldman/c3p0) 0.9.0 -> 0.10.0
+  
 ___
 ¹Due to license incompatibilities/restrictions these plugins are hosted and released in 3rd part repository,
  go to [SkyAPM java plugin extension repository](https://github.com/SkyAPM/java-plugin-extensions) to get these.