27526


Leiningenを使わず、clojureのREPL環境にて`compile`関数を利用することでクラスファイルを生成し、それをjarファイルにまとめ、しかも`java
-jar jar`ファイル名のような形で実行できるようにしたいと考えています。

javaについては言語の理解はありますが、それを支えるエコシステム(`java`,
`jar`コマンド等)に関しては経験がなくて、リファレンスを見ながら試行錯誤している状態です。  
このため、本件はclojureに関するミスがあってのことなのか、javaとそれに関するツールの使い方の問題であるかの切り分けが自分ではできませんでした。

**ディレクトリ構成** :

  * 作業ディレクトリ(ルート)の下にサブディレクトリとして以下の名前のディレクトリを配置 
    * classes
    * test1
  * ルート直下にclojure-1.8.0.jar(clojureランタイム)を配置
  * test1ディレクトリの直下に core.clj を配置

**core.clj:**

[code]

    (ns test1.core
      (:gen-class))
    
    (defn -main
      [greetee]
      (println (str "Hello " greetee "!")))
    
[/code]

**REPL環境でコンパイル:**

[code]

    $ java -cp ./clojure-1.8.0.jar clojure.main
    user=> (compile 'test1.core)
    test1.core
    
[/code]

**JARにまとめない形で実行してみる:**

[code]

    $ java -cp ./classes:./clojure-1.8.0.jar test1.core Fred
    Hello Fred!
    
[/code]

**JARファイルを作成:**

[code]

    $ jar cfe test1.jar test1.core classes
    
    $ jar tf test1.jar
    META-INF/
    META-INF/MANIFEST.MF
    classes/
    classes/test1/
    classes/test1/core$fn__5.class
    classes/test1/core$loading__5569__auto____3.class
    classes/test1/core$_main.class
    classes/test1/core.class
    classes/test1/core__init.class
    
    $ jar xf test1.jar META-INF/MANIFEST.MF
    $ cat META-INF/MANIFEST.MF
    Manifest-Version: 1.0
    Created-By: 1.8.0_40 (Oracle Corporation)
    Main-Class: test1.core
    
[/code]

**作成されたJARファイルを指定して実行してみる:**

[code]

    java -cp .\clojure-1.8.0.jar -jar test1.jar Fred
    エラー: メイン・クラスtest1.coreが見つからなかったかロードできませんでした
    
[/code]

なぜメインクラスがロードできないでエラーとなるのか、半日近くかけて分からないなりに調べてみたのですが自分では埒があきませんでした。原因の分かる方がいらしたらご教示お願いします。

**追記(7/11 15:04)**  
Katsumiさんの答えに従って以下のようにjarコマンドを実行し直すと、エラー情報が変わりました。一歩前進だと思いますが、やはりこのエラーがなにを言っているのか、全く分からない状態です。

[code]

    $ jar cfe test1.jar test1.core -C classes test1
    
    $ jar tf test1.jar
    test1/
    test1/core$fn__5.class
    test1/core$loading__5569__auto____3.class
    test1/core$_main.class
    test1/core.class
    test1/core__init.class
    
    $ java -cp ./clojure-1.8.0.jar -jar test1.jar Fred
    Exception in thread "main" java.lang.NoClassDefFoundError: clojure/lang/Var
    at test1.core.<clinit>(Unknown Source)
    Caused by: java.lang.ClassNotFoundException: clojure.lang.Var
            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
    
[/code]

**追記(7/11 15:28)**  
以下のようにすると、実行そのものはできるようになりました。

[code]

    >java -cp .\clojure-1.8.0.jar;.\test1.jar test1.core Fred
    Hello Fred!
    
[/code]

[Java Platform, Standard
Editionツール・リファレンス](http://docs.oracle.com/javase/jp/8/docs/technotes/tools/unix/java.html#BGBCIEFC)を見てみると以下のように書いてありました。どうやらjarオプションを使うときには、指定するjarファイルに依存関係が全て入ってないと駄目なのか？？という程度には推測できるようになりました。

> -jar filename
>
> JARファイルにカプセル化されたプログラムを実行します。filename引数は、アプリケーションの開始位置として機能するpublic static
> void main(String[]  
>  args)メソッドによってクラスを定義する、Main-Class:classnameの形式の行を含むマニフェストのあるJARファイルの名前です。
>
> -jarオプションを使用すると、指定したJARファイルがすべてのユーザー・クラスのソースになり、他のクラス・パスの設定は無視されます。


CC BY-SA 3.0
2016-07-11T05:48:06.150
27522
2016-07-11T06:55:49.157
2016-07-11T06:35:24.833
9403
9403
question
java clojure jar
compile + JAR化したclojureのプログラムが「java.lang.ClassNotFoundException: clojure.lang.Var」とエラーになる


jarにしたフォルダ構成の問題です。  
下記のようにclassesフォルダを含まない形でパッケージングする必要があります。

[code]

    META-INF/
    META-INF/MANIFEST.MF
    test1/
    test1/core$fn__5.class
    test1/core$loading__5569__auto____3.class
    test1/core$_main.class
    test1/core.class
    test1/core__init.class
    
[/code]


CC BY-SA 3.0
2016-07-11T05:59:21.830
27523
2016-07-11T05:59:21.830
10724
27522
answer


ヒントをいただいた甲斐があって、自己解決しました。  
`java`/`jar`コマンドに対する理解が不足していたことが原因でした。

上記の例で言うと、  
先に以下のようなメタファイルを作成してjarを実行すれば、ファイルの配置が正しければ実行できることを確認しました。

[code]

    $ cat test1.mf
    Main-Class: test1.core
    Class-Path: ./clojure-1.8.0.jar
    
    $ jar cmf test1.mf test1.jar -C class test1
    $ java -jar .\test1.jar Fred
    Hello Fred!
    
[/code]


CC BY-SA 3.0
2016-07-11T06:55:49.157
27526
2016-07-11T06:55:49.157
9403
27522
answer