2017-01-20 2 views
0

Я новичок в Java и столкнулся с проблемой, которая меня смутила. У меня есть приложение MyApp, которое я написал в IntelliJ. Приложение использует внешнюю библиотеку MyLib.jar, которая ведет переговоры с базой данных, используя sqljdbc42.jar от Microsoft. MyLib.jar и sqljdbc.jar установлены как внешние библиотеки в IntelliJ.Java как jar не может найти классы в sublibrary

Проблема у меня в том, что мое приложение работает отлично, когда я запускаю его в среде IDE, но когда я использую Generate Artifact для создания jar, ошибки jar возникают при попытке подключиться к базе данных.

Ошибка: class java.lang.ClassNotFoundException | com.microsoft.sqlserver.jdbc.SQLServerDriver

Это класс в sqljdbc42.jar. Я предполагаю, что это означает, что MyApp.jar не может видеть классы в sqljdbc42.jar.

sqljdbc42.jar не может быть включен в MyApp.jar из-за способа его подписания. Вместо этого, у меня есть файл в той же папке, MyApp.jar, и это мой MANIFEST.MF:

Manifest-Version: 1.0 
Class-Path: sqljdbc42.jar 
Main-Class: com.mycompany.myapp.Main 

И это файл макета:

- MyApp_jar/ 
    - sqljdbc42.jar 
    - MyApp.jar 

Я другое приложение настройки так же, насколько я могу судить, и что .jar отлично работает с использованием того же класса.

UPDATE - Файл .jar, который я пытаюсь включить, является подписанной банкой. Любой другой файл jar, который я пытаюсь включить, работает отлично. Вот пример приложения для тестирования:

import com.microsoft.sqlserver.jdbc.SQLServerDriver; 
public class Main 
{ 
public static void main(String[] args) 
{ 
    try { 
     System.out.println(SQLServerDriver.class); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 
} 

И это баночка я не могу заставить работать: https://www.microsoft.com/en-us/download/details.aspx?id=11774 (4,2 версия)

+0

очевидно, что все правильно. Вы проверили содержимое MANIFEST.MF, которое включено в JAR? Я имею в виду, откройте JAR с помощью WinZip или аналогичного (команда jar также сделает) и извлеките файл MANIFEST.MF, чтобы увидеть его содержимое. https://docs.oracle.com/javase/tutorial/deployment/jar/view.html –

+0

Да, содержимое файла META-INF/MANIFEST.MF соответствует указанному выше. – Wige

ответ

0

Запустить файл банку, а не класс:

java -jar MyApp.jar

и он должен добавить sqljdbc42.jar в путь к классам.

+0

Да. Это команда, которую я запускаю, и которая вызывает упомянутое сообщение об ошибке. – Wige

+0

@Wige Вы запускаете его из каталога, содержащего оба файла Jar? – SubOptimal

+0

Да, я запускаю его из папки MyApp_jar. – Wige

0

Я загрузил архив sqljdbc_4.2.6420.100_enu.tar.gz с вашего адреса и извлек sqljdbc42.jar.

следующие шаги работают, как и ожидалось

Main.java

package com.mycompany.myapp; 
import com.microsoft.sqlserver.jdbc.SQLServerDriver; 
public class Main { 
    public static void main(String[] args) { 
     System.out.println(SQLServerDriver.class); 
    } 
} 

Manifest.mf

Manifest-Version: 1.0 
Class-Path: sqljdbc42.jar 
Main-Class: com.mycompany.myapp.Main 

файлы в текущем каталоге

Main.java 
manifest.mf 
sqljdbc42.jar 

компилировать

javac -d . -cp sqljdbc42.jar Main.java 

который создает файл класса .\com\mycompany\myapp\Main.class.

создать Jar

jar vcmf manifest.mf MyApp.jar com/ 

выход

added manifest 
adding: com/(in = 0) (out= 0)(stored 0%) 
adding: com/mycompany/(in = 0) (out= 0)(stored 0%) 
adding: com/mycompany/myapp/(in = 0) (out= 0)(stored 0%) 
adding: com/mycompany/myapp/Main.class(in = 466) (out= 321)(deflated 31%) 

запустить JAR

java -jar MyApp.jar 

выход

class com.microsoft.sqlserver.jdbc.SQLServerDriver 
+0

Yargh. Он работает и для меня, когда создаю банку из командной строки. Единственное различие, которое я мог видеть, это когда я создал его из командной строки, в манифесте добавилась эта строка: «Создано: 1.8.0_102 (Oracle Corporation)» Если я удалю эту строку, произойдет ошибка. Эта строка не добавляется при создании банки с IntelliJ. Кажется, это проблема исключительно с этой библиотекой? (Я могу включить другие баночки просто отлично без этой строки.) – Wige

+0

@Wige Вы имеете в виду, когда вы создаете 'MyApp.jar' с тем же' Main.class' с IntelliJ, тогда 'java -jar MyApp.jar' не работает (предполагая, что MyApp.jar и sqljdbc42.jar находятся в одном каталоге). Если да, не могли бы вы опубликовать вывод 'jar -tvf MyApp.jar'. – SubOptimal

Смежные вопросы