【问题标题】:How to add sqljdbc_auth.dll to my maven project如何将 sqljdbc_auth.dll 添加到我的 maven 项目中
【发布时间】:2012-11-09 19:39:03
【问题描述】:

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

我在构建时遇到另一个错误

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]

【问题讨论】:

  • 您打算如何使用您的应用程序,是 webapp 还是独立部署?
  • 显然你不能在你的jar中添加dll,如果可能的话,它会首先进入jdbc jar本身,为你省去所有的麻烦。我们可能有一个解决方案,具体取决于您打算如何使用您的应用
  • 不是网络。但是我不能说它是独立的,因为我不明白它的意思)
  • 我的意思是说你是如何开始你的程序的。像java MyClassmvn exec:java ... 或在一些网络容器中。以及如何分发您的项目,作为 jar 分发?
  • 现在我在 netbeans ide 中启动 java myclass。但将来我会有很多模块

标签: java sql-server maven netbeans jdbc


【解决方案1】:

我认为您不需要在这里使用maven-helper-plugin。 这里的文档说您需要安装 dll 或在系统变量java.library.path 中指定其路径。

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

更新: 确保 dll 与您的 jar 一起分发。如果您使用的是 Maven, 将 dll 文件放在 src/main/resources 文件夹中。然后通过将其从包中排除来确保 dll 最终在 jar 之外。遵循类似于here 概述的步骤。在此之后,您应该在target 目录中拥有您的 dll 以及您构建的 jar 文件

然后,当您运行应用程序时,将系统属性作为命令行参数 java -Djava.library.path=.

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

【讨论】:

  • 不不不。我知道。但它将是本地的。但我需要将其添加到项目中
【解决方案2】:

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

我已经在生产环境中运行了几年,在 Java

这是我的做法:

  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 :
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

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 运行您的代码

  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,然后使用上述代码的变体将其强制到库路径中。

【讨论】:

    【解决方案3】:

    将 dll 直接放在与主 jar 相同的级别就足够了。 我怀疑您的问题与 dll 的 x64 和 x86 版本有关。 你确定你的版本是一致的吗?

    我正在使用这个部门:

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

    【讨论】:

      猜你喜欢
      • 2013-01-18
      • 1970-01-01
      • 2011-08-28
      • 2021-09-02
      • 1970-01-01
      • 2019-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多