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

yfjy0ee7  于 2022-11-10  发布在  Maven
关注(0)|答案(3)|浏览(204)

我正在尝试建立连接到一个数据库。这是一个简单的项目与使用maven。
我遇到sqljdbc_auth.dll问题
我添加了mssql jdbc驱动程序,并在pom.xml中添加了依赖项

<dependency>
    <groupId>com.microsoft</groupId>
    <artifactId>mssql-jdbc</artifactId>
    <version>4.0.0</version>
</dependency>

这是我的try区块

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]
mznpcxlj

mznpcxlj1#

我不认为你需要在这里使用maven-helper-plugin。这里的文档说你要么需要 * 安装 * dll,要么在系统变量java.library.path中指定它的路径。
请访问http://msdn.microsoft.com/en-us/library/ms378428.aspx#Connectingintegrated
UPDATE:确保dll与您的jar沿着分发。如果您使用的是maven,请将dll文件放在src/main/resources文件夹中。然后通过将dll从包中排除来确保dll最终位于jar之外。按照类似于here所述的步骤操作。在此之后,您应该将dll与您构建的jar文件放在target目录中
然后,当您运行应用程序时,将系统属性作为命令行参数java -Djava.library.path=.传递。
如果您不想通过命令行传递参数--您可以使用System.getProperty("user.dir"))提取当前工作目录,并按照here所述的步骤在main方法中以编程方式将java.library.path设置为当前目录

nnsrf1az

nnsrf1az2#

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

y0u0uwnf

y0u0uwnf3#

将dll直接放在与主jar相同的级别上就足够了。我怀疑你的问题与dll的x64和x86版本有关。你确定你的版本一致吗?
我正在使用此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位项目,它工作得很好

相关问题