如何将sqljdbc_auth.dll添加到我的maven项目中

时间:2012-11-21 14:16:59

标签: java sql-server maven netbeans jdbc

我正在尝试建立与数据库的连接。这是一个使用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:

我有sqljdbc_auth.dll,但我不需要将它放到我的C:\windows\... 我需要在maven的项目中添加它。我怎么能这样做?

我尝试将其添加到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>
    </plugins>

构建

时出现了另一个错误
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]

3 个答案:

答案 0 :(得分:0)

我认为你不需要在这里使用maven-helper-plugin。 这里的doc说你要么安装 dll,要么在系统变量java.library.path中指定它的路径。

看看 http://msdn.microsoft.com/en-us/library/ms378428.aspx#Connectingintegrated

更新: 确保dll与jar一起分发。如果你正在使用maven, 将dll文件放在src / main / resources文件夹中。然后确保dll通过从包装中排除而最终到达罐子外面。按照类似于here概述的步骤进行操作。在此之后,您应该将您的dll与您在target目录

中构建的jar文件一起使用

然后当您运行app pass系统属性作为命令行参数java -Djava.library.path=.时。

如果您不想通过命令行传递参数,则可以使用System.getProperty("user.dir"))提取当前工作目录,并按照here所述的步骤以编程方式将java.library.path设置为当前目录您的main方法

答案 1 :(得分:0)

根据在 this answer 中找到的信息,您可以通过在运行时将 dll 注入 java.library.path 来实现。

我已经在生产环境中运行了几年,在 Java <= 8 上没有问题。不过从来没有真正用于较新的版本。快速测试适用于 Java 11,而非 Java 15

这是我的做法:

  1. 将 dll 存储在您的应用程序路径中。例如:
project_root
├─src (or any other source path structure)
│ └─...packages...
└─extlib
  └─SqlJdbc
    └─auth
      ├─x64
      │ └─sqljdbc_auth.dll
      └─x86
        └─sqljdbc_auth.dll
  1. 在创建 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);
    }
}

根据 this answer,您应该能够使用 MethodHandles.privateLookupIn 而不是 ClassLoader.class.getDeclaredField 将其推送到至少 Java <= 13。例如:

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 中肯定被破坏了,因为 usr_paths 中的字段 ClassLoader 不再存在

此时,您应该可以从 IDE 运行代码

  1. 在您的 jar 旁边部署包含 dll(即 extlib)的目录。对于 Maven,您可以在 pom.xml 中使用以下内容:
<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 中,您可以使用 maven-resources-plugin 执行此操作,并在运行时解压所需的 dll,然后使用上述代码的变体将其强制添加到库路径中。

答案 2 :(得分:0)

将 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 位项目,它工作正常