Исполняемый Jar с зависимостью от DLL

Я пытаюсь развернуть приложение Swing, которое использует DLL для облегчения соединения с базой данных (используя jar sqljdbc4, который зависит от sqljdbc_auth.dll). Моя стратегия развертывания заключается в создании исполняемого файла JAR. Проблема в том, что я не могу заставить функции, которые полагаются на sqljdbc_auth.dll, работать в исполняемом фляге, которую я создаю.

Я могу получить проект, работающий отлично в затмении, используя любой из следующих методов:

  1. Ссылка на папку, содержащую dll, в конфигурации пути сборки, указав расположение собственной библиотеки в папке Source.
  2. Поместите dll в каталог C:\Windows\System32
  3. Добавьте следующий аргумент VM, ссылающийся на относительный путь к папке dll в моем проекте "-Djava.library.path=path/to/dllfolder"

Четвёртый метод, который я попробовал, это загрузить 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 для использования при установлении соединения.

В любом случае, я не могу заставить что-либо из перечисленных выше методов работать при развертывании приложения в виде исполняемого файла JAR с помощью функции экспорта eclipse. Единственное, что я могу получить, это упомянутое ранее сообщение об ошибке.

Следующий пример приложения дает тот же результат.

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 или нет, я просто хочу, чтобы он работал!

1 ответ

Решение

Я бы предположил, что это как-то связано с помещением DLL в вашу библиотеку

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

Когда вы экспортируете банку, у вас также будет возможность экспортировать файлы библиотеки в папку.

Если после этого вы декомпилируете Jar, вы заметите, что есть файл манифеста и в нем пути к файлам вашей библиотеки (на основе экспорта, который создал для вас папку библиотеки, обычно jarname_lib).

При экспорте у вас есть возможность сохранить как файл ANT, который затем можно отредактировать, чтобы изменить место экспорта файлов библиотеки на имя папки по вашему выбору. Затем вы можете добавить этот отредактированный ANT-файл в вашу сборку, чтобы это происходило при каждой сборке проекта:

(In Eclipse, Properties->Builders->New)
Другие вопросы по тегам