Je commence juste à construire des applications Java (j'ai une expérience .NET) et j'essayais de construire une petite application de test dont le code entier est le suivant:
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 j'exécute l'application dans le IDE (IntelliJ IDEA 12.1.6 Community Edition), ayant SQL Server disponible, l'application fonctionne bien en faisant exactement ce qu'elle devrait.
Le pilote SQL Server est téléchargé à partir de Microsoft et ajouté en tant que bibliothèque externe. J'ai créé un artefact en tant que fichier JAR:
Maintenant, si j'inclus le sqljdbc4.jar dans le cliTest.jar (mon JAR), le JAR résultant est gros (550 Ko et inclut également les classes dans ce JAR). Ou je peux l'exclure. De toute façon, en cours d'exécution
Java -jar cliTest.jar
Résulte 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
Je parie que je manque quelque chose d'assez basique, mais je n'arrive pas à comprendre ce qui cause exactement cela.
LE1: J'ai essayé d'ajouter sqljdbc4.jar (bien que cela ne semble pas nécessaire) et sqljdbc_auth.dll dans le répertoire contenant le JAR mais toujours pas de changement.
Édition ultérieure 2: Sur la base de la réponse de Nikolay, j'ai fait ce qui suit:
.. et a abouti à ceci:
Construire -> Construire des artefacts -> cliTest.jar -> Reconstruire
Invite CMD dans le dossier contenant:
[cliTest.jar 566 Ko a été généré]
Java -jar cliTest.jar
Maintenant je reçois:
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)
Eh bien, j'aurais dû construire le JAR sans le sqljdbc4.jar intégré.
La deuxième chose que j'aurais dû exécuter la commande comme ceci:
Java -classpath sqljdbc4.jar;cliTest.jar com.company.Main
.. et puis tout a fonctionné!
Utilisation Java -cp
au lieu de Java -jar
et placez tous vos fichiers de dépendances dans classpath.
Une autre façon est de regrouper toutes les dépendances dans un seul pot, ce qui vous permet d'exécuter l'application en utilisant Java -jar
.
MODIFIER:
Dans Java * .jar contient un grand nombre de classes. Lorsque vous créez votre propre application, le fichier jar de résultat contient généralement uniquement vos classes, mais doit toujours charger les classes à partir des bibliothèques externes que vous utilisez ( soi-disant dépendances).
Cela peut se faire de deux manières différentes:
Vous créez un dossier pour votre application, par exemple, appelé lib
et placez votre jar d'application et toutes les dépendances dans. Ensuite, vous exécutez l'application à l'aide de Java -cp lib:/\* com.company.Main
ou (merci @NilsH, cette variante me manque) vous faites MANIFEST.MF
fichier et spécifiez Main-Class
et Classpath
attributs à l'intérieur comme décrit ici
Vous utilisez un outil spécial (comme maven-dependency-plugin si vous utilisez maven pour la construction) pour emballer toutes les classes, soit la vôtre, soit externe à un seul pot. Vous avez un énorme fichier et pouvez l'exécuter en utilisant Java -jar cliTest.jar
.
Généralement, la première approche est préférée et en utilisant un MANIFEST.MF
le fichier est une bonne forme.