Ficheros JAR en JCreator

Ficheros JAR 1 ¿Qué son los ficheros JAR? 2 Creación en un terminal de texto 3 Applets 4 Creando ficheros .jar desde JCr

Views 101 Downloads 6 File size 262KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Ficheros JAR 1 ¿Qué son los ficheros JAR? 2 Creación en un terminal de texto 3 Applets 4 Creando ficheros .jar desde JCreator

1 ¿Qué son los ficheros JAR? Como hemos visto una aplicación en Java está compuesta por varios ficheros .java. Al compilarlos obtenemos varios ficheros .class (uno por fichero .java), y no un único fichero ejecutable como ocurre en otros lenguajes. Para colmo, a menudo la aplicación está formada no sólo por los ficheros .class sino que usa ficheros de sonido (usualmente .au en Java), iconos, etc., lo que multiplica la cantidad de ficheros que forman la aplicación compilada. Esto hace que "llevarse" la aplicación para ejecutarla en un ordenador diferente resulte un poco lioso: olvidar cualquiera de los ficheros que componen la aplicación significaría que ésta no va a funcionar correctamente. En el caso de un applet se añade el problema de la velocidad, al tener que viajar todos los ficheros a través de internet. Los ficheros Jar (Java ARchives) permiten recopilar en un sólo fichero varios ficheros diferentes, almacenándolos en un formato comprimido para que ocupen menos espacio. Es por tanto, algo similar a un fichero .zip (de hecho están basados en ficheros .zip). Entonces, ¿dónde está la "gracia"? ¿No se podrín usar directamente ficheros .zip? La particularidad de los ficheros .jar es que no necesitan ser descomprimidos para ser usados, es decir que el intérprete de Java es capaz de ejecutar los archivos comprimidos en un archivo jar directamente. Por ejemplo, si hemos recopilado todos los ficheros necesarios para ejecutar una aplicación en un fichero "aplic.jar", podemos lanzar la aplicación desde una terminal de texto mediante: java -jar aplic.jar

Vamos a ver ahora cómo se crean los ficheros .jar.

2 Creación en un terminal de texto Hemos visto que se puede lanzar una aplicación llamando al intérprete de java (comando java) seguido de -jar y del nombre del fichero .jar correspondiente. Sin embargo hay algo en todo esto que no "encaja": Si el fichero .jar contiene muchos ficheros .class, ¿cuál de todos se ejecuta? Sabemos que debe ejecutarse el que contiene el método main pero,

¿cómo sabe el intérprete de Java que clase de todas las del fichero contiene este método? La respuesta es que lo sabe porque se lo tenemos que decir durante la creación del fichero jar. Y la forma de hacerlo es un poco liosa. Vamos a verlo paso a paso. Para simplificar suponemos que estamos en un terminal de texto (consola Linux o símbolo del sistema en Windows), que el comando jar es accesible (es decir, la carpeta que contiene jar.exe está en el Path) y que nos encontramos en el directorio donde se encuentran los ficheros .class que deseamos "empaquetar". Crear un directorio META-INF (¡las mayúsculas son importantes!) y dentro un fichero MANIFEST.MF. Este fichero indica, entre otras cosas, cual será la clase principal. A menudo el fichero MANIFEST.MF contiene una única línea: Main-Class: Principal

indicando que Principal.class es la clase que contiene el método main. Observación : El fichero MANIFEST.MF se puede crear con cualquier editor de texto. Hay que introducir un fin de línea (enter) tras la última linea con texto. Crear el fichero .jar mediante el comando jar cfm fich.jar META-INF/MANIFEST.MF *.class

El nombre fich.jar es el que nosotros queramos y corresponde al fichero .jar que se creará conteniendo todos los ficheros indicados (en este caso todos los ficheros .class). Se puede comprobar que el contenido del fichero es el el adecuado escribiendo: jar tf fich.jar

que mostrará la lista de clases contenidas en el fichero. Este comando también puede ser útil para examinar el contenido de las librerías del sistema. Para lanzar el archivo basta con teclear ahora: java -jar fich.jar

Si alguna vez se quiere "desempaquetar" el contenido de un archivo jar se pueden usar las opciones "xf": jar fich.jar

Esto puede resultar particularmente útil si queremos echar un vistazo a algunos paquetes del sistema que vienen de esta forma.

3 Applets Aunque aún no sepamos demasiadas cosas sobre applets este es un buen punto para indicar como se debe usar la herramienta jar en relación a los applets. Vamos a verlo con un ejemplo: supongamos que tenemos un applet de nombre TicTacToe.java. Suponemos que ya está compilado, es decir que ya existe el fichero TicTacToe.class. Además suponemos que este applet utiliza imágenes, que se encuentran en una carpeta images y sonidos que se encuentran en una carpeta sounds. Es decir, tenemos (resultado de hacer

"dir" en un símbolo del sistema): Queremos crear un fichero .jar para guardar toda esta información en un único fichero, que será el que "viaje" por internet. Para ello se hace: jar -cf titac.jar TicTacToe.class audio images

Como se puede ver no se ha incluido el fichero TicTacToe.java (porque no es necesario para la ejecución del programa, aunque se podría haber incluido si se hubiera querido). Ya tenemos el fichero tictac.jar creado. Para cargar el applet desde una página html sólo debemos copiar este fichero a la misma carpeta donde este la página. La página por su parte debe incluir un código similar al siguiente código para "incrustar" el programa Java:

4 Creando ficheros .jar desde JCreator Se puede configurar JCreator para llamar al comando jar. Brevemente estos son los pasos a seguir una vez: Dentro del menú Configure elegir la opción Options . En la ventana que aparece, hacemos click sobre la palabra Tools que aparece en la lista de la izquierda. La pantalla tendrá el aspecto:

(salvo porque la parte derecha no estará vacía si ya hemos introducido otras herramientas como los accesos a javadoc). Pulsar el botón New y del menú desplegable que aparece elegir la opción: Create Jar File . Pulsamos "OK" y ya tenemos JCreator para crear ficheros .jar con el contenido del proyecto que tengamos Java, sin más que pulsar el botón de herramientas que hayamos configurado (la llave inglesa con el número correspondiente, por ejemplo 1 si es la primera herramienta que configuramos). De todas formas hay que hacer algunas observaciones: •



Un fallo (gordo) de esta herramienta es que no crea un fichero MANIFEST adecuado. Esto hace que el "empaquetamiento" sea útil para applets (donde el fichero MANIFEST no importa), pero no para aplicaciones con main. El fichero generado lleva el nombre del proyecto (y extensión .jar, obviamente). Queda almacenado en el directorio del proyecto de JCreator. A menudo pare encontrarlo lo más fácil es usar el buscador de Windows.

Leer los archivos JAR (Febrero de 2005)

Crear archivos JAR Los archivos JAR (Java Archive) son la forma sencilla y eficiente de transportar recursos. Con un archivo JAR facilitamos la distribución e instalación de una gran variedad de archivos, applets, video, sonido, imágenes, texto, etc. Además un archivo JAR puede contener firmar digitales que aseguran la integridad y autenticidad de los datos. Para las clases (.class) la utilidad es doble: puede empaquetar sus clases y colocar el archivo JAR en el CLASSPATH. Además puede poner sus applets en un JAR y señalar dicho archivo en el parámetro ARCHIVE de la etiqueta APPLET de HTML. La compresión JAR es del tipo ZLIB. En el siguiente ejemplo empaquetamos archivos de sonido en un archivo JAR por medio de la utilidad jar que viene con el JDK. Para crear el archivo JAR:

jar -cvf sonidos.jar adagio_barber.mid ....[el resto de archivos que se incluyen] Para visualizar las entradas (archivos) que están en el JAR:

jar -tvf sonidos.jar Que nos muestra por pantalla:

0 Thu Apr 22 17:50:32 CEST 2004 META-INF/ 71 Thu Apr 22 17:50:32 CEST 2004 META-INF/MANIFEST.MF 8232 Thu Apr 22 17:13:40 CEST 2004 adagio_barber.mid 9085 Mon Mar 29 05:03:12 CEST 2004 canon_pachelbel.mid 29070 Sat Mar 13 03:44:16 CET 2004 highway40blues.mid 10889 Thu Apr 22 17:38:06 CEST 2004 ghost_riders_in_the_sky.mid MANIFEST.MF, situado en el directorio META-INF, es un archivo de información sobre versiones y control. Para nuestro caso no será necesario que lo utilicemos. Si quisiéramos extraer el contenido usaríamos:

jar -xvf sonidos.jar

Extraer información del archivo JAR Vamos a plantear un applet de ejemplo, que tiene un archivo JAR con los siguientes contenidos: • • •

El archivo .class del applet Archivo de audio (.mdi) Archivo de video (.gif)

El applet lo puede ver más abajo. En la parte superior aparece una lista que contiene información sobre el archivo JAR y las entradas del archivo. En la parte inferior puede ver la imagen contenida en el JAR (si no la ve bien, presione 'Actualizar').

Respecto a las URLs lo más importante es entender que:

• •

La URL absoluta del archivo JAR empieza señalando el protocolo (jar:) Al final del nombre del archivo JAR hay una exclamación (por ejemplo: pack.jar!). Las URLs de las entradas (archivos contenidos) se construyen simplemente añadiendo su path al final de la URL del archivo JAR. Por ejemplo:

jar:http://www.proactivacalidad.com/java/archivos/jar/pack.jar!/ (archivo JAR) jar:http://www.proactivacalidad.com/java/archivos/jar/pack.jar!/canon_pachelbel.mid (archivo audio) Para la extracción del archivo .class el proceso es automático. Lo único que hay que hacer es indicar su nombre en el parámetro ARCHIVE de la etiqueta APPLET de HTML:

code="docen_archivos.applet_jar.class" archive="jar/pack.jar" Respecto a la extracción y reproducción de los archivos de audio o imagen hay que cumplir con varios pasos: 1. Primero, hay que crear una URL de cada uno de los archivos contenidos: 2. 3. URL url_audio = new URL( "jar:" + getCodeBase().toString() + "jar/pack.jar!/canon_pachelbel.mid" ); 4. URL url_imagen = new URL( "jar:" + getCodeBase().toString() + "jar/pack.jar!/buho.gif" ); 5. A partir de la URL obtener el objeto imagen (clase Image) y audio (AudioClip): 6. 7. audio = getAppletContext().getAudioClip( url_audio ); // Consigo un AudioClip 8. imagen = this.getImage( url_imagen ); // Consigo un Image

9. La reproducción de la imagen es un asunto sencillo que ya hemos tratado. Lo esencial es llamar a drawImage():

10. 11.

public void paint(Graphics g) { Rectangle rec = g.getClipBounds(); 13. int ancho_imagen = imagen.getWidth( this ); 14. int alto_imagen = imagen.getHeight( this ); 15. g.drawImage( imagen, rec.width/2 - ancho_imagen/2, rec.height/2, this ); 16. }

12.

17. El archivo de audio se reproduce de manera simple: 18. 19. audio.play();

El lector podría poner una objeción: en este ejemplo ya sabiamos lo que contiene el archivo JAR, en especial ya conociamos los nombres y extensiones de los archivos de audio e imagen. Pero puede darse el caso de que no lo conozcamos previamente, supongamos que necesitamos listar todos los archivos de audio y no sabemos sus nombres. Hay una solución para esto, que de forma breve se denomina "obtener las entradas de un archivo JAR". Los pasos a seguir:

• • • • • • • •

Obtener un objeto de la clase JarFile. Recorrer una a una las entradas (clase JarEntry) que componen el JarFile. Puedo obtener el nombre de la entrada llamando al método getName() de un JarEntry; en nuestro caso añadimos el nombre a una lista (clase List): JarEntry entry; for (Enumeration e = jar.entries(); e.hasMoreElements(); ) { entry = (JarEntry) e.nextElement(); lista.add(entry.getName()); // Añadir a la lista }

package docen_archivos; import import import import import import import import import import import import import import import

java.awt.*; java.awt.event.*; java.applet.Applet; java.applet.AudioClip; java.net.URL; java.net.URLConnection; java.net.JarURLConnection; java.io.IOException; java.io.FileNotFoundException; java.net.MalformedURLException; java.lang.SecurityException; java.util.jar.JarEntry; java.util.jar.JarFile; java.util.Vector; java.util.Enumeration;

/****************************************************************** * Clase que descarga un gráfico y un archivo midi del archivo JAR. * Reproduce el archivo de audio. * Pone una lista con información de archivos en mitad superior del applet. * Pinta imagen en mitad inferior del applet *****************************************************************/ public class applet_jar extends Applet { List lista = new List(); Image imagen; AudioClip audio = null;; /************** Inicializar el applet *********************/ public void init() { try { jbInit(); } catch (Exception e) { e.printStackTrace(); } } /****************** Inicialización de componentes **********/ private void jbInit() throws Exception {

this.setLayout( new GridLayout(2,1)); filasxcolumnos definir_lista(); cargar(); en lista) if (audio != null) audio.play();

// Divido el applet en

// Pone entradas de JAR en lista // Carga de audio e imagen (también escribe // Si el audio no es nulo, se reproduce

add(lista); repaint(); // Para asegurar que se ve bien la imagen desde el

inicio }

/*** Pinto la imagen centrada y en mitad inferior del applet ***/ public void paint(Graphics g) { Rectangle rec = g.getClipBounds(); int ancho_imagen = imagen.getWidth( this ); int alto_imagen = imagen.getHeight( this ); g.drawImage( imagen, rec.width/2 - ancho_imagen/2, rec.height/2, this ); } /***************** Al destruir el applet se para la música *********/ public void destroy() { if (audio != null) audio.stop(); } /****************************************************************** ****** * Escribe en la lista: 1) URL ABSOLUTA del archivo JAR y 2) URLs RELATIVAS * de las entradas del JAR. ****************************************************************** *****/ void definir_lista() { try { /****** Consigo un JarFile a partir de la URL *****/ URL url = new URL("jar:" + this.getCodeBase().toString() + "jar/pack.jar!/"); Ja

Firmar applet Para firmar un applet debes seguir los siguientes pasos: 1. Crear un archivo jar 2. Generar clave

3. Firmar applet 1. Para crear un archivo jar utiliza la siguiente sentencia jar cvf tuArchivoJar.jar tuClase1.class tuClase2.class image01.jpg etc 2. Luego creas una entrada en el almacen de claves: keytool -genkey -alias tuAlias -validity 360 -v Al momento de ejecutar esta sentencia te solicitara que ingreses algunos datos, los cuales apareceran en el certificado al momento de ejecutar el applet. 3. Firmas el applet: jarsigner.exe tuArchivoJar.jar tuAlias -verbose Con esto es suficiente para firmar un applet

Cómo firmar applets para Netscape

Lo primero que se necesita es hacerse con las herramientas necesarias. En primer lugar, hay que notar que para poder firmar un applet que va a acceder a recursos restringidos, como el sistema de ficheros, propiedades del sistema o conexiones de red, se necesita alterar el código fuente del applet, incluyendo llamadas a ciertas funciones para garantizar los privilegios requeridos. Estas clases constituyen lo que se denomina el Netscape Java Capabilities API. Por otro lado, se requiere la herramienta de firmado, conocida como SignTool 1.1. Una vez armados con este arsenal, se puede proceder ya a firmar applets, siguiendo los siguientes pasos.

Paso 1: Crear un certificado para firmar applets El primer paso consiste también en adquirir un certificado adecuado de una autoridad de certificación. Hay que asegurarse de que la autoridad elegida emite certificados que permitan firmar software, los de clase 2 para uso personal y los de clase 3 para aplicaciones comerciales. VeriSign puede ser de nuevo la elección adecuada. Se pueden consultar más autoridades propuestas por Netscape, aptas para certificar sus productos. En este caso, y como sólo se necesita para hacer pruebas, se creará un certificado de prueba, que es gratis, utilizando la citada herramienta SignTool 1.1.

Antes de instalar claves y certificados nuevos en las bases de datos de Netscape Communicator, es imprescindible crear una contraseña para acceder a la base de datos. Para hacerlo, se pulsa el botón de Seguridad en la barra de herramientas de Communicator, se elige Passwords y después se pulsa el botón de Establecer Passwords para crearlo. Otro aviso importante es que para ejecutar SignTool se debe cerrar antes todas las ventanas abiertas de Communicator, ya que en caso contrario se corre el riesgo de corromper las bases de datos de claves y certificados. Para generar un certificado de prueba se utiliza la opción -G seguida de un nombre y la opción -d para indicar el directorio donde se encuentra la base de datos de certificados (el fichero cert7.db) y claves (el fichero key3.db) de Communicator. Por ejemplo, para crear un certificado para Gonzalo del CSIC, se puede escribir lo siguiente (en negrita aparece lo que se debe introducir en la línea de comandos): signtool -G gonzalo -d c:\netscape\users\gonzalo using certificate directory: c:\netscape\users\gonzalo Enter certificate information. All fields are optional. Acceptable characters are numbers, letters, spaces, and apostrophes. certificate common name: Certificado para pruebas organization: CSIC organization unit: TIC state or province: Madrid country (must be exactly 2 characters): ES username: gonzalo email address: [email protected] Enter Password or Pin for "Communicator Certificate DB": [no se produce eco] generated public/private key pair certificate request generated certificate has been signed certificate "gonzalo" added to database Exported certificate to x509.raw and x509.cacert. Si en el paso anterior se especificó la opción -d junto con el camino donde se encuentra la base de datos de claves y de certificados de Communicator, la base ya ha quedado automáticamente actualizada. La próxima vez que se arranque Communicator, si se pulsa el botón de Seguridad de la barra de herramientas, en Certificados y a continuación en Propios se comprobará que aparece el recién creado. Se puede comprobar que el certificado se ha instalado correctamente también mediante signtool, con la opción -l: signtool -l using certificate directory: . Object signing certificates --------------------------------------gonzalo Issued by: gonzalo (Certificado para pruebas) Expires: Sun Apr 11, 1999

--------------------------------------For a list including CA's, use "signtool -L" Con este certificado ya se está listo para firmar applets. Ahora bien, no basta con firmarlos. Para que los usuarios puedan ejecutar applets firmados es necesario que instalen en su versión de Communicator el certificado que se acaba de generar. Si se hace un listado del directorio donde se está trabajando, se observará que signtool ha creado dos ficheros automáticamente, x509.cacert y x509.raw. El primero de ellos contiene el certificado en formato base64. Para que quede a disposición de cualquiera que lo necesite, se seguirán los siguientes pasos: •





Crear un enlace al fichero x509.cacert en una página Web Por ejemplo, puede añadir la siguiente línea en HTML a su página personal para que los visitantes que deseen ejecutar sus applets sepan dónde obtener su certificado: Primero debes instalar mi certificado. Asegurarse de que el servidor Web exporta el fichero como MIME-type application/x-x509-ca-cert Los servidores de Netscape están configurados así por defecto y también algunos servidores Unix. No así el Internet Information Server de NT, por lo que habrá que configurarlo para que asocie ese tipo MIME a la extensión .cacert. Instalar el certificado Una vez que esos pasos han sido seguidos, basta con pinchar en el enlace anterior para que automáticamente se lance el proceso de instalación de certificados de Netscape. Siguiendo las instrucciones del proceso, muy sencillo, se instalará el certificado en el navegador del usuario, que podrá a partir de ahora ejecutar correctamente todos los applets firmados con este certificado.

Paso 2: Crear un applet con privilegios Antes de traspasar los límites del recinto de seguridad, los applets tienen que pedir permiso educadamente. La manera como se consigue es mediante el API de capacidades. Cada vez que un applet quiere efectuar alguna acción restringida, debe pedir permiso al navegador para ver si éste se lo concede, para lo cual se sirve de las funciones contenidas en esta API. Cuando el applet le pide permiso al navegador, éste busca en su base de datos si existe una entrada para el firmante del applet y si la acción le está permitida. Caso de no existir ninguna entrada, el navegador presenta una ventana pidiendo confirmación antes de conceder el permiso. El usuario decide si garantiza o deniega el permiso, con la posibilidad de almacenar la decisión en la base de datos para futuras referencias. La forma de modificar el applet consiste en preceder todas las llamadas a recursos protegidos de una llamada al gestor de privilegios. Por ejemplo, para solicitar privilegios antes de leer propiedades del sistema, la función en Java que lee los privilegios irá precedida de: PrivilegedManager.enablePrivilege("UniversalPropertyRead"); Para leer/crear/escribir ficheros, se precedería el bloque de funciones correspondiente por:

PrivilegedManager.enablePrivilege("UniversalFileAccess"); Y así con distintas llamadas para cada tipo de recurso. Una vez terminadas las operaciones que requieren privilegios, constituye una buena práctica revocar los privilegios concedidos, utilizando la siguiente función: PrivilegeManager.revertPrivilege("UniversalPropertyRead"); Puedes consultar el listado completo de los recursos que se pueden acceder. La documentación completa sobre este API donde se detalla su funcionamiento se puede obtener gratuitamente. El mayor inconveniente de este enfoque es que exige la modificación del applet y además, como consecuencia de los cambios introducidos, no funcionará ya en ningún otro navegador, tirando por tierra la filosofía de Java de "Escribir una vez, ejecutar en cualquier sitio".

Paso 3: Firmar y empaquetar los ficheros con las clases En vez de firmar el fichero con todas las clases compactadas, como se hacía en el caso de IE, primero se crea un directorio al que se copian todas las clases que componen el applet y a continuación se firma el directorio utilizando la herramienta SignTool. La propia herramienta se encarga de generar un fichero comprimido con todas las clases y demás ficheros que se hayan copiado en el directorio. Este fichero recibe el nombre de Archivo Java (JAR). En versiones anteriores esta herramienta se llamaba zigbert, pero con la versión actual de SignTool ha quedado obsoleta. En el caso supuesto de que se quiera firmar la clase abednego.class, se copiará a un directorio al que se llamará abednego y se ejecutará el programa SignTool, pasándole la clave del certificado almacenada en la base de datos de Communicator, que se acaba de generar en el paso 1. Por ejemplo: signtool -k gonzalo -Z abednego.jar abednego using certificate directory: . Generating abednego/META-INF/manifest.mf file.. --> abednego.class adding abednego/gon.txt to abednego.jar...(deflated 0%) Generating zigbert.sf file.. Aquí pide el password: Enter Password or Pin for "Communicator Certificate DB": [no se produce eco] Si se ha introducido correctamente, continúa: adding abednego/META-INF/manifest.mf to abednego.jar...(deflated 14%) adding abednego/META-INF/zigbert.sf to abednego.jar...(deflated 27%) adding abednego/META-INF/zigbert.rsa to abednego.jar...(deflated 43%) tree "abednego" signed successfully

Ahora ya está disponible el fichero abednego.jar para distribuirlo con su firma incorporada. Se puede verificar que el proceso se ha realizado correctamente utilizando la opción -v: signtool -v abednego.jar using certificate directory: . archive "abednego.jar" has passed crypto verification. status path ------------ ------------------verified abednego.class

Paso 4: Incrustar el JAR en la página web En este caso la etiqueta también cambia ligeramente para permitir la inserción del archivo JAR:

Es importante eliminar el fichero abednego.class original del directorio, ya que en caso contrario el navegador lo cargaría, en lugar del firmado. Ahora ya se puede visualizar correctamente el applet en Communicator. En cada ocasión en la que el applet necesite acceder a un recurso protegido, al usuario se le presentará una ventana de advertencia, en la que se le informa de los permisos que está solicitando ese applet, acompañados de una estimación del riesgo potencial derivado de su concesión. Siempre y cuando no se active la casilla para recordar la decisión, esta ventana aparecerá cada vez que el applet intente acceder de nuevo a ese recurso. En la figura se muestra la información del certificado que el usuario puede comprobar pulsando el botón Certificado en la ventana anterior. Obsérvese cómo los datos corresponden a los que se introdujeron en el paso 1.

Ejemplos de applets para Netscape Communicator Puedes ver un ejemplo operativo con su código fuente disponible en: •

Renegado: esta applet gozará de los privilegios necesarios para acceder a las propiedades del sistema y al disco.