对dll具有依赖性的可执行jar

时间:2015-03-20 22:43:14

标签: java eclipse dll executable-jar sqljdbc

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

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

  1. 通过在源文件夹
  2. 上指定本机库位置,在构建路径配置中引用包含dll的文件夹
  3. 将dll放在C:\ Windows \ System32目录
  4. 添加以下VM参数,引用项目中的dll文件夹的相对路径" -Djava.library.path = path / to / dllfolder"
  5. 我尝试的第四种方法是通过以下行直接在代码中加载dll。 System.load("C:/Users/Me/Desktop/sqljdbc_auth.dll"); 我没有成功使用这种方法并得到以下错误。

    Mar 20, 2015 4:18:44 PM com.microsoft.sqlserver.jdbc.AuthenticationJNI <clinit> WARNING: Failed to load the sqljdbc_auth.dll cause : no sqljdbc_auth in java.library.path

    但是,该错误并非直接来自加载库的代码行,当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);
                }
            }
        });     
    }
    

    }

    我已经阅读了大量关于使用带可执行jar的dll的帖子,他们似乎都使用这个System.load方法引用。具有讽刺意味的是,这是我无法开展工作的一件事。我知道我有正确的dll;但是,因为我可以在IDE环境中使用其他方法。如果dll与可执行jar包装在一起,我不在乎,我只是想让它工作!

1 个答案:

答案 0 :(得分:0)

我认为这与将dll放入你的库

有关
(In Eclipse, Properties->Java Build Path->Libraries).

导出jar时,您还可以选择将库文件导出到文件夹中。

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

导出时,您可以选择保存为ANT文件,然后可以编辑该文件以将库文件的导出位置更改为您选择的文件夹名称。然后,您可以将此编辑的ANT文件添加到构建中,以便在构建项目时发生:

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