我有以下构建。Gradle in my project
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 Server JDBC驱动的META-INF/services/java.sql.Driver
。这个(和其他)文件被覆盖的后果是什么?
文件冲突是否常见?
考虑不要构建fatjar。否则,您将需要将不同驱动程序中的META-INF/services/java.sql.Driver
合并到一个文件中(可以自动合并,也可以提供您自己的文件)。如果不合并,自动驱动程序加载将无法为未包含服务定义文件的驱动程序工作。如果不能或不想合并(或提供自己的版本),则需要使用Class.forName
显式加载驱动程序。参见驱动程序类如何位于JDBC4中。
至于要使用的DuplicateStrategy
,可能最好使用FAIL
并显式地排除文件或位置,或者提出合并它们的策略,但这可能很麻烦。
至于其他文件,我不能真正回答,但META-INF/native-image/*
似乎与使用GraalVM中的库有关,所以除非你使用它,否则你可能可以安全地忽略该目录中的文件。
然而,如果你真的关心这个,或者你不知道文件做什么,更好的选择是不使用fatjar(又名uberjar),而是使用一种正确生成类路径的部署方式(例如使用清单,或启动器文件),并将应用程序使用的各种库分开。例如,参见使用Gradle在manifest中添加类路径。