提问人:Kadymov Mukhammed 提问时间:11/21/2012 最后编辑:EricSchaeferKadymov Mukhammed 更新时间:11/15/2023 访问量:12517
如何将sqljdbc_auth.dll添加到我的 maven 项目中
How to add sqljdbc_auth.dll to my maven project
问:
我正在尝试建立与数据库的连接。这是一个使用 maven 的简单项目。
我有问题sqljdbc_auth.dll
我添加了mssql jdbc驱动程序,并在pom.xml
<dependency>
<groupId>com.microsoft</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>4.0.0</version>
</dependency>
这是我的尝试块
try {
// Establish the connection.
SQLServerDataSource ds = new SQLServerDataSource();
ds.setIntegratedSecurity(true);
ds.setServerName("BUILDSRV");
ds.setDatabaseName("master");
ds.setIntegratedSecurity(true);
con = ds.getConnection();
}
我收到这个错误
21.11.2012 18:07:04 com.microsoft.sqlserver.jdbc.AuthenticationJNI <clinit>
WARNING: Failed to load the sqljdbc_auth.dll cause :- no sqljdbc_auth in java.library.path
com.microsoft.sqlserver.jdbc.SQLServerException:
我有我的,但我不需要把它放在我的项目中,我需要从 maven 将其添加到我的项目中。我该怎么做?sqljdbc_auth.dll
C:\windows\...
我试图将其添加到中,但它不起作用pom.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>attach-artifacts</id>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<file>target</file>
<type>dll</type>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
我在构建时又遇到了另一个错误
Failed to execute goal org.codehaus.mojo:build-helper-maven-plugin:1.1:attach-artifact (attach-artifacts) on project mavenproject1dbconnect: Unable to parse configuration of mojo org.codehaus.mojo:build-helper-maven-plugin:1.1:attach-artifact for parameter file: Cannot configure instance of org.codehaus.mojo.buildhelper.Artifact from target -> [Help 1]
答:
我认为你不需要在这里使用。
这里的文档说你要么需要安装dll,要么在系统变量中指定其路径。maven-helper-plugin
java.library.path
看看 http://msdn.microsoft.com/en-us/library/ms378428.aspx#Connectingintegrated
更新:
确保 DLL 与 JAR 一起分发。如果您使用的是 maven,
将 dll 文件放在 src/main/resources 文件夹中。然后,通过将 dll 从包中排除,确保它最终出现在 jar 之外。按照与此处概述的步骤类似的步骤操作。在此之后,您应该将 dll 和构建的 jar 文件放在目录中target
然后,当您运行应用程序时,将系统属性作为命令行参数传递。java -Djava.library.path=.
如果您不想费心通过命令行传递参数 -- 您可以使用并按照此处所述的步骤提取当前工作目录,以编程方式在方法中将当前目录设置为当前目录System.getProperty("user.dir"))
java.library.path
main
评论
根据此答案中的信息,您可以通过在运行时将 dll 注入来执行此操作。java.library.path
我已经在生产环境中运行了几年,在 Java <= 8 上没有问题。不过,从未真正与较新的版本一起使用过。快速测试适用于 Java 11,而不是 Java 15
我是这样做的:
- 将 dll 存储在应用程序路径中。例如:
project_root
├─src (or any other source path structure)
│ └─...packages...
└─extlib
└─SqlJdbc
└─auth
├─x64
│ └─sqljdbc_auth.dll
└─x86
└─sqljdbc_auth.dll
- 在建立 JDBC 连接的类中使用以下静态初始化代码(java <= 11 版本):
static {
File file;
if ("64".equals(System.getProperty("sun.arch.data.model")))
file = new File("./extlib/SqlJdbc/auth/x64");
else
file = new File("./extlib/SqlJdbc/auth/x86");
String dllPath;
try {
dllPath = file.getCanonicalPath();
synchronized(Runtime.getRuntime()) {
final Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths");
usrPathsField.setAccessible(true);
Object o = usrPathsField.get(null);
String[] paths = o == null ? new String[0] : (String[]) o;
if (!Arrays.stream(paths).anyMatch(s -> dllPath.equals(s))) {
String[] usr_paths = Arrays.copyOf(paths, paths.length + 1);
usr_paths[paths.length] = file.getCanonicalPath();
usrPathsField.set(null, usr_paths);
}
}
DriverManager.registerDriver(new SQLServerDriver());
} catch (Exception e) {
e.printStackTrace();
throw new ExceptionInInitializerError(e);
}
}
根据这个答案,您应该能够将其推送到至少 Java <= 13 使用 而不是 .例如:MethodHandles.privateLookupIn
ClassLoader.class.getDeclaredField
Lookup cl = MethodHandles.privateLookupIn(ClassLoader.class, MethodHandles.lookup());
VarHandle usrPathsField= cl.findStaticVarHandle(ClassLoader.class, "usr_paths", String[].class);
Object o = usrPathsField.get();
...
usrPathsField.set(usr_paths);
Java 15 肯定打破了它,因为 ClassLoader
中不再存在字段 usr_paths
此时,您应该能够从 IDE 运行代码
- 将包含 dll(即 )的目录与 jar 一起部署。对于 Maven,您可以在 pom.xml 中使用以下内容:
extlib
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/extlib</outputDirectory>
<resources>
<resource>
<directory>extlib</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
从那里,如果需要将 dll 打包在 jar 中,可以使用 执行此操作,并在运行时解压缩所需的 dll,然后使用上述代码的变体将其强制到库路径上。maven-resources-plugin
将 dll 直接放在与主 jar 相同的水平上应该就足够了。 我怀疑您的问题与 x64 与 x86 版本的 dll 有关。 你确定你的版本一致吗?
我正在使用这个 dep:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.1.1.jre8-preview</version>
</dependency>
还有 dll:
mssql-jdbc_auth-9.1.1.x64-preview.dll
对于我的 64 位项目,它工作正常
评论
java MyClass
mvn exec:java ...