Java 依赖于dll的可执行Jar

Java 依赖于dll的可执行Jar,java,eclipse,dll,executable-jar,sqljdbc,Java,Eclipse,Dll,Executable Jar,Sqljdbc,我试图部署一个swing应用程序,它使用dll来促进数据库连接(使用依赖于sqljdbc_auth.dll的sqljdbc4 jar)。我的部署策略是创建一个可执行的jar文件。问题是我无法让依赖sqljdbc_auth.dll的函数在我创建的可执行jar中工作 通过使用以下任何一种方法,我可以在eclipse中使项目正常工作: 通过在源文件夹上指定本机库位置,在生成路径配置中引用包含dll的文件夹 将dll放在C:\Windows\System32目录中 添加以下VM参数,引用我的项目中dll

我试图部署一个swing应用程序,它使用dll来促进数据库连接(使用依赖于sqljdbc_auth.dll的sqljdbc4 jar)。我的部署策略是创建一个可执行的jar文件。问题是我无法让依赖sqljdbc_auth.dll的函数在我创建的可执行jar中工作

通过使用以下任何一种方法,我可以在eclipse中使项目正常工作:

  • 通过在源文件夹上指定本机库位置,在生成路径配置中引用包含dll的文件夹
  • 将dll放在C:\Windows\System32目录中
  • 添加以下VM参数,引用我的项目中dll文件夹的相对路径“-Djava.library.path=path/to/dllfolder”
  • 我尝试过的第四种方法是通过以下行直接在代码中加载dll<代码>系统.load(“C:/Users/Me/Desktop/sqljdbc_auth.dll”) 我使用此方法失败,并出现以下错误

    2015年3月20日下午4:18:44 com.microsoft.sqlserver.jdbc.AuthenticationJNI
    警告:未能加载sqljdbc_auth.dll原因:java.library.path中没有sqljdbc_auth

    但是,该错误并非直接来自加载库的代码行,它似乎是在sqljdbc库尝试加载dll以用于建立连接时出现的

    无论哪种方式,当我通过eclipse的导出功能将应用程序部署为可执行jar文件时,我都无法使上述任何方法起作用。我唯一能得到的就是前面提到的错误消息

    下面的示例应用程序产生相同的结果

    public class TestApp {
    public static void main(String[] args){
    
            SwingUtilities.invokeLater(new Runnable(){
                public void run(){
                    JFrame mainFrame = new JFrame();
                    mainFrame.setSize(300,300);
                    mainFrame.setLocationRelativeTo(null);
                    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    mainFrame.setVisible(true);
    
                try{
                    //System.load("C:/Users/Me/Desktop/sqljdbc_auth.dll");
                    String serverName = "local";
                    String databaseName = "test_database";
                    String connString = "jdbc:sqlserver://" + serverName + "; databaseName=" + databaseName + ";integratedSecurity=true";
    
                    Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
                    Connection  conn = DriverManager.getConnection(connString);
                    Statement st = conn.createStatement();
                    ResultSet rs = st.executeQuery("select distinct name from test_table");
                    rs.next();
    
                    JOptionPane.showMessageDialog(null, "From db: " + rs.getString(1), "Test", JOptionPane.INFORMATION_MESSAGE);
    
                } catch (SQLException e) {
                    e.printStackTrace();
                    JOptionPane.showMessageDialog(null, e.getMessage(), "Test", JOptionPane.INFORMATION_MESSAGE);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                    JOptionPane.showMessageDialog(null, e.getMessage(), "Test", JOptionPane.INFORMATION_MESSAGE);
                } catch (Exception e){
                    e.printStackTrace();
                    JOptionPane.showMessageDialog(null, e.getMessage(), "Test", JOptionPane.INFORMATION_MESSAGE);
                }
            }
        });     
    }
    
    }


    我读过很多关于使用DLL和可执行JAR的文章,它们似乎都引用了使用System.load方法。具有讽刺意味的是,这是我唯一不能做的事情。我知道我有正确的dll;但是,因为我可以在IDE环境中使用其他方法。我不在乎dll是否与可执行jar打包,我只想让它工作

    我认为这与将dll放入您的库有关

    (In Eclipse, Properties->Java Build Path->Libraries).
    
    导出jar时,还可以选择将库文件导出到文件夹中

    如果在此之后反编译Jar,您会注意到有一个清单文件,其中有指向库文件所在位置的路径(基于导出,导出为您创建了一个库文件夹,通常是jarname_lib)

    导出时,您可以选择另存为ANT文件,然后可以对其进行编辑以将库文件的导出位置更改为您选择的文件夹名称。然后,您可以将此已编辑的ANT文件添加到生成中,以便在生成项目时执行此操作:

    (In Eclipse, Properties->Builders->New)
    

    谢谢你的建议。我在Java构建路径中添加了dll文件夹位置(尝试了外部文件夹和项目中的文件夹)作为本机库位置(这是唯一一种不出现构建错误的方法)。这在eclipse中运行良好,但在导出项目时仍然不起作用。我还保存了一个ANT文件,但它只导出了jar库,而不是dll。因此,我不知道将dll放在何处,也不知道如何尝试引用它们的位置。在ANT文件的
    标记中,我假设dll应该位于类路径中,就像JAR一样。所以,就像这样:
    。在这种情况下,如果主jar位于
    C://
    中,则会将库文件导出到
    C:/my_lib
    至于导出dll和jar,它看起来像是
    使它工作了。自定义清单允许我移动一些以前无法移动的切换。作为其他可能有问题的人的参考,我发现如果你不想弄乱清单,你也可以把dll放在java安装的bin文件夹中,因为它是默认的库位置。你能解释一下你是怎么做到的吗?