Puede empaquetar fácilmente todo el conjunto de clases y recursos de una aplicación en un archivo Java (JAR). De hecho, ese es uno de los objetivos de tener archivos jar. Otra es permitir que los usuarios ejecuten fácilmente la aplicación almacenada en el archivo. Entonces, ¿por qué los archivos jar son ciudadanos de segunda clase en el universo de Java (que funcionan solo como archivos) cuando pueden ser de primera clase, junto con los ejecutables nativos?
Para ejecutar un archivo jar, puede usar el
java
comando
-jar
opción. Por ejemplo, supongamos que tiene un archivo jar ejecutable llamado
myjar.jar
. Debido a que el archivo se puede ejecutar, puede ejecutarlo así:
java -jar myjar.jar
.
Alternativamente, Java Runtime Environment (JRE), cuando se instala en un sistema operativo como Microsoft Windows, asocia archivos jar con la JVM para que pueda hacer doble clic en ellos para ejecutar la aplicación. Estos JAR deben poder ejecutarse.
La pregunta es: ¿Cómo se puede ejecutar un JAR?
El archivo de manifiesto y la entrada Main-Class
Dentro de la mayoría de los archivos JAR, un archivo llamado
MANIFEST.MF
se almacena en un directorio llamado
META-INF
. Dentro de ese archivo, una entrada especial llamada
Main-Class
le dice al
java -jar
comando qué clase ejecutar.
El problema es que usted mismo debe agregar correctamente esta entrada especial al archivo de manifiesto; debe ir en un lugar determinado y debe tener un formato determinado. Sin embargo, a algunos de nosotros no nos gusta editar archivos de configuración.
Deje que la API lo haga por usted
Desde Java 1.2, un paquete llamado java.util.jar
le permite trabajar con archivos jar. (Nota: se basa en el java.util.zip
paquete). Específicamente, el paquete jar le permite manipular fácilmente ese archivo de manifiesto especial a través de la Manifest
clase.
Escribamos un programa que use esta API. Primero, este programa debe conocer tres cosas:
- El JAR que deseamos hacer ejecutable
- La clase principal que deseamos ejecutar (esta clase debe existir dentro del JAR)
- El nombre de un nuevo JAR para nuestra salida, porque no deberíamos simplemente sobrescribir archivos
Escribe el programa
La lista anterior constituirá los argumentos de nuestro programa. En este punto, elija un nombre adecuado para esta aplicación. ¿Cómo MakeJarRunnable
suena?
Verifique los argumentos a main
Supongamos que nuestro principal punto de entrada es un main(String[])
método estándar . Primero deberíamos comprobar los argumentos del programa aquí:
if (args.length! = 3) {System.out.println ("Uso: MakeJarRunnable" + ""); System.exit (0); }
Preste atención a cómo se interpreta la lista de argumentos, ya que es importante para el siguiente código. El orden y el contenido de los argumentos no están escritos en piedra; sin embargo, recuerde modificar el otro código adecuadamente si lo cambia.
Acceda al JAR y su archivo de manifiesto
Primero, debemos crear algunos objetos que sepan sobre JAR y archivos de manifiesto:
// Cree el objeto JarInputStream y obtenga su manifiesto JarInputStream jarIn = new JarInputStream (new FileInputStream (args [0])); Manifiesto manifiesto = jarIn.getManifest (); if (manifest == null) {// Esto sucederá si no existe ningún manifiesto manifest = new Manifest (); }
Establecer el atributo Main-Class
Ponemos la Main-Class
entrada en la sección de atributos principales del archivo de manifiesto. Una vez que obtenemos este conjunto de atributos del objeto manifiesto, podemos establecer la clase principal apropiada. Sin embargo, ¿qué pasa si un Main-Class
atributo ya existe en el JAR original? Este programa simplemente imprime una advertencia y sale. Quizás podríamos agregar un argumento de línea de comando que le diga al programa que use el nuevo valor en lugar del preexistente:
Atributos a = manifest.getMainAttributes (); String oldMainClass = a.putValue ("Main-Class", args [1]); // Si existe un valor antiguo, dígale al usuario y salga if (oldMainClass! = Null) {System.out.println ("Advertencia: el valor antiguo de Main-Class es:" + oldMainClass); System.exit (1); }
Salida del nuevo JAR
Necesitamos crear un nuevo archivo jar, por lo que debemos usar la JarOutputStream
clase. Nota: Debemos asegurarnos de no usar el mismo archivo para la salida que para la entrada. Alternativamente, tal vez el programa debería considerar el caso donde los dos archivos jar son iguales y preguntar al usuario si desea sobrescribir el original. Sin embargo, me reservo esto como ejercicio para el lector. ¡Sigamos con el código!
System.out.println("Writing to " + args[2] + "..."); JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(args[2]), manifest);
We must write every entry from the input JAR to the output JAR, so iterate over the entries:
//Create a read buffer to transfer data from the input byte[] buf = new byte[4096]; //Iterate the entries JarEntry entry; while ((entry = jarIn.getNextJarEntry()) != null) { //Exclude the manifest file from the old JAR if ("META-INF/MANIFEST.MF".equals(entry.getName())) continue; //Write the entry to the output JAR jarOut.putNextEntry(entry); int read; while ((read = jarIn.read(buf)) != -1) { jarOut.write(buf, 0, read); } jarOut.closeEntry(); } //Flush and close all the streams jarOut.flush(); jarOut.close(); jarIn.close();
Complete program
Of course, we must place this code inside a main
method, inside a class, and with a suitable set of import statements. The Resources section provides the complete program.
Usage example
Let's put this program to use with an example. Suppose you have an application whose main entry point is in a class called HelloRunnableWorld
. (This is the full class name.) Also assume that you've created a JAR called myjar.jar
, containing the entire application. Run MakeJarRunnable
on this jar file like so:
java MakeJarRunnable myjar.jar HelloRunnableWorld myjar_r.jar
Again, as mentioned earlier, notice how I order the argument list. If you forget the order, just run this program with no arguments and it will respond with a usage message.
Try to run the
java -jar
command on
myjar.jar
and then on
myjar_r.jar
. Note the difference! After you've done that, explore the manifest files (
META-INF/MANIFEST.MF
) in each JAR. (You can find both JARs in the
source code
.)
Here's a suggestion: Try to make the MakeJarRunnable
program into a runnable JAR!
Run with it
Running a JAR by double-clicking it or using a simple command is always more convenient than having to include it in your classpath and running a specific main class. To help you do this, the JAR specification provides a Main-Class
attribute for the JAR's manifest file. The program I present here lets you utilize Java's JAR API to easily manipulate this attribute and make your JARs runnable.
Más información sobre este tema
- Descargue el código fuente y los archivos JAR para este consejo
//images.techhive.com/downloads/idge/imported/article/jvw/2002/05/makejarrunnable.zip
- "Java Tip 120Execute Self-Extracting JARs", Z. Steve Jin y John D. Mitchell ( JavaWorld, noviembre de 2001)
//www.javaworld.com/javaworld/javatips/jw-javatip120.html
- JAR File Specification
//java.sun.com/j2se/1.3/docs/guide/jar/jar.html
- jar—The Java Archive Tool
//java.sun.com/j2se/1.3/docs/tooldocs/win32/jar.html
- View all previous Java Tips and submit your own
//www.javaworld.com/javatips/jw-javatips.index.html
- Learn Java from the ground up in JavaWorld's Java 101 column
//www.javaworld.com/javaworld/topicalindex/jw-ti-java101.html
- Java experts answer your toughest Java questions in JavaWorld's Java Q&A column
//www.javaworld.com/javaworld/javaqa/javaqa-index.html
- Browse the Core Java section of JavaWorld's Topical Index
//www.javaworld.com/channel_content/jw-core-index.shtml
- Manténgase al tanto de nuestros trucos y sugerencias suscribiéndose a los boletines informativos semanales gratuitos por correo electrónico de JavaWorld
//www.javaworld.com/subscribe
- Aprender los conceptos básicos de Java del lado del cliente en JavaWorld' s Java Principiante discusión. Los temas centrales incluyen el lenguaje Java, la máquina virtual Java, API y herramientas de desarrollo.
//forums.idg.net/[email protected]@.ee6b804
- Encontrará una gran cantidad de artículos relacionados con TI de nuestras publicaciones hermanas en .net
Esta historia, "Java Tip 127: Ver ejecución de JAR" fue publicada originalmente por JavaWorld.