質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JAR

JAR(又はJava ARchive)はコンパイルされた複数のJavaバイトコード及び関連ファイルのリソースを一つのファイルに統合したものです。JARファイルはZIPファイルのフォーマットで構築されています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

994閲覧

jarコマンドで生成したjarファイルからC++のコードを実行したい

nanashi123

総合スコア51

JAR

JAR(又はJava ARchive)はコンパイルされた複数のJavaバイトコード及び関連ファイルのリソースを一つのファイルに統合したものです。JARファイルはZIPファイルのフォーマットで構築されています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2023/01/29 19:34

jarファイルからJNAライブラリを利用したC++コードの呼び出しを試験しています
対象のコードは以下です

D\P\Test.java

1package P; 2import com.sun.jna.Library; 3import com.sun.jna.Native; 4 5public class Test{ 6 public static void main(String[] args){ 7 I.i.Window(300, 300, 300, 300); 8 } 9} 10 11interface I extends Library{ 12 static I i=(I)Native.loadLibrary("..\\..\\Jar\\JNA\\CLR.dll",I.class); 13 void Window(int x,int y,int a,int b); 14}

このコードをコンパイルすると、C++側の関数が実行されます
これをjarファイルから起動したいと考え、マニフェストファイルを以下の内容で定義しました

D\D.mf

1Main-Class: P.Test 2Class-Path: ..\..\Jar\JNA\jna-5.1.0.3.jar 3

そして以下のコマンドでjarファイルを生成します

jar

1jar -cvfm Test.jar D.mf *

このjarファイルをjavaコマンドで起動すると、以下のようなエラーが表示されます

Error

1Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/jna/Library 2 at java.base/java.lang.ClassLoader.defineClass1(Native Method) 3 at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1013) 4 at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150) 5 at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862) 6 at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760) 7 at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681) 8 at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639) 9 at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) 10 at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) 11 at P.Test.main(Test.java:7) 12Caused by: java.lang.ClassNotFoundException: com.sun.jna.Library 13 at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) 14 at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) 15 at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) 16 ... 10 more

一行目の英文から、おそらくjna-5.1.0.3.jarにメインクラス属性が含まれていない為と思われますが、これを回避してコマンドより生成したjarファイルからコードを実行する方法は何か考えられるでしょうか?
そもそもそのようなことは不可能でしょうか?

尚、Eclipsを用いてエクスポートした実行可能jarファイルからは対象コードが正常に動作しているので、コード及びファイルパスの指定に不備はないと考えています
その為Eclips経由でも問題はないのですが、コマンド操作による実行パターンも把握したいため、よろしければご助力頂けると幸いです

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xebme

2023/01/29 20:26

java -jar Test.jar eclipseで作ったjarがこれで起動できるなら、マニフェストファイルにmainクラスの記述が書かれています。 jarファイルはzipファイルなので、拡張子をzipに変えて圧縮解除すれば、中を見られます。
int32_t

2023/01/29 21:30

Test.jar と jna-5.1.0.3.jar のディレクトリの関係はどうなっていますか? Class-Path は相対URLだそうなので、\ ではなく / の方がいいかもしれません。
xebme

2023/01/29 22:19

↑そうでしたか。絶対パスは書けずしかも参照するjarを移動するとClass-Pathを書き換えなければならない。
nanashi123

2023/01/29 23:46

生成したTest.jarは、 Java\WorkSpace\D\Test.jar となっていて、 jna-5.1.0.3.jarは、 Java\Jar\JNA\jna-5.1.0.3.jar となっており、JavaフォルダにWorkSpaceフォルダとJarフォルダが存在します 尚対象コードのパスは Java\WorkSpace\D\P\Test.Java となります クラスパスは/で統一した方がよろしいでしょうか? ただ今回の場合、/を用いてパスを書き直しても、同一のエラーが表示されてしまいました
nanashi123

2023/01/30 00:17 編集

ツリーを以下に示します H:\Project\Java ├─WorkSpace │ ├─D │ │ Test.jar │ │ D.mf │ │ Test2.jar //Eclipsからエクスポートしたjarファイル │ │ │ └─P │ Test.java │ Test.class │ I.class │ │ ├─Jar │ │ │ └─JNA │ jna-jpms-5.13.0.jar │ jna-5.13.0.jar │ jna-platform-jpms-5.13.0.jar │ jna-platform-5.13.0.jar │ CLR.dll クラスパスについて試したことが少し曖昧になってしまったので補足すると、Class-Path属性では「\」を「/」に、Native.loadLibraryの引数では「\\」及び「//」または「/」の3パターンで指定を変え、実行を試験しました *編集機能に気づかず重複投稿してしまいました、申し訳ありません
jimbe

2023/02/01 18:17 編集

そもそも、 Class-Path にカレント以下以外を指定出来るのでしょうか。 >jna-5.13.0.jar 5.1.0.3 では無く?
nanashi123

2023/02/04 03:17

>カレント以下以外 Class-Path属性には、カレントディレクトリ以外を指定できます 今回、Eclipsで作成したjarファイルへのディレクトリパスを、外部フォルダに用意したマニフェストファイルのClass-Path属性に指定し、これをソースに生成された外部jarファイルを起動することで、Eclipsで作成した側のjarファイルが実行できることを確認しています 「jna-5.13.0.jar」のファイル名は完全一致です JNAライブラリには、以下の4つのjarファイルが存在します jna-5.13.0.jar jna-jpms-5.13.0.jar jna-platform-5.13.0.jar jna-platform-jpms-5.13.0.jar (GitHub - java-native-access/jna: Java Native Access) https://github.com/java-native-access/jna >クラスパスを記述できます クラスパスを記述できることは認識しております ただ「zipフォルダへの変換」についての方法は知らず、今回コメントしてくださった方法でEclips製のjarファイルを展開したところ、Eclipsで生成されたマニフェストファイルの内容を覗くことが出来ました その内容を元に新規にディレクトリを構築した結果、つい先ほど解決することが出来ました 遅ればせながら、ご助力ありがとうございました その他コメントして下さった方々も誠にありがとうございます コメント欄ではベストアンサーを選べない為、自己解決という形になってしまいますが、以下に解決までの過程を記録してこの質問は締めたいと思います
guest

回答1

0

自己解決

まず、以下のようなディレクトリツリーを新規に生成しました

H:\Test2

1H:\Test2 2│ Window.java 3│ Window.class 4│ I.class 5│ Window.mf 6│ Window.jar 78└─Source 9 CLR.dll 10 jna-5.13.0.jar 11 jna-jpms-5.13.0.jar 12 jna-platform-5.13.0.jar 13 jna-platform-jpms-5.13.0.jar

前回は異なるディレクトリにあるjnaライブラリとdllファイルを参照する形をとっていましたが、今回はそれらを一つのディレクトリ内に格納しました

Window.javaのコードは以下

H:\Test2\Window.java

1import com.sun.jna.Native; 2import com.sun.jna.Library; 3 4public class Window{ 5 public static void main(String... args){ 6 I.i.Window(200, 200, 200, 200); 7 } 8} 9 10interface I extends Library{ 11 static I i=(I)Native.loadLibrary("Source\\CLR.dll",I.class); 12 13 void Window(int x,int y,int z,int w); 14}

dllファイルはSourceというフォルダに移動させたので、パスも書き換えています
マニフェストファイルは以下の通りに記述しました

H:\Test2\Window.mf

1Main-Class: Window 2Class-Path: .\Source\jna-5.13.0.jar 3

これをソースにjarコマンドを用いてjarファイルを生成
次にjavaコマンドを使ってこのjarファイルを実行したところ、今回は無事C++のコードを実行させることに成功しました

また、Testフォルダの外に以下のディレクトリを生成しました

H:\E

1H:\E 2 E.jar 3 X.class 4 X.java 5 main.mf

main.mfは以下の取り

H:\E\main.mf

1Main-Class: X 2Class-Path: ..\Test2\Window.jar 3

H:\Test2\Window.jarを参照するマニフェストです
これを元にE.jarを生成し、起動したところ、このjarファイルを経由してWindows.jarの実行に成功しました

ただし、この実行には一つ条件があり、それがWindow.javaのインターフェイス「I」に宣言されたNative.loadLibraryの引数に指定される「dllファイルまでのディレクトリパス」と一致するフォルダ内でE.jarを起動させることです
今回の例では、このE.jarはH:\Test2内で起動される必要がある模様です

結局のところEclips側では何故質問に挙げたコードで正常に起動できるjarファイルが生成できたのかは解りませんでしたが、コマンドでJNAライブラリを利用したjarファイルを生成する場合、ソースとなるdllとJNAライブラリのjarファイルを、一つのディレクトリで一元的に管理する必要があるらしいことまで把握しました

尚、jna-5.13.0.jarファイルにはMain-Class属性が含まれていないと思い込んでいましたが、zipフォルダに変換、解凍したところ、内部のマニフェストフィルにMain-Class属性を見つけました
初歩的なことかもしれませんが、この点に気づけたことは大きいです
本当にありがとうございました

投稿2023/02/04 03:59

編集2023/02/04 04:09
nanashi123

総合スコア51

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問