2009-11-03 37 views
20

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.Ejecutar un archivo JAR sin llamar directamente a 'java`

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

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

¿Hay alguna forma (en Linux, Ubuntu Server) para crear un archivo JAR que invoca Java VM por sí mismo? He buscado un shebang, pero no he podido encontrar uno (que, por supuesto, tiene sentido ya que es 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

+0

Ninguna de las respuestas indica una mejor solución que leí en algún lugar donde básicamente concatenas un comando de shell en la parte superior del archivo jar. No es elegante pero muy conveniente. https://mesosphere.com/blog/executable-jars/ –

Respuesta

16

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

+1

Un enlace relacionado: http://www.linuxhq.com/java.html –

+0

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. Estoy muy gratamente sorprendido de que Linux haya implementado eso, muy impresionante. – HalfBrian

+1

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

39

El formato de archivo .zip (en el que se basa el formato .jar) parece ser sólido en presencia de datos adicionales antes del archivo. Por lo tanto, si usa el comando cat para colocar un shebang antes de los datos zip en el archivo jar y hacer que el archivo sea ejecutable, puede llamar al archivo jar como lo haría con cualquier script de shell común.

Por ejemplo: (Tenga en cuenta que el comando unzip -l es sólo para ilustrar el punto No cambia nada sobre el .jar y puede ser omitida cuando en realidad estás haciendo este proceso..)

[[email protected] ~]$ 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 

[[email protected] ~]$ cat header.txt 
#!/usr/bin/java -jar 
[[email protected] ~]$ cat header.txt tex4ht.jar > tex4ht_exe.jar 
[[email protected] ~]$ 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 
[[email protected] ~]$ chmod +x tex4ht_exe.jar 
[[email protected] ~]$ ./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 
en
+1

¡Guau! ¡Eso realmente funciona! ¡Estoy muy impresionado! –

+2

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

+0

@Daniel: de acuerdo. la solución 'binfmt_misc' es definitivamente la más limpia, pero este es un hack realmente genial ;-) –

2

distribución basada en Debian, es posible instalar jarwrapper

sudo apt-get install jarwrapper 

creo que esto es posible hacer lo mismo en otras distribuciones mediante la instalación con el mismo nombre del paquete.

Cuestiones relacionadas