18

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

SQL Server を利用できる IDE (IntelliJ IDEA 12.1.6 Community Edition) でアプリを実行すると、アプリは正常に実行され、本来の動作を実行します。

SQL Server ドライバーは Microsoft からダウンロードされ、外部ライブラリとして追加されます。JARファイルとしてアーティファクトを作成しました:

ここに画像の説明を入力

ここで、sqljdbc4.jar を cliTest.jar (私の JAR) に含めると、結果の JAR は太くなります (550kB で、その JAR にもクラスが含まれます)。または、除外することができます。いずれにせよ、実行中

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$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

かなり基本的なものが欠けているに違いありませんが、何が原因なのか正確にはわかりません。

LE1 : JAR を含むディレクトリに sqljdbc4.jar (必要ではなかったようですが) と sqljdbc_auth.dll を追加しようとしましたが、変更はありません。

後で編集2:ニコライの答えに基づいて、次のことを行いました:

  1. 既存のアーティファクトを削除しました
  2. 次のような新しいアーティファクトを作成しました:

ここに画像の説明を入力

ここに画像の説明を入力

..そしてこれをもたらしました:

ここに画像の説明を入力

  1. ビルド -> アーティファクトのビルド -> cliTest.jar -> リビルド

  2. 以下を含むフォルダーでの CMD プロンプト:

【cliTest.jar 566KBが生成されました】

java -jar cliTest.jar

今私は得る:

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)
4

3 に答える 3

7

java -cp代わりに使用しjava -jarて、すべての依存関係 jar をクラスパスに配置します。

もう 1 つの方法は、すべての依存関係を 1 つの jar にパックすることです。これにより、.xml を使用してアプリケーションを実行できますjava -jar

編集:

Java *.jar ファイルには、大量のクラスが含まれています。独自のアプリをビルドする場合、通常、結果の jar ファイルにはクラスのみが含まれますが、使用する外部ライブラリ (いわゆる依存関係) からクラスをロードする必要があります。

次の 2 つの方法で実行できます。

  1. たとえば、アプリケーション用のフォルダーを作成し、libアプリケーション jar とすべての依存関係を配置します。次に、使用してアプリケーションを実行するjava -cp lib:/\* com.company.Mainか (@NilsH に感謝します。このバリアントが恋しいです)、MANIFEST.MFファイルを作成し、ここで説明されているように内部で属性を指定Main-Classします。Classpath

  2. 特別なツール (ビルドに maven を使用する場合は maven-dependency-plugin など) を使用して、すべてのクラス (独自のクラスまたは外部の単一の jar のいずれか) をパックします。1 つの巨大なファイルを取得し、java -jar cliTest.jar.

一般に、最初のアプローチが好まれ、MANIFEST.MFファイルを使用するのが適切な形式です。

于 2013-11-03T19:58:07.163 に答える