clojure uberjar выдает ошибки при запуске на openjdk

Я написал приложение clojure, которое позволяет зашифровать или расшифровать файл вместе с именами исходного и целевого файлов и выполняет указанные операции. Я разработал приложение в виртуальном боксе, используя xubuntu 13, используя clojure-1.5.1 и oracle Java SE 7 JDK. В этой среде все отлично работает, но когда я копирую uberjar в хост-систему, на которой работает Xubuntu 12.10 с использованием openjdk/jre 7, я получаю другое поведение с точки зрения разбора cli.

1) Приложение должно распечатать баннер использования, если параметры не указаны. Это работает так, как должно в среде разработки, но в openjdk генерируется исключение NullPointerException.

2) Опция -v должна печатать версию сборки приложения. Опять же, это отлично работает в среде разработки, но в openjdk/Xubuntu-12.10 выдается исключение, указывающее, что параметр -v является недопустимым.

Вот функция (вызванная из -main): которая занимается разбором cli:

(defn parse-cli 
    "Parses command line arguments then calls functions based on those arguments.  Returns a String or nil if successful." 
    [args]
        (let [[opts files banner] 
          (cli args
              ["-h" "--help" "Print this help message." :flag true :default false]
              ["-v" "--version" "Print build number." :flag true :default false]
              ["-e" "--encrypt" "Encrypt source file" :flag true :default false]
              ["-d" "--decrypt" "Decrypt source file" :flag true :default false] 
              ["-k" "--keyfile" "Path to keyfile" :default "./keyfile"])]

            (cond (or (true? (:help opts)) (zero? (count args))) banner
                  (true? (:version opts)) (implementation-version)
                   :else (let [sfile (first files)
                    dfile (second files)
                    cryptoVec (get-cipher-key (:keyfile opts))]

                    (cond (true? (:encrypt opts)) (if (nil? sfile) "No input file specified" 
                                                        (if (nil? dfile) "No outputfile specified." 
                                                            (encrypt-file sfile dfile (first cryptoVec) (second cryptoVec))))
                            (true? (:decrypt opts)) (if (nil? sfile) "No input file specified" 
                                                    (if (nil? dfile) "No outputfile specified." 
                                                            (decrypt-file sfile dfile (first cryptoVec) (second cryptoVec))))
                            :else "No operation specified.")))))

Ниже приведена полная трассировка исключения, когда uberjar запускается без аргументов:

satch@Ziggy-lin:/media/satch/DATA/.crypto$ java -jar cryptfile.jar
Exception in thread "main" java.lang.NullPointerException
    at java.io.FileInputStream.<init>(FileInputStream.java:134)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at clojure.lang.Reflector.invokeConstructor(Reflector.java:180)
at clojure_crypt_file.core$decrypt_file.invoke(core.clj:40)
at clojure_crypt_file.core$_main.doInvoke(core.clj:81)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.AFn.applyToHelper(AFn.java:159)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure_crypt_file.core.main(Unknown Source)

И трассировка при запуске приложения с опцией -v:

satch@Ziggy-lin:/media/satch/DATA/.crypto$ java -jar cryptfile.jar -v
Exception in thread "main" java.lang.Exception: '-v' is not a valid argument
    at clojure.tools.cli$apply_specs.invoke(cli.clj:72)
    at clojure.tools.cli$cli.doInvoke(cli.clj:130)
    at clojure.lang.RestFn.invoke(RestFn.java:486)
    at clojure_crypt_file.core$_main.doInvoke(core.clj:61)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure_crypt_file.core.main(Unknown Source)

Остальные функции приложения работают должным образом в обеих средах.

Я предполагаю, что проблемы возникают из-за различий между jre openjdk7 и jre oracle SE 7, но помимо этого я ничего не знаю. В частности, я хотел бы найти способ обойти эти различия, если это действительно проблема.


person satch5150    schedule 24.06.2013    source источник
comment
Просто чтобы уточнить, я проверял md5sums при копировании с гостя на хост, и они проверились.   -  person satch5150    schedule 25.06.2013


Ответы (1)


Что ж, после перекомпиляции приложение теперь работает в обеих средах. Я изменил условие (false? (количество аргументов)) на (nil? args), но, согласно документам, это должно работать в любом случае (и работало в среде разработки). Я ничего не делал с параметром -v cli, но теперь приложение демонстрирует идентичное и правильное поведение в обеих средах. Именно из-за таких вещей компьютерная наука вызывает любовь или ненависть. :)

person satch5150    schedule 25.06.2013