Ejecutar un archivo JAR sin llamar directamente a `java`

5 minutos de lectura

Estoy implementando una herramienta de línea de comandos escrita en Java que acepta argumentos de línea de comandos. Lo tengo empaquetado como un archivo JAR porque es conveniente tener un solo archivo.

El problema es que para ejecutarlo primero debes llamar java -jar (filename) (args) y eso es bastante molesto.

La forma actual en que lo tengo es tener un script bash simple que lo inicia, pero esto es menos que ideal.

¿Existe de todos modos (en Linux, Ubuntu Server) para crear un archivo JAR que invoque la VM de Java por sí mismo? Busqué un shebang, pero no pude encontrar uno (lo que, por supuesto, tiene sentido ya que es un código compilado).

Esto es lo que quiero hacer: myprogram.jar arg1 -arg2 en lugar de esto: java -jar myprogram.jar arg1 -arg2

Gracias,
Brian

  • Ninguna de las respuestas indica una mejor solución que leí en alguna parte donde básicamente concatenas un comando de shell en la parte superior del archivo jar. No elegante pero muy conveniente. mesosphere.com/blog/ejecutable-jars

    – Sridhar Sarnobat

    12 dic. 17 a las 23:29


Ejecutar un archivo JAR sin llamar directamente a java
ken florecer

El formato de archivo .zip (en el que se basa el formato .jar) parece ser sólido en presencia de datos adicionales añadidos al archivo. Por lo tanto, si usa el cat comando para poner un shebang antes de los datos zip en el archivo jar y hacer que el archivo sea ejecutable, luego puede llamar al archivo jar como si llamara a cualquier script de shell normal.

Por ejemplo: (Tenga en cuenta que el unzip -l comando es sólo para ilustrar el punto. No cambia nada sobre el .jar y se puede omitir cuando esté realizando este proceso).

[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

  • Esta es una solución muy interesante, aunque bastante poco ortodoxa.

    –Daniel Pryden

    04 de noviembre de 2009 a las 1:06

  • @Daniel: de acuerdo. el binfmt_misc La solución es definitivamente la más limpia, pero este es un truco realmente genial 😉

    – Joaquín Sauer

    04 de noviembre de 2009 a las 1:15

  • ¡Guau! Increíble. Me siento terrible por no poder aceptar ambas soluciones. Sin embargo, @Joachim tiene razón, esto no es tan kosher como binfmt_misc, por lo que obtiene la solución.

    – Medio Brian

    04 de noviembre de 2009 a las 14:02

  • @HalfBrian: bien por mí, publiqué ambas soluciones.

    –Ken Bloom

    05 de noviembre de 2009 a las 4:20

  • No hagas esto, tal JAR modificado rompió una de mis compilaciones SBT con Scala ya que las clases en el JAR no se encontraron a pesar de que el JAR estaba en el classpath. Quitar el shebang resolvió el problema.

    – ComFreek

    10 ene.

Ver Documentation/java.txt en la documentación del Kernel de Linux, que le indica cómo configurar un sistema utilizando el binfmt_misc módulo kernel para ejecutar archivos Jar automáticamente. Sin embargo, esta es una opción de configuración que cambia en una computadora, no algo que cambia sobre el archivo jar, por lo que no sigue el archivo jar de un sistema a otro.

  • Parece una gran idea, pero no puedo permitirme instalar el SDK en todas las máquinas de producción. Sin embargo, no tengo problemas para hacer pequeños cambios en el cuadro de destino. Sin embargo, estoy muy gratamente sorprendido de que Linux haya implementado eso, muy impresionante.

    – Medio Brian

    03 de noviembre de 2009 a las 15:12

  • No necesita el JDK completo (con el compilador) para que esto funcione. El JRE (que de todos modos necesita en las máquinas de producción) debería estar bien.

    –Ken Bloom

    03 de noviembre de 2009 a las 15:27

  • ¡Guau! Esa es una gran herramienta. Funcionó muy bien (sans-SDK). Muchas gracias.

    – Medio Brian

    03 de noviembre de 2009 a las 15:46

En una distribución basada en Debian, es posible instalar jarwrapper

sudo apt-get install jarwrapper

Creo que es posible hacer lo mismo en otras distribuciones instalando con el mismo nombre de paquete.

  • Funciona genial. Gracias.

    – Fiddy Bux

    15 abr.

.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad