【问题标题】:Running a JAR file without directly calling `java`运行 JAR 文件而不直接调用 `java`
【发布时间】:2010-12-12 16:12:21
【问题描述】:

我正在部署一个用 Java 编写的命令行工具,它接受命令行参数。我把它打包成一个 JAR 文件,因为有一个文件很方便。

问题是要运行它,你必须先调用java -jar (filename) (args),这很烦人。

我目前的方法是使用一个简单的 bash 脚本来启动它,但这并不理想。

是否有(在 Linux、Ubuntu Server 中)制作一个可以自行调用 Java VM 的 JAR 文件?我一直在寻找一个 shebang,但找不到一个(这当然是有道理的,因为它是编译代码)。

这就是我想要做的:myprogram.jar arg1 -arg2 而不是这个:java -jar myprogram.jar arg1 -arg2

谢谢,
布赖恩

【问题讨论】:

  • 没有一个答案说明我在某个地方读到的更好的解决方案,您基本上在 jar 文件的顶部连接了一个 shell 命令。不优雅但很方便。 mesosphere.com/blog/executable-jars

标签: java linux command-line


【解决方案1】:

.zip 文件格式(.jar 格式所基于的)在文件中附加了额外数据的情况下似乎很健壮。因此,如果您使用cat 命令在jar 文件中的zip 数据之前放置一个shebang,并使文件可执行,那么您可以像调用任何普通shell 脚本一样调用jar 文件。

例如: (请注意,unzip -l 命令只是为了说明这一点。它不会改变 .jar 的任何内容,并且在您实际执行此过程时可以省略。)

[bloom@cat-in-the-hat ~]$ java -jar tex4ht.jar 
   xtpipes (2009-01-27-22:19)
   Command line options: 
     java xtpipes [-trace] [-help] [-m] [-E] [-s script_file] [-S script_map]
                  [-i script_dir] [-o out_file] 
                  [-x...ml2xml_arg...]  (-d in_data | in_file)
     -m        messages printing mode
     -E        error messages into exception calls
     in_data   XML data directly into the command line

[bloom@cat-in-the-hat ~]$ cat header.txt 
#!/usr/bin/java -jar
[bloom@cat-in-the-hat ~]$ cat header.txt tex4ht.jar > tex4ht_exe.jar 
[bloom@cat-in-the-hat ~]$ unzip -l tex4ht_exe.jar
Archive:  tex4ht_exe.jar
warning [tex4ht_exe.jar]:  21 extra bytes at beginning or within zipfile
  (attempting to process anyway)
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2009-07-09 15:48   META-INF/
       42  2009-07-09 15:47   META-INF/MANIFEST.MF
        0  2009-07-09 15:48   ./
        0  2009-07-09 15:48   tex4ht/
     2217  2009-07-09 15:48   tex4ht/DbUtilities.class
     2086  2009-07-09 15:48   tex4ht/GroupMn.class
     6064  2009-07-09 15:48   tex4ht/HtJsml.class
     4176  2009-07-09 15:48   tex4ht/HtSpk.class
     1551  2009-07-09 15:48   tex4ht/JsmlFilter.class
     2001  2009-07-09 15:48   tex4ht/JsmlMathBreak.class
     6172  2009-07-09 15:48   tex4ht/OoFilter.class
     3449  2009-07-09 15:48   tex4ht/OoUtilities.class
     1468  2009-07-09 15:48   tex4ht/OomFilter.class
      346  2009-07-09 15:48   xtpipes.class
        0  2009-07-09 15:48   xtpipes/
     4071  2009-07-09 15:48   xtpipes/FileInfo.class
     6904  2009-07-09 15:48   xtpipes/InputObject.class
    25906  2009-07-09 15:48   xtpipes/Xtpipes.class
     1238  2009-07-09 15:48   xtpipes/Xtpipes$5.class
      713  2009-07-09 15:48   xtpipes/Xtpipes$3.class
     1533  2009-07-09 15:48   xtpipes/Xtpipes$1.class
      709  2009-07-09 15:48   xtpipes/Xtpipes$7.class
     1294  2009-07-09 15:48   xtpipes/XtpipesEntityResolver.class
     1235  2009-07-09 15:48   xtpipes/Xtpipes$6.class
     3367  2009-07-09 15:48   xtpipes/Xtpipes$4.class
      709  2009-07-09 15:48   xtpipes/Xtpipes$8.class
     1136  2009-07-09 15:48   xtpipes/Xtpipes$2.class
      875  2009-07-09 15:48   xtpipes/XtpipesPrintWriter.class
     1562  2009-07-09 15:48   xtpipes/XtpipesUni.class
        0  2009-07-09 15:48   xtpipes/util/
     5720  2009-07-09 15:48   xtpipes/util/ScriptsManager.class
     1377  2009-07-09 15:48   xtpipes/util/ScriptsManagerLH.class
---------                     -------
    87921                     32 files
[bloom@cat-in-the-hat ~]$ chmod +x tex4ht_exe.jar
[bloom@cat-in-the-hat ~]$ ./tex4ht_exe.jar 
   xtpipes (2009-01-27-22:19)
   Command line options: 
     java xtpipes [-trace] [-help] [-m] [-E] [-s script_file] [-S script_map]
                  [-i script_dir] [-o out_file] 
                  [-x...ml2xml_arg...]  (-d in_data | in_file)
     -m        messages printing mode
     -E        error messages into exception calls
     in_data   XML data directly into the command line

【讨论】:

  • 这是一个非常有趣的解决方案,虽然很不正统。
  • @Daniel:同意。 binfmt_misc 解决方案绝对是更清洁的解决方案,但这是一个非常酷的 hack ;-)
  • 哇!惊人的。我无法接受这两种解决方案,我感到很糟糕。 @Joachim 是正确的,但它不像 binfmt_misc 那样洁净,因此得到了解决方案。
  • @HalfBrian:我很好——我发布了两个解决方案。
  • 不要这样做,这样一个修改后的 JAR 破坏了我使用 Scala 构建的 SBT 之一,因为即使 JAR 在类路径上,也找不到 JAR 中的类。删除 shebang 解决了这个问题。
【解决方案2】:

参见Documentation/java.txt in the Linux Kernel documentation,它告诉您如何使用binfmt_misc 内核模块配置系统以自动运行Jar 文件。但是,这是您在计算机上更改的配置选项,而不是您对 jar 文件进行的更改,因此它不会在系统之间遵循 jar 文件。

【讨论】:

  • 这似乎是个好主意,但我无法在所有生产机器上安装 SDK。不过,我对目标框进行小的更改没有问题。 Linux 实现了这一点,我感到非常惊喜,非常令人印象深刻。
  • 您不需要完整的 JDK(带有编译器)来完成这项工作。 JRE(无论如何你都需要在生产机器上)应该没问题。
  • 哇!这是一个很棒的工具。工作得很好(sans-SDK)。非常感谢。
【解决方案3】:

在基于 debian 的发行版上,可以安装 jarwrapper

sudo apt-get install jarwrapper

我认为通过安装相同的包名,可以在其他发行版上做同样的事情。

【讨论】:

  • 效果很好。谢谢。
猜你喜欢
  • 1970-01-01
  • 2017-05-21
  • 2014-06-07
  • 2013-04-23
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多