Search code examples
javajarintellij-ideaclassnotfoundexceptionsqljdbc

ClassNotFoundException upon running JAR, no errors while running in IntelliJ IDEA


I'm just starting to build Java apps (I do have .NET experience) and I was trying to build a small test app whose whole code is this :

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();
    }
}

If I run the app in the IDE (IntelliJ IDEA 12.1.6 Community Edition), having the SQL Server available, the app runs fine doing exactly what it should.

The SQL Server Driver is downloaded from Microsoft and added as an External Library. I have created an artifact as JAR file :

enter image description here

Now, if I include the sqljdbc4.jar in the cliTest.jar (my JAR) the resulted JAR is fat (550kB and includes the classes in that JAR too). Or I can exclude it. Either way, running

java -jar cliTest.jar

Results in

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

I bet I'm missing something quite basic but I just can't figure out what exactly is causing this.

LE1 : I tried adding sqljdbc4.jar (although it didn't seem necessary) and sqljdbc_auth.dll in the directory containing the JAR but still no change.

Later edit 2 : Based on Nikolay's answer I've done the following :

  1. Deleted the existing artifact
  2. Created a new artifact like so :

enter image description here

enter image description here

.. and resulted this :

enter image description here

  1. Build -> Build artifacts -> cliTest.jar -> Rebuild

  2. CMD Prompt at the folder containing :

[cliTest.jar 566 KB was generated]

java -jar cliTest.jar

Now I get :

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)

Solution

  • Well I should have built the JAR without the sqljdbc4.jar embedded.

    The second thing I should have run the command like so :

    java -classpath sqljdbc4.jar;cliTest.jar com.company.Main
    

    .. and then all worked!