连接数据库时出现PatternSyntaxException (Kotlin)

问题描述 投票:0回答:1

我想访问网络内服务器上的 MariaDB 数据库。
为此,我在我的 kotlin 项目中设置了一个 JDBC 连接器。
(我正在使用 Android Studio 开发 Android 应用程序)。

这是我到目前为止的代码:

class Database {

    fun connect(){
            val jdbcDriver = "org.mariadb.jdbc.Driver"
            val jdbcURL = "jdbc:mariadb://192.168.178.66:3306/test"

            Class.forName(jdbcDriver)

            val password = "CDhkv7AD/OkRDrgv"

            val connection = DriverManager.getConnection(jdbcURL, "test", password)
    }
}

但是当尝试连接时,以下行会抛出以下异常:

val connection = DriverManager.getConnection(jdbcURL, "test", password)
java.lang.ExceptionInInitializerError
    at org.mariadb.jdbc.Driver.connect(Driver.java:70)
    at org.mariadb.jdbc.Driver.connect(Driver.java:95)
    at org.mariadb.jdbc.Driver.connect(Driver.java:26)
    at java.sql.DriverManager.getConnection(DriverManager.java:580)
    at java.sql.DriverManager.getConnection(DriverManager.java:218)
    at de.krabimannbardo.test.Database.connect(Database.kt:22)
    at de.krabimannbardo.test.MainActivity$onCreate$1.invokeSuspend(MainActivity.kt:28)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
    at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
    Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@6c8e0ec, Dispatchers.IO]
Caused by: java.util.regex.PatternSyntaxException: Syntax error in regexp pattern near index 185
^(\s*\{)?\s*((\?\s*=)?(\s*/\*([^*]|\*[^/])*\*/)*\s*call(\s*/\*([^*]|\*[^/])*\*/)*\s*((((`[^`]+`)|([^`}]+))\.)?((`[^`]+`)|([^`}(]+)))\s*(\(.*\))?(\s*/\*([^*]|\*[^/])*\*/)*\s*(#.*)?)\s*(}\s*)?$
^
    at com.android.icu.util.regex.PatternNative.compileImpl(Native Method)
    at com.android.icu.util.regex.PatternNative.<init>(PatternNative.java:53)
    at com.android.icu.util.regex.PatternNative.create(PatternNative.java:49)
    at java.util.regex.Pattern.compile(Pattern.java:3527)
    at java.util.regex.Pattern.<init>(Pattern.java:1413)
    at java.util.regex.Pattern.compile(Pattern.java:941)
    at org.mariadb.jdbc.Connection.<clinit>(Connection.java:32)
    ... 15 more

当我尝试使用其他密码或用户名连接时,我的访问被成功拒绝。
我认为这验证了与数据库的连接已成功建立,因为我仅在使用正确的登录信息时才会收到上述异常。 (或者这个假设是错误的?)

您知道为什么会发生 PatternSyntaxException 吗?
预先感谢。

java database kotlin jdbc mariadb
1个回答
0
投票

我在https://github.com/mariadb-corporation/mariadb-connector-j检查了MariaDB JDBC驱动程序的源代码,似乎类中的静态变量

org.mariadb.jdbc.Connection
是用正则表达式初始化的
Pattern 
.

^(\s*\{)?\s*((\?\s*=)?(\s*/\*([^*]|\*[^/])*\*/)*\s*call(\s*/\*([^*]|\*[^/])*\*/)*\s*((((`[^`]+`)|([^`}]+))\.)?((`[^`]+`)|([^`}(]+)))\s*(\(.*\))?(\s*/\*([^*]|\*[^/])*\*/)*\s*(#.*)?)\s*(}\s*)?$

堆栈跟踪中提到的索引 185 是未转义的

}
,其含义与该字符完全匹配。 (这是该字符串的最后一个
}
,因此从末尾开始搜索。)

对于其他 SO 帖子,例如 Android 上的 java.util.regex.PatternSyntaxException Regex 模式 SyntaxException 与 Android 上包含右花括号的正则表达式相关,解决方案都包括使用反斜杠来转义

\ 
.

我还在Android官方文档中发现了一个声明,右大括号必须被转义:

从 API 级别 10 (Android 2.3) 开始的行为

从Android 2.3 Gingerbread开始,ICU4C成为正则表达式实现的后端。与其他正则表达式实现相比,Android 的行为可能有所不同,例如在 Android 上必须对文字右大括号 ('}') 进行转义。

文字右大括号的转义在“桌面 Java”中没有区别,无论有或没有转义,它的行为都相似。

因此您发现 MariaDB JDBC 驱动程序与 Android 不兼容。您可以尝试向他们报告问题,或者尝试自己修复驱动程序(您将在堆栈跟踪中找到要查找的位置),或者最好尝试并行执行这两个操作:在开源项目中提出修复方案同时使用您自己更新的驱动程序。

顺便说一句,您是对的,此错误仅在加载 Connection 类时对服务器进行第一次

成功
身份验证后才会发生。

© www.soinside.com 2019 - 2024. All rights reserved.