ClassNotFoundException al ejecutar JAR, no se producen errores mientras se ejecuta en IntelliJ IDEA
Estoy empezando a crear aplicaciones Java (tengo experiencia con .NET) y estaba intentando crear una aplicación de prueba pequeña cuyo código completo es este:
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();
}
}
Si ejecuto la aplicación en el IDE (IntelliJ IDEA 12.1.6 Community Edition), teniendo el servidor SQL disponible, la aplicación funciona bien haciendo exactamente lo que debería.
El controlador de SQL Server se descarga de Microsoft y se agrega como una biblioteca externa. He creado un artefacto como archivo JAR:
Ahora, si incluyo el sqljdbc4.jar en el cliTest.jar (mi JAR), el JAR resultante es gordo (550 kB e incluye las clases en ese JAR también). O puedo excluirlo. De cualquier manera, corriendo
java -jar cliTest.jar
Resultados en
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$1.run(Unknown Source)
at java.net.URLClassLoader$1.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
Apuesto a que me estoy perdiendo algo bastante básico, pero simplemente no puedo averiguar qué es exactamente lo que está causando esto.
LE1: Intenté agregar sqljdbc4.jar (aunque no me pareció necesario) y sqljdbc_auth.dll en el directorio que contiene el JAR pero aún no hay cambios.
Edición posterior 2: Basado en la respuesta de Nikolay, he hecho lo siguiente:
Se eliminó el artefacto existente.Creó un nuevo artefacto así:.. y resultó esto:
Construir -> Construir artefactos -> cliTest.jar -> Reconstruir
Solicitud de CMD en la carpeta que contiene:
[cliTest.jar 566 KB fue generado]
java -jar cliTest.jar
Ahora me sale:
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$2.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.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.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)