多个 JDBC 驱动程序的正确 DuplicateStrategy 是什么?
What is the correct DuplicateStrategy for multiple JDBC drivers?
我的项目中有以下build.gradle
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'com.oracle.database.jdbc:ojdbc11-production:21.3.0.0'
implementation 'com.microsoft.sqlserver:mssql-jdbc:9.4.0.jre8'
}
tasks.named('jar') {
setDuplicatesStrategy(DuplicatesStrategy.WARN)
manifest {
attributes 'Main-Class': 'com.example.App'
}
from {
configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
文件 META-INF/services/java.sql.Driver
存在于两个导入的 jar 中。实际上这个 Oracle JDBC 依赖项导入了多个 jar,它们之间有更多冲突文件(内容不同)(例如 META-INF/native-image/native-image.properties
和这个目录中的其他文件)。
当 DuplicatesStrategy 设置为 WARN 时,Oracle 驱动程序会覆盖 SQL 服务器 JDBC 驱动程序的 META-INF/services/java.sql.Driver
。这个(和其他)文件被覆盖的后果是什么?
我该如何处理这些重复的文件?有没有办法从所有罐子里获取所有文件? jar 的某些文件被覆盖的机会让我感到不安。
文件冲突是否常见?
考虑不构建 fatjar。否则,您需要将 META-INF/services/java.sql.Driver
从各种驱动程序合并到一个文件中(自动或提供您自己的文件)。如果您不合并,自动驱动程序加载将不会对未包含其服务定义文件的驱动程序起作用。如果您不能或不想合并(或提供您自己的版本),您将需要求助于使用 Class.forName
显式加载驱动程序。另见 How is driver class located in JDBC4。
至于使用DuplicateStrategy
,最好使用FAIL
并明确排除文件或位置,或者想出一个合并它们的策略,但这可能很麻烦。
至于其他文件,我无法真正回答,但 META-INF/native-image/*
似乎与在 GraalVM 中使用该库有关,因此除非您使用它,否则您可以安全地忽略该目录中的文件.
但是,如果这真的让您担心,或者您不知道文件的作用,更好的选择是不使用 fatjars (a.k.a uberjars),而是使用能够正确生成的部署方式class-路径(例如使用清单或启动器文件)并将应用程序使用的各种库分开。例如,参见 Add classpath in manifest using Gradle。
我的项目中有以下build.gradle
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'com.oracle.database.jdbc:ojdbc11-production:21.3.0.0'
implementation 'com.microsoft.sqlserver:mssql-jdbc:9.4.0.jre8'
}
tasks.named('jar') {
setDuplicatesStrategy(DuplicatesStrategy.WARN)
manifest {
attributes 'Main-Class': 'com.example.App'
}
from {
configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
文件 META-INF/services/java.sql.Driver
存在于两个导入的 jar 中。实际上这个 Oracle JDBC 依赖项导入了多个 jar,它们之间有更多冲突文件(内容不同)(例如 META-INF/native-image/native-image.properties
和这个目录中的其他文件)。
当 DuplicatesStrategy 设置为 WARN 时,Oracle 驱动程序会覆盖 SQL 服务器 JDBC 驱动程序的 META-INF/services/java.sql.Driver
。这个(和其他)文件被覆盖的后果是什么?
我该如何处理这些重复的文件?有没有办法从所有罐子里获取所有文件? jar 的某些文件被覆盖的机会让我感到不安。
文件冲突是否常见?
考虑不构建 fatjar。否则,您需要将 META-INF/services/java.sql.Driver
从各种驱动程序合并到一个文件中(自动或提供您自己的文件)。如果您不合并,自动驱动程序加载将不会对未包含其服务定义文件的驱动程序起作用。如果您不能或不想合并(或提供您自己的版本),您将需要求助于使用 Class.forName
显式加载驱动程序。另见 How is driver class located in JDBC4。
至于使用DuplicateStrategy
,最好使用FAIL
并明确排除文件或位置,或者想出一个合并它们的策略,但这可能很麻烦。
至于其他文件,我无法真正回答,但 META-INF/native-image/*
似乎与在 GraalVM 中使用该库有关,因此除非您使用它,否则您可以安全地忽略该目录中的文件.
但是,如果这真的让您担心,或者您不知道文件的作用,更好的选择是不使用 fatjars (a.k.a uberjars),而是使用能够正确生成的部署方式class-路径(例如使用清单或启动器文件)并将应用程序使用的各种库分开。例如,参见 Add classpath in manifest using Gradle。