ClassNotFoundException при запуске JAR, нет ошибок во время работы в IntelliJ IDEA
Я только начинаю создавать Java-приложения (у меня есть опыт .NET), и я пытался создать небольшое тестовое приложение, весь код которого таков :
package com.company;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) throws SQLException {
System.out.println("Buna lume!");
SQLServerDataSource ds = new SQLServerDataSource();
ds.setIntegratedSecurity(true);
ds.setServerName("localhost");
ds.setPortNumber(1433);
ds.setDatabaseName("Test");
Connection con = ds.getConnection();
String SQL = "SELECT * FROM Test WHERE ID = ?";
PreparedStatement stmt = con.prepareStatement(SQL);
stmt.setInt(1, 2);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt(1) + ", " + rs.getString(2));
}
rs.close();
stmt.close();
con.close();
}
}
если я запускаю приложение в IDE (IntelliJ IDEA 12.1.6 Community Edition), имея доступный SQL Server, приложение работает нормально, делая именно то, что должно.
драйвер SQL Server загружается из Microsoft и добавляется как внешняя библиотека. Я создал артефакт как файл JAR :
теперь, если я включу sqljdbc4.банки в cliTest.jar (my JAR) полученная банка жирная (550kB и включает классы в этой банке тоже). Или я могу исключить это. В любом случае, бегом!--5-->
java -jar cliTest.jar
результаты
Buna lume!
Exception in thread "main" java.lang.NoClassDefFoundError: com/microsoft/sqlserv
er/jdbc/SQLServerDataSource
at com.company.Main.main(Main.java:15)
Caused by: java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLSer
verDataSource
at java.net.URLClassLoader.run(Unknown Source)
at java.net.URLClassLoader.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 1 more
держу пари, я пропустил что-то довольно основное, но я просто не могу понять, что именно вызывает это.
LE1: я попытался добавить sqljdbc4.jar (хотя это не казалось необходимым) и sqljdbc_auth.dll в каталог, содержащий банку, но по-прежнему без изменений.
позже редактировать 2 : на основе ответа Николая я сделал следующее:
- удалить существующий артефакт
- создал новый артефакт так:
.. и вот результат:
построение -> построить артефакты -> cliTest.сосуд>- Перестроить
CMD подскажите в папке, содержащей:
[cliTest.jar 566 KB был сгенерирован]
java-jar cliTest.Джар
теперь я понимаю :
Exception in thread "main" java.lang.SecurityException: Invalid signature file d
igest for Manifest main attributes
at sun.security.util.SignatureFileVerifier.processImpl(Unknown Source)
at sun.security.util.SignatureFileVerifier.process(Unknown Source)
at java.util.jar.JarVerifier.processEntry(Unknown Source)
at java.util.jar.JarVerifier.update(Unknown Source)
at java.util.jar.JarFile.initializeVerifier(Unknown Source)
at java.util.jar.JarFile.getInputStream(Unknown Source)
at sun.misc.URLClassPath$JarLoader.getInputStream(Unknown Source)
at sun.misc.Resource.cachedInputStream(Unknown Source)
at sun.misc.Resource.getByteBuffer(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access0(Unknown Source)
at java.net.URLClassLoader.run(Unknown Source)
at java.net.URLClassLoader.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
3 ответов
использовать java -cp
вместо java -jar
и поместите все ваши зависимости jars в classpath.
другой способ-упаковать все зависимости в одну банку, что позволяет запускать приложение с помощью java -jar
.
EDIT:
В Java *.файл jar содержит большую часть классов. При создании собственного приложения, как правило, результирующий jar-файл содержит только ваши классы, но все равно должен загружать классы из внешних библиотек, которые вы используете (так называемые зависимости.)
это можно сделать двумя разными способами:
вы создаете папку для своего приложения, например, под названием
lib
и поместите банку приложений и все зависимости. Затем вы запускаете приложение с помощьюjava -cp lib:/\* com.company.Main
или (Спасибо @NilsH, я скучаю по этому варианту) вы делаетеMANIFEST.MF
файл и указатьMain-Class
иClasspath
атрибуты внутри, как описано здесьвы используете специальный инструмент (например Maven-dependency-plugin если вы используете maven для сборки), чтобы упаковать все классы, либо ваши собственные, либо внешние для одного jar. У вас есть один огромный файл и вы можете запустить его с помощью
java -jar cliTest.jar
.
как правило, первый подход является предпочтительным и с помощью MANIFEST.MF
файл-хорошая форма.
Ну я бы построил банке без sqljdbc4.фляги врезал.
второе, что я должен был выполнить команду так:
java -classpath sqljdbc4.jar;cliTest.jar com.company.Main
.. а потом все сработало!
Ну, если вы используете maven, вы можете использовать Maven-shade-plugin для включения зависимых jar в исполняемый jar фрагмент pom.xml приведен ниже.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.main.class.YouMainClass</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>