Instalador configurable a través de ficheros XML

Anuncio
TRABAJO FIN DE ESTUDIOS
PROYECTO FIN DE CARRERA
Instalador configurable a través de ficheros XML
Miguel Marañón Grandes
Tutor: Julio Rubio García
Curso 2009-2010
Instalador configurable a través de ficheros XML, trabajo fin de estudios
de Miguel Marañón Grandes, dirigido por Julio Rubio García (publicado por la Universidad
de La Rioja), se difunde bajo una Licencia
Creative Commons Reconocimiento-NoComercial-SinObraDerivada 3.0 Unported.
Permisos que vayan más allá de lo cubierto por esta licencia pueden solicitarse a los
titulares del copyright.
©
©
El autor
Universidad de La Rioja, Servicio de Publicaciones, 2012
publicaciones.unirioja.es
E-mail: [email protected]
UNIVERSIDAD DE LA RIOJA
Facultad de Ciencias, Estudios Agroalimentarios e Informática
PROYECTO FIN DE CARRERA
Ingeniería Técnica en Informática de Gestión
Un instalador configurable a través de ficheros
XML
Alumno: Miguel Marañón Grandes
Director: Julio Jesús Rubio García
Logroño, julio de 2010
1. Resumen
La instalación de programas computacionales (software) es el proceso por el cual nuevos programas son transferidos a un computador y, eventualmente, configurados, para
ser usados con el fin para el cual fueron desarrollados. Un instalador es un programa
que realiza el proceso de instalación de un determinado software.
Pues bien, en este proyecto se explicará cómo construir un creador de instaladores; es
decir, una aplicación que permita elaborar instaladores de todo tipo, configurables mediante los datos almacenados en un fichero XML.
Además, la aplicación que desarrollaremos deberá ser capaz de permitir al usuario que
ejecutará en última instancia la instalación cambiar algunos parámetros del instalador,
así como proporcionar un desinstalador que revierta las modificaciones producidas
por el instalador.
Es necesario remarcar que la metodología empleada a la hora de desarrollar la aplicación se alejó ligeramente de algunos de los procedimientos habituales en Ingeniería
del Software. Para dar un carácter más experimental al proyecto, se consideró conveniente no determinar completamente desde el comienzo los requisitos que debía cumplir el creador de instaladores. De este modo, ha sido necesario ir modificando los requisitos poco a poco, a medida que implementábamos nuevas funcionalidades.
2
2. Índice
2.1. Índice de contenidos
1.
2.
Resumen......................................................................................................... 2
Índice.............................................................................................................. 3
2.1.
Índice de contenidos ......................................................................................... 3
2.2.
Índice de figuras y tablas .................................................................................. 5
3.
Introducción.................................................................................................... 6
4.
Memoria......................................................................................................... 8
4.1.
Documento de Objetivos del Proyecto (D. O. P.) .............................................. 8
4.1.1. Definición del proyecto ................................................................................ 8
Antecedentes.......................................................................................................... 8
Objetivos del proyecto ........................................................................................... 9
Descripción del producto ....................................................................................... 9
4.1.2. Alcance del proyecto .................................................................................. 10
Informe del alcance .............................................................................................. 10
Entregables ........................................................................................................... 10
Actividades de apoyo............................................................................................ 11
4.1.3. Recursos humanos, personal y plan de comunicaciones ........................... 11
Conexiones del proyecto ...................................................................................... 11
Plan de dirección del personal ............................................................................. 11
Plan de comunicaciones ....................................................................................... 12
4.1.4. Dirección de riesgos.................................................................................... 12
Fuentes de riesgo.................................................................................................. 12
Síntomas de riesgo ............................................................................................... 13
Cuantificación de los riesgos ................................................................................ 13
Plan de contingencia............................................................................................. 14
4.1.5. Planificación del proyecto .......................................................................... 14
Estructura de Descomposición del Proyecto (EDP).............................................. 15
Listado de actividades .......................................................................................... 16
Calendario de trabajo ........................................................................................... 18
Diagrama de Gantt ............................................................................................... 19
4.2.
Análisis ............................................................................................................ 21
4.2.1. Análisis de requisitos .................................................................................. 21
4.2.2. Casos de uso ............................................................................................... 23
Definir nombre instalador .................................................................................... 23
Definir archivos a copiar....................................................................................... 24
Definir accesos directos........................................................................................ 25
Definir paquetes ................................................................................................... 26
Definir accesos directos menú Inicio y escritorio................................................. 27
Definir usuarios finales ......................................................................................... 28
Definir iconos........................................................................................................ 29
Definir ruta instalación ......................................................................................... 30
Definir grupo programas ...................................................................................... 31
3
Definir modificación registro................................................................................ 32
Definir archivos auto-ejecutables......................................................................... 33
Ejecutar instalador................................................................................................ 34
4.2.3. Diagrama de casos de uso .......................................................................... 35
4.3.
Diseño ............................................................................................................. 36
4.3.1. Descripción de la clase Creador_instaladores............................................ 37
4.3.2. Descripción de la clase Construct............................................................... 38
4.3.3. Descripción del archivo Make.bat .............................................................. 45
4.3.4. Relaciones entre los archivos de la aplicación ........................................... 46
4.3.5. Interfaz del usuario creador ....................................................................... 46
Descripción ........................................................................................................... 46
Precondiciones ..................................................................................................... 48
Poscondiciones ..................................................................................................... 48
4.3.6. Interfaz del usuario final............................................................................. 49
Captura de pantalla .............................................................................................. 49
Descripción ........................................................................................................... 49
Precondiciones ..................................................................................................... 51
Poscondiciones ..................................................................................................... 51
Diagrama de estados ............................................................................................ 52
4.3.7. Interfaz para el desinstalador..................................................................... 53
4.4.
Implementación .............................................................................................. 54
4.5.
Pruebas ........................................................................................................... 60
4.5.1. Pruebas de comprobación de la funcionalidad .......................................... 60
4.5.2. Pruebas de la interfaz de usuario ............................................................... 64
4.6.
Gestión del proyecto....................................................................................... 66
4.7.
Conclusiones ................................................................................................... 68
4.7.1. Concordancia entre resultados y objetivos................................................ 68
4.7.2. Lecciones aprendidas ................................................................................. 68
4.7.3. Líneas de ampliación posibles .................................................................... 69
4.8.
Bibliografía ..................................................................................................... 70
4.9.
Anexos............................................................................................................. 71
4.9.1. ANEXO I: Manual de instrucciones del usuario creador............................. 71
4.9.2. ANEXO II: Cronología del Proyecto Fin de Carrera ..................................... 74
4.9.3. ANEXO III: Actas de reuniones.................................................................... 79
4
2.2. Índice de figuras y tablas
Figura 1: Esquema global de la aplicación........................................................................ 9
Figura 2: Modelo de planificación .................................................................................. 15
Figura 3: Diagrama EDP .................................................................................................. 16
Figura 4: Calendario de trabajo ...................................................................................... 19
Figura 5: Diagrama de Gantt del trabajo planificado ..................................................... 20
Figura 6: Diagrama de casos de uso ............................................................................... 35
Tabla 1: Elementos y atributos para modificar el registro ............................................. 40
Tabla 2: Claves del fichero de configuración y su descripción ....................................... 45
Figura 7: Diagrama de colaboración entre los ficheros de la aplicación........................ 46
Figura 8: XML-Schema del fichero Instalador.xml.......................................................... 47
Figura 9: XML-Schema del elemento lugaresInstalacion ............................................... 47
Figura 10: Prototipo de la interfaz del usuario final....................................................... 49
Figura 11: Prototipo de interfaz para cancelar la instalación ........................................ 50
Figura 12: Prototipo de interfaz para confirmar la instalación ...................................... 51
Figura 13: Diagrama de estados de la interfaz del usuario final .................................... 52
Figura 14: Prototipo de interfaz para ejecutar el desinstalador .................................... 53
Figura 15: Prototipo de interfaz para confirmar la desinstalación................................. 53
5
3. Introducción
El proyecto que queremos desarrollar consiste en la construcción de un creador de
instaladores configurable a través de un fichero XML, de modo que parte de la configuración inicial dada por este fichero pueda ser modificada posteriormente por el
usuario que a la postre instalará la aplicación para la que se construyó el instalador.
Las funciones del creador de instaladores no se limitarán a proporcionar el instalador
del programa que queremos que se instale, sino también a crear los archivos y procesos necesarios para desinstalarlo del equipo (es decir, un desinstalador de ese mismo
programa). Además, deberá dar la opción de que el instalador creado permita configurar la instalación en los aspectos más usuales: creación de accesos directos, elección
del directorio de instalación, etcétera.
Para la construcción de este creador de instaladores nos fijaremos en las características de algunos productos de software similares ya existentes. Si bien uno de los objetivos del proyecto será emularlos en lo más básico, se intentará mejorarlos en la medida
de lo posible.
Las razones por las que he elegido este tema para realizar el Proyecto Fin de Carrera
son tres: por un lado, la posibilidad de colaborar con el Departamento de Matemáticas
y Computación; por otro, la opción de formar parte del equipo de desarrollo de la
aplicación para alumnos de matemáticas de secundaria TutorMates (este aspecto lo
explicaremos con más detalle en el siguiente párrafo); y finalmente, mi deseo de embarcarme en un proyecto eminentemente tecnológico y de investigación que me proporcione una formación de garantías para el desarrollo de la profesión de ingeniero
informático.
Centrándonos en TutorMates, AddLink Research, S.L. es la empresa encargada del desarrollo y comercialización de esta aplicación, dirigida a los alumnos y profesores que
forman parte de la enseñanza de las matemáticas en secundaria. Al igual que la mayoría de las aplicaciones informáticas, TutorMates necesitaba un instalador de modo que
fuera más fácil incorporar el programa al equipo del usuario que lo utilizara. Así, el
equipo de desarrollo de TutorMates decidió incluir en el proyecto un creador de instaladores desarrollado en Java y de código abierto para cubrir sus necesidades iniciales
y poder contar con él desde el primer día. Es posible que la herramienta que vamos a
construir se encargue de la elaboración de este instalador.
6
Existen determinadas funcionalidades del creador de instaladores que finalmente no
se considerarán en el proyecto, como es la incorporación de un soporte multilingüe
(hay que tener en cuenta que TutorMates es una herramienta pensada para ser usada
en todo el territorio nacional, por lo que debería estar traducida, al menos, al gallego,
vasco y catalán), una interfaz para el usuario creador de la instalación o un soporte
multiplataforma, de modo que no sólo funcione en Windows. La razón por la que no se
considerarán tales requisitos es la falta de tiempo: la fecha tope de entrega de la memoria se ha establecido en julio de 2010, siendo la fecha de inicio octubre de 2009.
7
4. Memoria
En este apartado desarrollaremos el cuerpo de la memoria, uno de los entregables más
importantes del proyecto.
4.1. Documento de Objetivos del Proyecto (D. O. P.)
En este capítulo se especificarán asuntos relativos al proyecto tales como sus objetivos, descripción, entregables principales, plan de trabajo y otros aspectos.
4.1.1.
Definición del proyecto
En este punto se explicarán, entre otras cosas, los antecedentes en los que viene enmarcado el proyecto, los objetivos que se pretenden y una descripción del producto
que se desea elaborar con él.
Antecedentes
El proyecto se enmarca dentro de la construcción de una aplicación que servirá como
herramienta de apoyo a los estudiantes de matemáticas de secundaria: TutorMates.
En concreto, lo que se pretende con dicho proyecto es la construcción de un creador
de instaladores que pueda ser aprovechado por la empresa que desarrolla este producto con el fin de no utilizar programas de instalación externos a ella y, de este modo,
fabricar el instalador definitivo de la aplicación.
Este proyecto se realiza para la empresa Addlink Research, S.L., propietaria de la marca
TutorMates, en colaboración con el Ministerio de Educación, Geogebra y las universidades de Cantabria y La Rioja. El profesor de la UR Julio Rubio García actuó como tutor
académico del proyecto, mientras que el papel de director del proyecto (y, por tanto,
responsable de todas las decisiones tomadas en él) recayó en mi persona.
Se trata de un proyecto clave dentro de este marco, porque de él depende que la elaboración del instalador de la aplicación utilice herramientas ajenas a la empresa. Por
otro lado, el producto que se espera obtener debería emular (y si fuera posible, mejorar) a alguno de los creadores de instaladores ya existentes (en concreto, a IzPack, basado precisamente en la configuración de la instalación a través de ficheros XML). Este
hecho permitiría la opción de realizar (si la empresa lo creyera conveniente) el instalador definitivo de TutorMates bajo mi responsabilidad, como algo fuera de proyecto pero con una cierta remuneración económica.
8
4.1.2.
Alcance del proyecto
En este apartado se detallará qué se hará y qué no se hará en el proyecto, así como los
entregables que se depositarán.
Informe del alcance
Este proyecto está englobado en otro más grande, basado en la realización de una aplicación que sirva como herramienta de aprendizaje matemático a los alumnos y profesores de la educación secundaria: TutorMates. Esta aplicación deberá cumplir los siguientes requisitos:
El desarrollo multiplataforma: Windows, Linux y Mac OS X.
El motor de cálculo reposará en herramientas de uso libre y gratuito, como
MAXIMA y Geogebra.
La interfaz de usuario desarrollada en Java tendrá como principales referentes
la facilidad de uso y la interacción con el usuario final (el alumno).
El soporte multilingüe.
El creador de instaladores no cumplirá, en un principio, todas estas características.
Concretamente, sólo será válido para Windows, ya que se usarán mandatos propios y
exclusivos de este sistema operativo, y por falta de tiempo no dispondrá del soporte
multilingüe. Sin embargo, sí que se esperará que cumpla los requisitos relativos a la facilidad de uso de su interfaz.
Por otro lado, como hemos explicado más arriba, la aplicación deberá imitar (o mejorar, en la medida de lo posible) a las herramientas de construcción de instaladores más
conocidas hoy en día. En concreto, estará inspirada por IzPack, de modo que ambas estén desarrolladas en lenguaje Java y recojan las opciones que puedan estar disponibles
en las instalaciones mediante la lectura de ficheros XML. Un aspecto que nuestra aplicación mejorará con respecto a IzPack es dar la opción al usuario que instalará el programa de instalar en su equipo la máquina virtual de Java, necesaria para el correcto
funcionamiento del creador de instaladores, en caso de no disponer de ella.
Entregables
Una vez que el proyecto esté terminado y listo para entregar, tendrán que estar finalizados los siguientes entregables:
Ficheros en Java de la aplicación (creador de instaladores), junto con un script
que ponga en ejecución los archivos compilados, las instrucciones de uso en un
fichero en formato de texto y el resto de archivos necesarios para su correcta
ejecución. Todo esto será entregado, precisamente, en forma de un instalador
creado por la misma aplicación.
Memoria del proyecto.
Presentación del proyecto preparada.
10
Actividades de apoyo
Será valiosa una buena documentación sobre:
XML.
Java y C++.
JDom.
Swing/AWT (para la interfaz gráfica del instalador).
4.1.3.
Recursos humanos, personal y plan de comunicaciones
En este punto se explicará qué roles desempeñan las personas que participan en el
proyecto, así como las obligaciones que deben cumplir y las decisiones que deben
tomar.
Conexiones del proyecto
Estas son las personas que participarán en el proyecto, de forma directa o indirecta:
Miguel Marañón: Director y desarrollador del proyecto.
o Decisiones a tomar: todas.
o Dedicación: completa.
Julio Rubio: Tutor de la Facultad.
o Decisiones a tomar: cualquiera, en caso de que lo estime oportuno.
o Dedicación: esporádica (solo en caso de que su intervención en el Proyecto
Fin de Carrera –de aquí en adelante, PFC –sea necesaria).
Jónathan Heras Vicente: Miembro del Departamento de Matemáticas y Computación de la Universidad de La Rioja.
o Decisiones a tomar: ninguna que afecte al desarrollo del proyecto, pues colaborará desinteresadamente como consejero y supuesto “cliente” de mi
aplicación.
o Dedicación: esporádica, siempre que él quiera.
Miembros del tribunal evaluador: Grupo de profesores que evaluarán el PFC.
o Decisiones a tomar: la nota final del proyecto.
o Dedicación: solamente lo necesario para evaluar el proyecto y acudir a la
defensa del PFC.
Plan de dirección del personal
Yo soy el director del proyecto; por consiguiente, las decisiones finales serán tomadas
por mí, sea cual sea su naturaleza. No obstante, Julio Rubio aconsejará cuando él lo
considere oportuno o cuando yo lo solicite.
11
Plan de comunicaciones
Las herramientas que se emplearán para la comunicación dentro del PFC son:
Reuniones: Servirán de comunicación entre Julio Rubio (tutor académico) y yo.
En ellas se tomarán las decisiones relativas al proyecto y se tratarán los aspectos más trascendentes.
Correo electrónico.
Defensa: Se utilizará una presentación de 30 minutos de duración máxima para
comunicar al Tribunal evaluador los aspectos más relevantes del proyecto. En
ella se utilizarán medios como transparencias y una demostración “en vivo” de
las características de la aplicación.
4.1.4.
Dirección de riesgos
En este apartado se identificarán las fuentes principales de riesgo y se creará un plan a
seguir.
Fuentes de riesgo
A continuación se enumerarán las fuentes de riesgo identificadas para este proyecto.
1. La poca experiencia en el desarrollo de proyectos es una fuente de riesgo potencial. Hasta este momento, el alumno sólo tiene experiencia en realizar trabajos de
índole informática a menor escala, no habiendo ninguno que alcance la magnitud
de este proyecto. Con mucha seguridad, esta inexperiencia ocasionará diversos fallos en todos los aspectos relativos al proyecto: planificación, diseño, análisis…
2. La estimación de las fechas para las actividades que conforman el proyecto puede
no ser la adecuada, ya que el alumno no podrá tener dedicación exclusiva al mismo
hasta mediados del mes de junio de 2010. Esto hará que el alumno sólo pueda trabajar una media de 15 horas semanales, las cuales pueden llegar a ser insuficientes, provocando el consiguiente retraso en las tareas programadas.
3. El diseño realizado por el alumno puede no ser óptimo. Puede haber algunos cambios en el diseño que ocasionen rehacer necesariamente el trabajo.
4. Puede haber problemas software ocasionados por la incorrecta manipulación de
las herramientas disponibles. Dicho riesgo se centra sobre todo en la utilización de
las variables de entorno del sistema PATH y CLASSPATH. El uso indebido de estas
variables puede ocasionar la incorrecta ejecución de algunos comandos, tanto de
Java como del sistema operativo Windows.
5. Al disponer el alumno de un periodo relativamente pequeño de tiempo (que no llega a los 9 meses), hay riesgo de que el alumno caiga enfermo o sufra algún percance que le impida trabajar en el proyecto dentro de los plazos estimados.
12
Síntomas de riesgo
Al detectar alguno de estos síntomas se activará inmediatamente el plan de
contingencia.
1. Continuos errores que impiden avanzar en el desarrollo del proyecto en las fechas
planificadas.
2. A medida que el proyecto avanza, puede haber un continuo retraso en la finalización de paquetes de trabajo que nos haga pensar que tal vez la estimación de las
fechas que se había realizado no era la correcta.
3. En tiempo de diseño se realizará una exhaustiva revisión del mismo. Es entonces
cuando se decidirá si remodelar el diseño o dejarlo como está.
4. Es sencillo percatarse del incorrecto funcionamiento de las herramientas utilizadas,
pues esto impide por completo la ejecución de la aplicación.
5. Síntomas de enfermedad, aparte de los propios síntomas médicos, pueden ser el
descenso de la productividad y el uso continuo de trabajo excesivo sin poder llegar
a tiempo a las fechas planificadas.
Cuantificación de los riesgos
Cada fuente de riesgo tendrá una diferente evaluación: desde una fuente de riesgo potencial cuyo daño se considerará elevado hasta una fuente de riesgo cuyo daño se considerará mínimo.
1. El rumbo del proyecto, debido a los continuos informes semanales del alumno, va a
estar siempre bajo la supervisión de Julio Rubio, por lo que el riesgo en este aspecto es pequeño: si Julio Rubio detectara alguna anomalía lo suficientemente grave
como para poner en compromiso toda la estimación realizada, informará de inmediato con el fin de que el alumno pueda corregir a tiempo.
2. La estimación de fechas realizada para las actividades que conforman el proyecto
puede no ser la apropiada. Hay que recordar que el alumno no puede trabajar a
tiempo completo en el proyecto hasta el mes de junio de 2010, de modo que las
horas que dedique al proyecto durante el curso académico pueden no ser
suficientes.
3. Un cambio en el diseño a destiempo es un riesgo bastante grave, ya que puede suponer que el trabajo de varios meses caiga en saco roto.
4. Podemos suponer que el riesgo relacionado con el uso indebido de las variables de
entorno es de tipo medio-alto, ya que podría suponer la imposibilidad de poder
ejecutar en la máquina afectada el proyecto hasta no descubrir el origen real del
error.
5. Ya que la incapacidad física del alumno puede ser prolongada o no, este punto será
considerado de riesgo medio en el proyecto.
13
Plan de contingencia
Para cada fuente de riesgo identificada se actuará según lo descrito en este punto.
1. Se pedirá una reunión con Julio Rubio con el fin de que pueda reorientar al alumno
según crea conveniente.
2. Se realizará un cambio en la estimación de las fechas en el plan del proyecto, intentando que las nuevas sean más acordes a la realidad que se está observando. Los
motivos por los cuales se habrá realizado el cambio serán tomados en cuenta en un
futuro, con el fin de evitar caer en los mismos errores.
3. Si se detectara que el diseño es incorrecto, el alumno realizará los cambios que
estime oportunos antes de comenzar la implementación.
4. Si se detectaran problemas con las herramientas de software, el alumno deberá
tratar de resolverlos en primera instancia, siendo consciente de las posibles fuentes de origen del error. Si después de un tiempo considerable el alumno no hubiera conseguido solventar sus problemas y además éstos le supusieran un grave impedimento para seguir con la realización del proyecto, será al fin Julio Rubio el que
tomará cartas en el asunto.
5. La principal medida de contingencia frente al agotamiento consistirá en ir reduciendo paulatinamente todas las funciones que no se consideren críticas para el
sistema.
4.1.5.
Planificación del proyecto
En primer lugar, es necesario indicar que la evolución de este proyecto se basará en la
sucesiva repetición de dos actividades mientras se esté elaborando, a saber:
1. Estudio de una de las funcionalidades del creador de instaladores IzPack.
2. Desarrollo de una nueva versión del generador de instaladores que incluya esta nueva funcionalidad, de modo que se realicen para dicha versión las pertinentes fases de análisis, diseño e implementación.
Por tanto, el método de trabajo que seguiré consistirá en la elaboración de prototipos
un poco más completos en cada iteración, los cuales incluirán o mejorarán alguna de
las características que proporciona IzPack. Este método de trabajo es muy similar al conocido como AGILE Extreme Programming, que se basa más en la adaptabilidad que
en la previsibilidad y que busca acercarse al producto final a través de sucesivas aproximaciones y continuos cambios en los requisitos.
La razón por la que se eligió este modo de trabajo es el desconocimiento a priori de las
funcionalidades del IzPack, pues no olvidemos que el objetivo final es la elaboración de
un creador de instaladores que emule o mejore a ese programa. Estas funcionalidades
se irán descubriendo a lo largo del desarrollo del proyecto, de modo que cada pequeña
iteración dentro de su ciclo de vida deba su existencia a la nueva funcionalidad.
14
PT003 Documentación
Este paquete contendrá toda la documentación que se precisa para realizar el proyecto. En ocasiones, será necesario realizar alguna investigación o ser partícipe de algún
tipo de aprendizaje; en esos casos, las actividades de este paquete realizarán dicha
labor.
A0030 Identificación de fuentes y búsqueda de los datos necesarios.
A0031 Lectura y aprendizaje.
PT010 Captura / Identificación de requisitos y análisis
Este paquete incluye el estudio y el análisis de las características y funcionalidades de
IzPack para que puedan ser diseñadas e implementadas más adelante. Actividades:
A0100 Estudio de las funcionalidades de IzPack.
A0101 Extracción de los requisitos que se deben implementar.
A0102 Análisis de los requisitos.
PT020 Diseño de la implementación
Este paquete de trabajo realizará el diseño de los requisitos para estudiar el modo en
el que serán implementados. Actividades:
A0200 Realización o modificación de la estructura de las clases.
A0201 Estudio de los flujos de actividad.
PT021 Revisión del diseño
Revisión de los modelos realizados por si existen errores o irregularidades en ellos, con
el fin de que puedan ser corregidos. Actividades:
A0210 Estudio de los diseños.
A0211 Corrección e introducción de los cambios (si fuese necesario).
PT030 Elección de las herramientas
Este paquete incluye el estudio que determina las herramientas de desarrollo que se
van a utilizar a lo largo del PFC. Actividades:
A0300 Consulta y estudio de posibles herramientas.
A0301 Elección de las herramientas.
PT031 Desarrollo de la implementación
El paquete se encargará de la implementación de los diseños realizados para cada funcionalidad que se desea añadir a la aplicación. Será sin duda uno de los más costosos
en el tiempo y esfuerzo invertidos, puesto que podrían aparecer errores de programación inesperados o que sean debidos a una causa difícil de detectar.
A0310 Implementación de las nuevas funcionalidades.
PT032 Revisión de la implementación
Se considera imprescindible una revisión de la implementación que se ha hecho, con el
fin de corregir los errores que se hayan podido encontrar en el código de la aplicación
o mejorarlo. Actividades:
A0320 Análisis del funcionamiento de los requisitos implementados.
A0321 Realización de los cambios y/o mejoras oportunos (si procede).
17
PT040 Elección de las pruebas
Diseño de las pruebas que se realizarán para comprobar el buen funcionamiento del
sistema, escogiendo los casos más susceptibles de poseer fallos. Se realizará un listado
de pruebas, detallando en cada una los posibles datos de entrada con sus correspondientes salidas esperadas. Actividades:
A0400 Estudio de los requisitos.
A0401 Listado de las pruebas.
PT041 Ejecución de las pruebas
Ejecución de las pruebas diseñadas y enumeradas en el paquete PT040. Actividades:
A0410 Ejecución funcional de las pruebas.
A0411 Registro de los resultados obtenidos en las pruebas.
Calendario de trabajo
Puesto que durante el curso 2009/2010 estaré estudiando el último curso de la doble
titulación (Ingeniería Técnica en Informática de Gestión + Licenciatura en Matemáticas), no podré dedicarme de forma exclusiva al proyecto hasta, por lo menos, el día 21
de junio, momento en el que terminan los exámenes del segundo cuatrimestre. Hasta
esa fecha, mi dedicación al PFC será parcial, combinándola con el estudio de las asignaturas de los cursos a los que me he referido antes. De hecho, habrá periodos en los
que incluso deje de invertir tiempo en el PFC ante la proximidad de los exámenes. Esto,
por tanto, hace que sea muy probable que no pueda terminar el proyecto hasta mediados de julio.
La Figura 4 representa el esquema del calendario de trabajo. En naranja se representan los días de “dedicación parcial” al proyecto, en azul los días de “dedicación completa”, en blanco los días en los que, presumiblemente, no pueda dedicarme al proyecto y
en verde los días a los que se puede extender la elaboración del PFC (durante los que
se supone que mi dedicación será total).
18
4.2. Análisis
4.2.1.
Análisis de requisitos
Se pretende construir un creador de instaladores que sea capaz de permitir la construcción y configuración de cualquier tipo de instalador, independientemente del programa para el que se quiera fabricar. Es deseable que el creador de instaladores proporcione una funcionalidad similar a la que tiene la aplicación IzPack (otro creador de
instaladores de código abierto); esto es, que sea capaz de permitirle al usuario:
Indicar el nombre que tendrá el archivo de instalación.
Definir el directorio en el que se instalará el programa.
Indicar los archivos de la instalación que se copiarán en el directorio de destino, sin
importar su ubicación u organización dentro del sistema en el momento de la creación del instalador.
Ordenar la creación de un nuevo grupo de programas dentro del menú Inicio de
Windows con los accesos directos a los archivos de la instalación que se deseen,
cuyo nombre también podrá ser definido.
Crear accesos directos durante la instalación a cualquier directorio o archivo en el
escritorio, en la carpeta de programas, en la carpeta de aplicaciones o en la carpeta
de inicio del menú Inicio.
Indicar si la instalación será válida para todos los usuarios del equipo o sólo para el
que ha iniciado la sesión.
Proporcionar un desinstalador que gestione la eliminación de los archivos de la
aplicación del sistema y de los valores del registro de Windows relacionados con
ella cuando éste se ejecute, así como incorporar un icono que aparezca en el acceso directo de este desinstalador (y otros iconos que estén vinculados a otros accesos directos).
Modificar el registro de Windows con los datos pertinentes relativos a la aplicación
durante la instalación, o usando opciones por defecto o bien dando la posibilidad
de hacerlo de forma libre, a gusto del usuario.
Incluir ejecutables (archivos léeme, instalaciones externas, etcétera) que se pongan
en funcionamiento al finalizar la instalación.
Definir los paquetes (grupos) de archivos que crea oportunos, definiéndose paquete de archivos como un conjunto de archivos que se instalan como un todo: si uno
de ellos se acaba instalando, los demás también.
Además, el creador de instaladores tendrá que ser capaz de proporcionar el instalador
en forma de ejecutable auto-extraíble, el cual deberá gestionar la descompresión de
los archivos incluidos en la instalación, ejecutarla, modificar adecuadamente el registro
de Windows y posteriormente eliminar los archivos descomprimidos (como consigue
hacer IzPack). También se requiere que el instalador incorpore la instalación de la JRE
de Java, con el fin de instalarla en caso de que el equipo del usuario que ejecutará la
instalación final no disponga aún de ninguna versión de ella.
21
Por otro lado, el usuario que ejecute la instalación al final deberá ser igualmente capaz
de modificar ciertos parámetros para definirlos como él prefiera, a saber:
La ruta de instalación de la aplicación.
La ubicación de los accesos directos en el escritorio.
Qué paquetes (grupos de archivos) deberán instalarse.
La creación y el nombre del grupo de programas dentro del menú Inicio en el que
se crearán los accesos directos.
Los usuarios para los cuales se instalará la aplicación (sólo el actual o todos los
usuarios del equipo).
La modificación de esta información deberá hacerse posible mediante la interacción
con una interfaz sencilla de manejar y eficaz, que además muestre los parámetros por
defecto elegidos por el usuario creador de la instalación.
Tanto el proceso de creación del instalador como la instalación en sí deberán ejecutarse en un tiempo no excesivamente largo, que sea razonablemente corto.
Por último, el desinstalador creado deberá revertir los cambios producidos en el equipo por el instalador de la misma aplicación, proporcionando al usuario la posibilidad de
conservar el directorio de instalación y las propiedades de su configuración incluidas
en los archivos de desinstalación (en cuyo caso no serán eliminados).
22
4.2.2.
Casos de uso
Definir nombre instalador
Caso de uso: Definir nombre instalador
Objetivo: Permitir al usuario creador la posibilidad de indicar el nombre que llevará el
instalador.
Actores: Usuario creador (UC)
Precondiciones: El usuario está en condiciones de editar un fichero de nombre
instalador.xml, que debe ser acorde a lo especificado en el fichero instalador.dtd o
instalador.xsd.
Poscondiciones: El nombre del instalador creado deberá ser el especificado por el
usuario.
Pasos:
1. UC: Escribe el nombre del instalador en el atributo “nombre” del elemento
“instalador” del fichero instalador.xml.
2. Sistema: Guarda el nombre elegido por el usuario para asignárselo al instalador.
23
Definir archivos a copiar
Caso de uso: Definir archivos a copiar
Objetivo: Ofrecer al usuario creador la posibilidad de definir los paquetes de archivos
que se podrán instalar.
Actores: Usuario creador (UC)
Precondiciones: El UC está en condiciones de editar un fichero de nombre
instalador.xml, que debe ser acorde a lo especificado en el fichero instalador.dtd o
instalador.xsd.
Poscondiciones: Los archivos declarados por el UC estarán en disposición de ser instalados por la aplicación, dependiendo de las decisiones de los usuarios creador y final,
de forma que serán copiados en el propio directorio de la instalación.
Pasos:
1. UC: Escribe las rutas de las carpetas o archivos que se deben instalar dentro del
elemento “instalador/fuentes/origen/archivo” del fichero instalador.xml.
2. Sistema: Guarda y trata la información introducida por el UC.
Extensiones:
1.1. El UC desea copiar los archivos que ha declarado en un subdirectorio de la carpeta de instalación cuando el instalador se ponga en funcionamiento.
1.1.1. UC: Escribe la ruta relativa del subdirectorio dentro de la carpeta de instalación
al
que
desea
que
se
copien
los
archivos
en
el
elemento
“instalador/fuentes/origen/destino” del fichero instalador.xml.
1.1.2. Vuelve al paso 2 del flujo normal.
24
Definir accesos directos
Caso de uso: Definir accesos directos
Objetivo: Permitir al usuario creador del instalador indicar qué ficheros de la instalación podrán tener un acceso directo, así como los lugares dentro del sistema en los
que se podrá ubicar.
Actores: Usuario creador (UC)
Precondiciones: El usuario está en condiciones de editar un fichero de nombre
instalador.xml, que debe ser acorde a lo especificado en el fichero instalador.dtd o
instalador.xsd. Además, se han debido especificar en el XML los archivos o carpetas
para los que se desean hacer los accesos directos.
Pasos:
1. Extends al caso de uso “Definir archivos a copiar”.
2. UC: Indica si desea que se cree por defecto un nuevo grupo de programas, para la
aplicación que se va a instalar, en el menú Inicio, dentro el atributo “incluir” del
elemento “instalador/lugaresInstalacion/programas” del fichero instalador.xml.
3. UC: Define qué accesos directos quiere que se creen mediante los atributos del
elemento “instalador/fuentes/origen” del paquete de archivos correspondiente,
dentro del fichero instalador.xml.
4. Sistema: Guarda y trata la información introducida por el usuario.
25
Definir paquetes
Caso de uso: Definir paquetes
Objetivo: Permitir al usuario creador definir qué paquetes de archivos tendrá la oportunidad de instalar opcionalmente el usuario final, y permitir instalarlos a éste último.
Actores: Usuario creador (UC), Usuario final (UF)
Precondiciones: El usuario está en condiciones de editar un fichero de nombre
instalador.xml, que debe ser acorde a lo especificado en el fichero instalador.dtd o
instalador.xsd. Además, se ha debido especificar en el XML qué carpetas y/o archivos
podrán ser copiados en el directorio de instalación.
Poscondiciones: Los paquetes de archivos que hayan sido elegidos finalmente por el
usuario final y aquellos archivos que no estuvieran incluidos en ningún paquete serán
instalados en el equipo, mientras que el resto no.
Pasos:
1. Extends al caso de uso “Definir archivos a copiar”.
2. UC: Define los paquetes que el usuario final tendrá la opción de instalar mediante
el subelemento “paquete” del elemento “instalador/fuentes/origen”, dentro del
fichero instalador.xml.
3. UC: Indica si el paquete declarado será instalado por defecto mediante el atributo
“defecto” del elemento “instalador/fuentes/origen/paquete”, dentro del fichero
instalador.xml.
4. Sistema: Guarda y trata la información introducida por el UC.
5. Sistema: Muestra en una interfaz al UF un formulario que le permita elegir los paquetes de archivos que desea instalar, mostrando la configuración por defecto elegida por el usuario creador.
6. UF: Selecciona (o deselecciona) los paquetes de archivos.
7. Detecta y guarda la información introducida por el UF.
26
Definir accesos directos menú Inicio y escritorio
Caso de uso: Definir accesos directos menú Inicio y escritorio
Objetivo: Permitir al usuario que ejecutará la instalación indicar si quiere que aparezcan accesos directos en el escritorio de aquellos ficheros que los admitan, según la
decisión del usuario creador, y si desea que se cree un nuevo grupo de programas que
incluya los accesos directos a los ficheros de la misma aplicación que deban aparecer
allí.
Actores: Usuario final (UF)
Precondiciones: El usuario creador ha definido previamente los archivos para los que
el instalador creará accesos directos.
Poscondiciones: El instalador deberá crear en las ubicaciones indicadas por el UF (escritorio, menú Inicio, ambas o ninguna) los accesos directos definidos por el usuario
creador. Si se eligió la opción “menú Inicio”, además tendrá que crear el grupo de programas correspondiente dentro del menú Inicio.
Pasos:
1. Herencia del caso de uso “Definir accesos directos”.
2. Sistema: Muestra en una interfaz al UF un formulario que le permita elegir instalar
accesos directos en el escritorio o en el menú Inicio (o en ambas ubicaciones),
mostrando la configuración por defecto elegida por el usuario creador.
3. UF: Selecciona (o deselecciona) las ubicaciones en las que desea que se creen los
accesos directos.
4. Detecta y guarda la información introducida por el UF.
27
Definir usuarios finales
Caso de uso: Definir usuarios finales
Objetivo: Permitir al usuario creador elegir por defecto qué usuarios del equipo en el
que se llevará a cabo la instalación tendrán a su disposición la aplicación que se desea
instalar, así como facilitar la elección definitiva al usuario final.
Actores: Usuario creador (UC), Usuario final (UF)
Precondiciones: El UC está en condiciones de editar un fichero de nombre
instalador.xml, que debe ser acorde a lo especificado en el fichero instalador.dtd o
instalador.xsd.
Poscondiciones: La instalación afectará a los usuarios definidos por el UF.
Pasos:
1. UC: Define los usuarios por defecto de la instalación mediante el atributo “todos”
del elemento “instalador/usuarios” del fichero instalador.xml.
2. Sistema: Guarda y trata la información introducida por el UC.
3. Sistema: Muestra en una interfaz un formulario que permita al UF decidir para qué
usuarios (el actual o todos) se instalará la aplicación, mostrando la configuración
por defecto elegida por el usuario creador.
4. UF: Selecciona los usuarios de la instalación.
5. Sistema: Detecta y guarda los usuarios de la instalación.
28
Definir iconos
Caso de uso: Definir iconos
Objetivo: Permitir al usuario creador declarar los iconos que acompañarán a los accesos directos que se hayan definido previamente.
Actores: Usuario creador (UC)
Precondiciones: El usuario está en condiciones de editar un fichero de nombre
instalador.xml, que debe ser acorde a lo especificado en el fichero instalador.dtd.
Además, se han debido especificar en el XML qué carpetas y/o archivos tendrán asociado un acceso directo.
Poscondiciones: Los iconos definidos por el usuario acompañarán a los accesos directos a los que están vinculados tras la instalación.
Pasos:
1. Extends al caso de uso “Definir accesos directos”.
2. UC: Define los iconos que acompañarán a los accesos directos mediante el subelemento “icono” del elemento “instalador/fuentes/origen” del paquete de archivos
correspondiente, dentro del fichero instalador.xml.
3. UC: Define el icono que acompañará al acceso directo del desinstalador mediante
el subelemento “icono” del elemento “instalador/desinstalador”, dentro del fichero instalador.xml.
4. Sistema: Guarda y trata la información introducida por el UC.
Extensiones:
3.1. El UC no define ningún icono para el acceso directo del desinstalador.
3.1.1. UC: Deja vacío el subelemento “icono” del elemento “instalador/desinstalador”.
3.1.2. Vuelve al paso 4 del flujo normal.
29
Definir ruta instalación
Caso de uso: Definir ruta instalación
Objetivo: Permitir al usuario creador elegir la ruta de instalación en la que por defecto
se copiarán los archivos de la aplicación que se desea instalar, así como facilitar al
usuario final la elección definitiva de esta ruta.
Actores: Usuario creador (UC), Usuario final (UF)
Precondiciones: El usuario creador está en condiciones de editar un fichero de nombre instalador.xml, que debe ser acorde a lo especificado en el fichero instalador.dtd
o instalador.xsd.
Poscondiciones: El instalador deberá copiar los archivos de la instalación en el directorio indicado.
Pasos:
1. UC: Define la ruta en la que se copiarán los archivos de la instalación en el subelemento “destino” del elemento “instalador/lugaresInstalacion” del fichero
instalador.xml.
2. Sistema: Guarda y trata la ruta introducida por el UC.
3. Sistema: Muestra en una interfaz al UF un campo con el nombre de la ruta elegida
por defecto por el UC, de modo que el UF pueda cambiarla si lo desea.
4. UF: Cambia, si así lo desea, la ruta de instalación.
5. Sistema: Detecta y guarda la ruta de la instalación.
30
Definir grupo programas
Caso de uso: Definir grupo programas
Objetivo: Permite al usuario creador asignar un nombre por defecto al nuevo grupo
de programas en el que se instalarán los accesos directos que se hayan definido para
los ficheros de la instalación en caso de que el usuario final ordene crearlo, así como
al usuario final elegir el nombre definitivo de este grupo de programas en el que se
copiarán finalmente los accesos directos. El nombre seleccionado será también el del
directorio de instalación.
Actores: Usuario creador (UC), Usuario final (UF)
Precondiciones: El usuario creador está en condiciones de editar un fichero de nombre instalador.xml, que debe ser acorde a lo especificado en el fichero instalador.dtd
o instalador.xsd.
Poscondiciones: El instalador creará los accesos directos especificados en el grupo de
programas determinado por el UF.
Pasos:
1. UC: Indica el nombre que llevará por defecto el grupo de programas que se creará durante la instalación en el menú Inicio (que será el mismo que el de la carpeta de instalación) en el elemento “instalador/lugaresInstalacion/programas” del
fichero instalador.xml.
2. Sistema: Guarda y trata los datos introducidos por el UC.
3. Sistema: Muestra al UF el grupo de programas elegido por defecto, de tal forma
que lo pueda cambiar.
4. UF: Elige el nombre del grupo de programas (bien sea uno nuevo u otro existente) del menú Inicio en el que se instalarán los accesos directos.
5. Detecta y guarda el grupo de programas seleccionado.
31
Definir modificación registro
Caso de uso: Definir modificación registro
Objetivo: Permitir al usuario creador definir el modo en el que se modificará el registro de Windows tras la instalación de la aplicación.
Actores: Usuario creador (UC)
Precondiciones: El usuario está en condiciones de editar un fichero de nombre
instalador.xml, que debe ser acorde a lo especificado en el fichero instalador.dtd o
instalador.xsd.
Poscondiciones: El instalador deberá modificar el registro de Windows de acuerdo a
la información suministrada por el UC.
Pasos:
1. UC: Escribe “Yes” en el atributo “modificar” del elemento
“instalador/lugaresInstalacion/registro” del fichero instalador.xml.
2. UC: Define las modificaciones que se deberán llevar a cabo en el registro de
Windows durante la instalación mediante los atributos y subelementos pertenecientes a los subelementos “instalacion” y “desinstalacion” del elemento
“instalador/lugaresInstalacion/registro” del fichero instalador.xml.
3. Sistema: Guarda y trata los datos introducidos por el UC.
Extensiones:
1.1. El UC no desea realizar ninguna modificación en el registro.
1.1.1. UC: Escribe “No” en el atributo “modificar” del elemento
“instalador/lugaresInstalacion/registro” del fichero instalador.xml.
1.1.2. Fin del caso de uso.
2.1. El UC desea personalizar la modificación del registro.
2.1.1. UC: Define las modificaciones que se deberán llevar a cabo en el registro de
Windows durante la instalación mediante los atributos pertenecientes al subelemento
“customize” del elemento “instalador/lugaresInstalacion/registro” del fichero
instalador.xml.
2.1.2. Vuelve al paso 3 del flujo normal.
32
Definir archivos auto-ejecutables
Caso de uso: Definir archivos auto-ejecutables
Objetivo: Dar la oportunidad al usuario creador de incluir en la instalación aquellos archivos externos auto-ejecutables que se deberán ejecutar en el transcurso de ésta
(otras instalaciones, ficheros de texto, etcétera).
Actores: Usuario creador (UC)
Precondiciones: El usuario está en condiciones de editar un fichero de nombre
instalador.xml, que debe ser acorde a lo especificado en el fichero instalador.dtd o
instalador.xsd.
Poscondiciones: El instalador deberá ejecutar al final de la instalación los autoejecutables definidos por el UC.
Pasos:
1. UC: Define los archivos que se ejecutarán al final de la instalación mediante el elemento “instalador/ejecutable” del fichero instalador.xml.
2. UC: Para cada uno de los archivos ejecutables, indica (si fuera necesario) con qué
programa se abre mediante el atributo “prog” del elemento
“instalador/ejecutable”.
3. Sistema: Guarda y trata la información introducida por el UC.
33
Ejecutar instalador
Caso de uso: Ejecutar instalador
Objetivo: Llevar a cabo la instalación de la aplicación, de modo que se cree un archivo
que gestione su posible desinstalación posterior.
Actores: Usuario final (UF)
Precondiciones: El instalador ha sido creado con las características definidas por el
usuario final y el usuario creador.
Poscondiciones: Se llevará a cabo la instalación.
Pasos:
1. UF: Hace doble clic sobre el fichero auto-ejecutable de la instalación.
2. Sistema: Descomprime los archivos a copiar, lleva a cabo la instalación y gestiona
la eliminación de los archivos que fueron necesarios durante el proceso.
34
4.2.3.
Diagrama de casos de uso
Figura 6: Diagrama de casos de uso
35
4.3. Diseño
En este apartado se describirán las soluciones y los procedimientos que se van a adoptar para satisfacer los requisitos descritos en el análisis, referentes a la aplicación que
estamos desarrollado: el creador de instaladores. La solución propuesta será válida solo para algunos de los sistemas operativos más recientes de Windows.
Esta solución está basada en la construcción de dos clases Java: Creador_instaladores
y Construct. La primera clase es la que contiene al método main, por lo que deberá hacer referencia a la clase Construct (cuyos métodos servirán para llevar a cabo la ejecución completa del programa) y será la encargada de dirigir el flujo principal del programa. Además, esta clase tendrá que leer los datos que se encuentren en el fichero
Instalador.xml, los cuales definirán la configuración de la instalación que haya elegido
el usuario creador. Por otro lado, la clase Construct se encargará de la construcción,
compilación y ejecución de los ficheros necesarios para poner en marcha el instalador.
Estas dos clases serán descritas con mucho más detalle posteriormente en esta
sección.
La filosofía de trabajo consiste en la creación y compilación del código necesario a partir de estos ficheros iniciales para conseguir la construcción del instalador, en forma de
archivo auto-extraíble fácilmente utilizable por el usuario final. Esto significa que los ficheros descritos hasta ahora elaborarán otros ficheros y archivos “extra”, cuya compilación y ejecución dará lugar a la ejecución del instalador definitivo. A pesar de que el
lenguaje de programación preferido para realizar este proyecto es Java (debido a que
es fácil de compilar y ejecutar, además de ser muy conocido), el lenguaje del código
generado variará en función de la necesidad o la comodidad de lo que se quiera hacer
en cada momento: cuando una tarea sea inviable o muy difícil de realizar en Java, se
creará código en otros lenguajes de programación que nos proporcionen alternativas
posibles o más sencillas con el fin de conseguir su ejecución sin más problema. Además
del lenguaje Java (el predeterminado), se utilizará C++ y el propio lenguaje de la shell
de Windows (pudiéndose de este modo construir archivos .bat, ejecutables por lotes).
Además de estos archivos, se deberán aportar otros tres más para obtener la correcta
y completa ejecución del proyecto. Uno de ellos ya ha sido mencionado: el
Instalador.xml, que se encargará de recoger la información de la configuración de la
instalación definida por el usuario creador. Puesto que es el propio usuario creador el
que debería encargarse de su edición, debido a nuestra decisión de no implementar
ninguna interfaz para este usuario, nos veremos obligados a incluir en nuestra aplicación una plantilla (de nombre plantilla.xml) que muestre con la mayor fidelidad posible la estructura del XML asociado a este archivo (la cual se describe con los ficheros
Instalador.dtd e Instalador.xsd, y con el esquema XML-Schema correspondiente).
36
Otro archivo “extra” que se incluirá es el llamado Make.bat, archivo ejecutable por
lotes de Windows que añadirá al CLASSPATH las rutas requeridas para que se ejecute
el programa, ejecutará los archivos iniciales antes descritos (Creador_instaladores.class
y Construct.class) y completará la ejecución de algunas tareas de creación y compresión de archivos necesarias para la creación del archivo que llevará a cabo la instalación definitiva.
El tercer archivo, InterfazGrafica.java, proporcionará el código fuente de la interfaz
del usuario final. Este código se encargará de guardar en las variables de la clase
Instalador la información introducida por el usuario que ejecuta el instalador, de modo
que le permitirá cambiar algunos aspectos de la configuración elegida por defecto por
el usuario creador del instalador de forma cómoda. La clase InterfazGrafica se compilará a la vez que la clase Instalador, por lo que no es necesario incluir en la carpeta de
nuestra aplicación los ficheros binarios referentes a la clase InterfazGrafica.
Sin más dilación, pasemos a estudiar con más detenimiento las funciones desempeñadas por las clases mencionadas, así como las de los archivos construidos a partir de
ellas.
4.3.1.
Descripción de la clase Creador_instaladores
Clase que contendrá al método principal y leerá los datos almacenados en el fichero
Instalador.xml. Por esto último, es necesario que importe las librerías org.jdom,
org.jdom.input y org.jdom.output. Además, usará la clase SAXBuilder con el fin de cargar en memoria el árbol de elementos del fichero XML que necesita leer.
Después de cargar el XML, la clase gestionará la lectura de los datos pertinentes. Éstos
serán almacenados en diferentes variables para ser utilizados posteriormente en el
constructor de la clase Construct. Una vez creado un objeto de esta clase, se invocará a
los métodos que posea, ya que éstos serán los encargados de construir el código del
instalador y del desinstalador, así como del resto de archivos que se precisan para
compilarlos, comprimirlos, ejecutarlos, etcétera.
Los métodos de esta clase se describen a continuación:
leerOrigen (Document) devuelve List: devuelve una lista que contiene a los archivos que se desean instalar, así como la ruta dentro del directorio de instalación en
la que se copiarán, el icono asociado a su acceso directo (si existe) y el paquete de
archivos al que pertenecen (en caso de que se declare).
leerDestino (Document) devuelve String: devuelve la ruta por defecto en la que el
directorio de la instalación será creado.
leerInstalador (Document) devuelve String: devuelve el nombre que tendrá el
instalador.
leerPrograma (Document) devuelve String: devuelve el nombre que tendrá por defecto el grupo de programas dentro del menú Inicio en el que se crearán los accesos directos del programa que se instalará. Además, también será el nombre que
recibirá la carpeta de instalación.
37
incluirPrograma (Document) devuelve String: devuelve “Yes” si el usuario creador
desea ordenar por defecto la creación de un grupo de programas en el menú Inicio
en el que incluir accesos directos; “No”, en otro caso.
leerUsuarios (Document) devuelve String: devuelve “Yes” si se desea que la aplicación se instale por defecto para todos los usuarios del equipo; “No”, si tan solo se
requiere para el usuario que ha iniciado la sesión.
leerDesinstalador (Document) devuelve String: devuelve la ubicación del icono
con el que se representará el acceso directo del instalador. En caso de que el usuario creador no haya definido ningún icono para el desinstalador, devolverá null.
leerRegistro (Document) devuelve List: devuelve una lista con toda la información
relativa a la modificación que se hará del registro una vez haya sido iniciada la
instalación.
leerEjecutables (Document) devuelve List: devuelve una lista con los ejecutables
que se deberán inicializar una vez finalizada la instalación. Estos ejecutables pueden ser instalaciones de programas complementarios, ficheros de texto (estilo
readme), etc. Para cada ejecutable, se incluye el programa con el que se deben
abrir dichos archivos (si fuese necesario).
4.3.2.
Descripción de la clase Construct
Esta es la clase más importante de la aplicación. Sus funciones son las que a continuación se muestran:
Generar el código de los archivos Instalador.java y Desinstalador.java.
Generar el ejecutable .exe que comprimirá todos los archivos y ejecutará la instalación. Para ello, creará complementariamente un archivo que colabore en la creación del ejecutable: temp.bat.
Generar los ficheros manifest. Estos ficheros son muy útiles cuando se van a construir ficheros .jar que contendrán las clases que se ejecutarán. Su función es indicar
cuál es la clase que contiene el método principal para que sea ejecutada cuando se
invoque al jar (bien mediante doble clic o por línea de comandos).
Compilar los archivos Instalador.java y Desinstalador.java. Esto provocará la aparición de dos ficheros .class, con el código binario de estas dos clases.
Generar el archivo install.properties, necesario para guardar las preferencias de instalación del usuario final. Esto permitirá al desinstalador encontrar la información
necesaria para revertir los cambios producidos en el sistema durante la instalación.
El archivo install.properties también servirá para mostrar al usuario final los parámetros de la instalación elegidos por defecto por el usuario creador.
Vamos a describir qué hace exactamente cada método de esta clase, comenzando por
el constructor.
38
Constructor:
Se encarga de recoger la información proveniente de la clase Creador_instaladores
y de almacenarla en las variables adecuadas. En primer lugar, construye una lista
que almacenará la información de los archivos que se usarán en la instalación. Para
ello, usará varios vectores de datos:
-Un vector para almacenar qué archivos tendrán acceso directo en el grupo de programas que se cree para la aplicación durante la instalación, otro para indicar cuáles lo tendrán en el escritorio y otros tres más para indicar lo mismo con respecto a
la carpeta de inicio, la carpeta de programas y la carpeta de aplicaciones, todas
pertenecientes al menú Inicio. Estos vectores almacenarán un booleano por cada
archivo, que valdrá true si el archivo va a tener un acceso directo en el lugar especificado y false en caso contrario. El orden de representación de los archivos en estos
vectores coincidirá con el que proviene de la lista definida en el constructor; de esta forma, quedará completamente determinado qué booleanos harán referencia a
qué archivos.
-Un vector para almacenar la ruta (en formato String) de los iconos que se usarán
para los accesos directos de estos archivos. Los archivos para los que no se haya
definido ningún acceso directo llevarán un null en su correspondiente componente
del vector.
-Otro vector para indicar la ruta de los archivos dentro del directorio de instalación.
Esta información es útil en determinados casos para copiar archivos dentro de un
subdirectorio de la carpeta de instalación. Nuevamente, si esta información no es
necesaria para un determinado archivo, su correspondiente componente en este
vector valdrá null.
-Dos vectores más para almacenar los paquetes de archivos que el usuario final
tendrá la opción de instalar y cuáles de esos paquetes se instalarían por defecto,
según la decisión del usuario creador.
Tras esto, el constructor guarda en los atributos de la clase el resto de la información de la configuración del instalador: la ruta de la carpeta de instalación, el nombre del instalador, el nombre del grupo de programas del menú Inicio relativo a la
aplicación que se deseará instalar (que será el mismo que el que tenga la carpeta
de instalación), para qué usuarios se instalará la aplicación (todos o solamente el
que haya iniciado sesión), si se creará un nuevo grupo de programas para la aplicación en el que incluir accesos directos, el icono que acompañará al acceso directo
del desinstalador (null si no existiese tal icono) y los programas que se ejecutarán
como complemento después de la instalación (instaladores externos, archivos
readme, etcétera). Conviene recordar que algunos de estos parámetros no son definitivos, pues serán revisados por el usuario final (el que ejecute la instalación en
última instancia). Además, el constructor elaborará a partir de esta información las
rutas dentro del sistema del menú Inicio, del escritorio y de las carpetas de aplicaciones, inicio y del grupo de programas de la aplicación dentro del menú Inicio.
39
Por último, el constructor construye las estructuras que almacenarán la información sobre la modificación del registro de Windows. Para ello, comprueba en primer lugar que el usuario desea modificar el registro a partir del atributo correspondiente al fichero XML leído: si su valor es “Yes”, construirá las estructuras necesarias para almacenar esta información; si es “No”, terminará en ese momento su labor. En caso de que se desee modificar el registro, el constructor contará con un
vector de cadenas de texto cuyas componentes guardarán los datos relativos a los
siguientes elementos y atributos del fichero Instalador.xml:
Componente
0
1
2
3
4
5
6
7
8
Elemento
Instalacion
Desinstalacion
Desinstalacion
Desinstalacion
Desinstalacion
Desinstalacion
Desinstalacion
Desinstalacion
Desinstalacion
Atributo
InstallDir
NoModify
NoRepair
DisplayVersion
DisplayIcon
URLInfo
HelpLink
Publisher
URLUpdate
Valor
Yes/No
Yes/No
Yes/No
version
icon
url
help
pub
update
Tabla 1: Elementos y atributos para modificar el registro
Esto significa que las componentes 0, 1 y 2 podrán guardar los valores “Yes” o “No”
solamente, mientras que el resto almacenarán la cadena que contengan los elementos del XML indicados en la columna “Valor”.
El resto de la información referente a la modificación del registro habrá quedado
almacenada en un atributo de tipo List junto a lo que acabamos de describir y será
tratada más adelante en otros métodos.
generarInstalador:
Su única (aunque trascendental) función es elaborar el código de la clase
Instalador. Es por eso que el método usa una variable de tipo File, con la cual crea
el fichero de nombre Instalador.java, y otra de tipo BufferedWriter asociada a la
anterior con la que escribe en el fichero que ha creado.
Estudiemos el código que ejecutará la clase Instalador (es evidente que dicho código dependerá de los datos de configuración almacenados en la clase Construct y en
el fichero de configuración install.properties, que veremos más adelante). En primera instancia, su método principal guarda los paquetes de archivos de instalación
y genera los valores (true o false) del vector que determinará qué paquetes se instalarán finalmente. Estos valores serán true al principio y únicamente se cambiarán
a false en el momento en el que el usuario final decida no instalar el correspondiente paquete. Lo último que hace el método principal es invocar a la interfaz gráfica con la que el usuario final interactuará y que veremos con más detalle en el
apartado 4.3.6. Interfaz del usuario final.
40
La interfaz gráfica llamará al método instalar de la clase Instalador, una vez ha modificado los atributos de esta clase con los datos introducidos por el usuario final.
Inicialmente, el método crea el directorio de instalación con sus diferentes subcarpetas: una con los archivos de la aplicación, otra con los iconos de los accesos directos (de nombre Iconos) y otra con el desinstalador (de nombre Desinstalador).
Después, extrae el fichero de configuración de la instalación install.properties del
archivo Instalador.jar y lo añade al jar del desinstalador, Desinstalador.jar, con el
nombre desinstall.properties. Acto seguido, procede a copiar los archivos pertinentes en cada subcarpeta, comprobando antes qué paquetes de archivos deben instalarse: los iconos, en Iconos; el jar con el desinstalador, en Desinstalador; y el resto
de archivos definidos, en la subcarpeta restante. Para cumplir con todos estos cometidos, la clase cuenta con dos métodos privados: copiarDirectorio y
copiarFichero, de modo que pueda crear o copiar cualquier directorio, incluyendo
sus subdirectorios y ficheros, de forma recursiva. Tras esto, crea los accesos directos. Para ello, necesita la ayuda de un programa externo, Shortcut.exe, que permite
la creación de accesos directos desde la línea de comandos. Este programa ofrece
muchas funcionalidades, por lo que dispone de muchos parámetros de entrada.
Nosotros usaremos tan solo tres: el que indica cuál será la ruta completa del acceso
directo (incluyendo el nombre), el de la ruta del archivo al que apunta el acceso directo y el de la ruta en la que está situado el icono con el que se mostrará el
shortcut (si éste existiera). Puesto que estamos haciendo uso de un programa ajeno al propio que se está ejecutando en Java (por tanto, en un hilo diferente del
proceso), hemos de obligar al sistema a esperar a la finalización del programa
Shortcut.exe para proseguir con la ejecución del código de la clase cada vez que se
cree un acceso directo.
Posteriormente, la clase Instalador procede con la modificación del registro de
Windows. Para ello, necesita hacer varias llamadas al sistema, bien para crear nuevas entradas en el registro o para cambiar las ya existentes en él. Con este fin, los
parámetros que nuestra aplicación pasa a la línea de comandos son: la ruta y la clave del registro que se modificará, el valor (en forma de cadena de texto) que tendrá dicha clave y el tipo de dato que representa al formato del valor asignado a la
clave (por defecto, REG_SZ). Al igual que pasaba con los accesos directos, la llamada al sistema implica la ejecución de un nuevo hilo dentro del proceso, por lo que
vuelve a ser necesario esperar a su finalización para continuar con la ejecución del
código de la clase.
Lo mismo sucede con los ejecutables (instalaciones externas, etcétera) que se pondrán en marcha tras la instalación: habrá que esperar a que termine su ejecución.
Este será el último deber de la clase Instalador.
41
Es preciso indicar que los archivos y accesos directos que se crean, así como la modificación del registro, dependen de la información almacenada en los vectores definidos por el constructor. No obstante, los datos del registro que el usuario creador define libremente (relativos al elemento customize del fichero XML) y los programas que se ejecutan tras la instalación (provenientes del elemento ejecutable
de Instalador.xml) no quedan recogidos en ningún vector. Esta información, que es
almacenada en dos estructuras de tipo List en el constructor, será extraída directamente de estas listas en el método generarInstalador que acabamos de estudiar.
La razón por la que se ha tomado esta decisión es que las cadenas de texto almacenadas se escribirán sin ningún tipo de tratamiento adicional en el fichero
Instalador.java, por lo que no se necesita de ninguna estructura que las recoja. Esto no sucede con los demás datos, debido a motivos de comodidad durante el desarrollo de la programación o al tratamiento y mutación de la información que
representan.
Hay que recordar que aquellos parámetros que puedan ser modificados por el
usuario final no se escribirán de forma directa en el fichero Instalador.java, sino
que serán parametrizados por diferentes variables que lean en tiempo de ejecución
la información almacenada en el fichero de configuración que se creó a tal efecto.
Los métodos que se encargan de dar valores a los atributos de la clase Instalador
serán invocados por la interfaz gráfica cuando el usuario final inicie la instalación.
generarDesinstalador:
Método que genera el fichero Desinstalador.java. Evidentemente, se trata del fichero que contiene a la clase Desinstalador, la cual posee un método cuya labor será eliminar del sistema todos los archivos y registros creados por la clase Instalador
relativos a la aplicación instalada. Al igual que ocurría con el método
generarInstalador (así como con los demás métodos que faltan por describir), este
método usa una variable de tipo File, con la cual crea el fichero de nombre
Desinstalador.java, y otra de tipo BufferedWriter asociada a la anterior, con la cual
escribe en el fichero que ha creado de acuerdo a la configuración establecida por el
usuario creador del instalador.
El método principal se encarga de cargar el fichero desinstall.properties que recoge
la información que necesita el desinstalador para revertir los cambios producidos
por el instalador y de recoger esta información en los atributos de la clase. Por otro
lado, también muestra al usuario final una interfaz para confirmar la desinstalación
y que le permita indicar si desea que se elimine el directorio de instalación junto
con los archivos del desinstalador. Esto se recoge en una variable de tipo booleano,
que a su vez se pasa como parámetro al método desinstalar, que es el encargado
de llevar a cabo la desinstalación propiamente dicha.
42
El método desinstalar borra, en primer lugar, todas las carpetas y archivos creados
previamente durante la instalación de forma recursiva (de modo que es capaz de
eliminar todas las subcarpetas sin tener que hacer referencia a cada una de ellas
explícitamente en el código). Para ello, se ayuda del método recursivo
borrarDirectorio. Este método recibe como parámetro la ruta de un directorio y
elabora una lista con los archivos y directorios que posee. Después, va recorriendo
uno a uno los elementos de esta lista, de modo que si es detectado como un archivo, lo borra directamente, y si es un directorio, se invoca a sí mismo enviándolo como parámetro.
Tras esto, el método principal se encarga de eliminar las claves del registro relacionadas con la aplicación que se está desinstalando. Tanto estas claves como los archivos anteriores se han podido detectar gracias a los vectores atributos de la clase
Construct que fueron definidos en el constructor, así como al fichero de configuración creado previamente.
Por último, si el usuario final así lo quiso, el método desinstalador invoca al método
forzarEliminacion, que es utilizado para borrar la carpeta de instalación cuando se
han eliminado todos los archivos y subcarpetas que contenía, a excepción del fichero Instalador.jar y las carpetas en las que se encuentra. La estricta necesidad de este método se debe a que un fichero Java (como Instalador.jar) no puede eliminarse
a sí mismo (tendría que cerrarse primero), por lo que se ha de recurrir a la creación
de un archivo bat (ejecutable por lotes) capaz de auto-borrarse y que, a su vez, borre a los directorios anteriores; si simplemente intentáramos borrar recursivamente la carpeta de instalación, los archivos que estuvieran abiertos no se podrían eliminar. De este modo, forzarEliminacion crea un fichero de nombre destruir.bat en
el directorio C:\ que, por este orden,
o
o
o
o
Mientras exista, intenta borrar (y al final, borra) el fichero Desinstalador.jar.
Borra la carpeta contenedora de Desinstalador.jar, Desinstalador.
Borra la carpeta de instalación.
Se borra a sí mismo.
Tras la construcción de este archivo, el método forzarEliminacion hace que se ejecute en la línea de comandos. Dicho método finaliza cuando se ha hecho efectiva
esta última acción.
Cabe recordar que, al igual que ocurría con el método generarInstalador, éste tampoco escribe directamente los parámetros configurables por el usuario final en el
fichero Desinstalador.java; en su lugar, crea variables que harán referencia a esa
información, de modo que la clase cuente con ella en tiempo de ejecución.
generarEjecutable:
Método que genera el ejecutable .exe que comprimirá todos los archivos y ejecutará la instalación cuando el usuario final ponga el fichero auto-ejecutable en funcionamiento mediante doble clic.
43
En primer lugar, el método crea un fichero de nombre arch.cpp. Éste comprobará
cuando se inicialice la instalación si está instalada en el equipo alguna versión de la
máquina virtual de Java, de modo que, de no ser así, instale la Versión 6 –
Actualización 18 en este equipo (deteniéndose la instalación hasta que este proceso termine). Tras esto, iniciará la instalación, ejecutando el Instalador.jar.
Después, se genera el archivo temp.bat, que ejecutará el resto de comandos para
construir el ejecutable final: añadirá al path la ruta del programa para comprimir
los archivos (que será el 7-Zip), compilará el archivo .cpp creado anteriormente (el
programa ejecutable resultante de la compilación se llamará Setup.exe), creará los
jars correspondientes al instalador y al desinstalador (incluyendo como parámetro
los ficheros de manifiesto que se habrán elaborado), creará un fichero comprimido
que incluya a todos los archivos necesarios para la instalación (de nombre
InstallFiles.7z), eliminará los archivos añadidos al fichero comprimido, creará el ejecutable final y borrará el .7z y a él mismo.
La razón por la que se eligió el 7-Zip como programa de compresión de los archivos
se debe a la posibilidad que ofrece de crear un archivo auto-ejecutable y autoextraíble desde la línea de comandos. Para la correcta ejecución de este proceso,
es necesaria la existencia de un par de archivos en el mismo directorio de la aplicación que estamos desarrollando: el 7zS.sfx, para crear el auto-extraíble, y el
config.txt, donde se le indica al auto-extraíble cuál es el fichero que debe ejecutar
(en nuestro caso, el Setup.exe, consecuencia de la compilación del archivo
arch.cpp). Por otro lado, la explicación de por qué se determinó utilizar el lenguaje
de programación C++ a la hora de componer el arch.cpp se debe a las facilidades
que proporciona C++ para crear archivos ejecutables (algo que en Java es más
complicado).
generarManifest:
Los ficheros de manifiesto, o manifest, sirven para ejecutar una aplicación Java
comprimida en un jar. Estos ficheros contienen el nombre de la clase que contiene
al método principal (es decir, la que debe ejecutarse). El método generarManifest
se encarga de la elaboración de estos ficheros de manifiesto, así como de la compilación de los ficheros Instalador.java y Desinstalador.java a los que hacen
referencia.
generarInstallConfig:
Creará el fichero de configuración; lo que escriba en él dependerá en primera instancia de la configuración que haya elegido inicialmente el usuario creador. Este fichero permitirá a la postre que el usuario final sea capaz de cambiar la configuración decidida por el usuario creador (pues no tendrá por qué coincidir con la suya).
Todas las claves presentes en este fichero tomarán, en un primer momento, los valores recogidos en la clase Instalador a excepción de la relativa a los accesos directos en el escritorio, que tomará siempre por defecto el valor true. Las claves y su
descripción quedan recogidas en la siguiente tabla.
44
Clave
Descripción
<Nombre_paquete> Paquete a instalar. Puede haber 10 a lo sumo. Tomará valor true
si se desea instalar y false en caso contrario.
Ruta
Ruta dentro del sistema en la que se ubicará la carpeta de
instalación.
Programas
Nombre de la carpeta de instalación y del grupo de programas
de la aplicación, en caso de que se acabe creando.
Todos
Usuarios para los que será válida la instalación. Tomará valor
true si es para todos los usuarios y false en caso contrario.
Inicio
Especifica si se creará un nuevo grupo de programas para la aplicación. Tomará valor true si el usuario desea crearlo y false en
caso contrario.
Escritorio
Especifica si se crearán accesos directos en el escritorio. Tomará
valor true si así se desea y false en caso contrario. Su valor por
defecto siempre será true.
Tabla 2: Claves del fichero de configuración y su descripción
4.3.3.
Descripción del archivo Make.bat
En los anteriores métodos hemos creado un archivo, temp.bat, pero en ninguno de
ellos lo hemos ejecutado. Además, hemos usado código en C++, pero en ningún momento hemos añadido al path ningún programa que sea capaz de compilarlo. Por otro
lado, el usuario creador del instalador necesitaría ejecutar de una manera sencilla la
clase Creador_instaladores, con el fin de, una vez definida la configuración de la instalación, crear el archivo auto-ejecutable (y auto-extraíble) correspondiente. Pues bien,
esas serán las funciones del archivo Make.bat: lo único que tendrá que hacer el usuario creador para construir su instalador es hacer doble clic sobre este archivo. Estará situado en el mismo directorio de la aplicación desarrollada (junto, por ejemplo, a los archivos Config.txt y 7zS.sfx del programa 7-Zip).
45
4.3.4.
Relaciones entre los archivos de la aplicación
La siguiente ilustración (Figura 7) muestra todas las relaciones que se darán entre los
diferentes archivos que formarán parte del proceso de creación del instalador.
Figura 7: Diagrama de colaboración entre los ficheros de la aplicación
4.3.5.
Interfaz del usuario creador
Descripción
El medio mediante el que el usuario creador podrá construir su instalador consistirá en
un fichero XML que deberá ser acorde al XML-Schema representado por el siguiente
esquema (Figura 8).
46
Figura 8: XML-Schema del fichero Instalador.xml
Este otro esquema (Figura 9) recoge la información detallada del elemento del XML
lugaresInstalacion presente en el esquema general anterior.
Figura 9: XML-Schema del elemento lugaresInstalacion
47
Para mayor comodidad, el usuario creador dispondrá de una plantilla escrita en lenguaje XML cuyo contenido será válido para el XML-Schema anterior. Las modificaciones introducidas por el usuario creador al editar dicho fichero (que deberá nombrarse
como Instalador.xml) deberán seguir respetando la especificación del XML-Schema
aquí descrito.
Es necesario indicar que se consideró seriamente dentro de este proyecto la realización de una interfaz que permitiera al usuario creador construir su instalador sin necesidad de escribir ninguna línea de código XML, pero finalmente se desechó debido
principalmente a dos razones:
Las mejoras que se obtendrían en caso de implementar la interfaz no compensan el
gran esfuerzo que supondría su creación. Hay que tener en cuenta que habría que
crear pantallas que permitieran al usuario la creación de accesos directos, la posibilidad de modificar el registro de Windows, indicar qué archivos se copiarán en el directorio de instalación… lo cual se puede indicar de un modo mucho más sencillo (y
de una sola vez) en el fichero XML.
Además, no es descabellado suponer que el usuario creador tendrá los conocimientos necesarios para editar sin problemas un fichero XML con las características descritas, por lo que la solución adoptada no supondría un contratiempo demasiado
importante para él.
Precondiciones
El usuario creador encontrará a su disposición un fichero de nombre plantilla.xml que
cumplirá las especificaciones definidas en el archivo Instalador.xsd e Instalador.dtd.
Por tanto, el código XML incluido en este archivo será acorde al esquema mostrado anteriormente en este documento.
Además, el usuario creador encontrará un pequeño manual de instrucciones que le
permita editar adecuadamente el fichero Instalador.xml y trabajar con el programa.
Poscondiciones
Las modificaciones introducidas por el usuario creador al editar el anterior documento
deberán respetar la especificación del XML-Schema descrito.
Por otra parte, la aplicación deberá recoger la información introducida por el usuario
creador y guardarla con el fin de mostrarla al usuario final para que pueda ser modificada (en unos casos) o usarla directamente como parámetro cuando se construya el
instalador (en otros).
Las características que deberá tener el fichero Instalador.xml una vez haya sido editado están definidas en el manual de instrucciones del creador de instaladores, el cual se
mostrará en el Anexo I de este proyecto.
48
Diagrama de estados
Figura 13: Diagrama de estados de la interfaz del usuario final
4.4. Implementación
A continuación, a lo largo de este apartado, se indicarán cuáles fueron las principales
dificultades que hubo que superar durante el desarrollo de este proyecto con respecto
a la implementación de los requisitos según la estrategia descrita en la fase de diseño,
tanto relativas a la programación como a las técnicas específicas empleadas.
En primer lugar, es conveniente comentar que solamente encontrar un diseño adecuado para la construcción del creador de instaladores fue un tarea, de por sí, compleja,
ya que requirió, desde el primer momento, el estudio del código de otros creadores de
instaladores (como IzPack), así como de las funcionalidades que son capaces de ofrecer. Algunas de las soluciones y técnicas adoptadas en este software fueron tenidas en
cuenta a la hora de construir nuestra aplicación; sin embargo, la mayoría de las ideas
empleadas en la elaboración del proyecto son completamente originales y son fruto
de la investigación surgida a raíz de los intentos de implementación de cada requisito.
Es decir, la construcción de gran parte de la aplicación se debe a un proceso que bien
puede dividirse en dos partes:
1. Estudio del siguiente requisito que se implementará.
2. Obtención del diseño de la implementación de este requisito, basada en la investigación y en el estudio de la situación.
En las siguientes líneas especificaremos con detalle los problemas encontrados y las
soluciones que se llevaron a cabo para solventarlos, así como los aspectos más importantes a destacar con respecto a la implementación.
Una de las principales dificultades que se tuvieron que afrontar (además, de modo
constante) fue todo lo relacionado con las rutas del PATH y del CLASSPATH, debido,
sobre todo, al desconocimiento que tenía acerca de ellos al iniciar el proyecto y a la
falta de experiencia con respecto a su manejo y sintaxis. Esto provocaba que, cada
vez que quería ejecutar una clase Java ubicada en cualquier directorio del sistema
o cualquier programa necesario para el correcto funcionamiento de la aplicación,
acabara obteniendo un error.
Finalmente, la ruta del PATH se modificó en el fichero Make.bat con el fin de poder
utilizar el programa Dev-Cpp para la compilación y ejecución del código C++ utilizado en la aplicación, además de en el fichero temp.bat para la ejecución del programa 7-Zip para la comprensión de los archivos de la instalación y la creación del fichero auto-ejecutable. Por su parte, la ruta del CLASSPATH se cambió en el propio
Make.bat con el fin de localizar los .class de la aplicación y el jdom.jar, necesario
para leer el fichero XML de configuración.
54
Aunque menor, otro de los problemas que me encontré inicialmente fue la lectura
del fichero XML de configuración. Como he comentado antes, esto se logró gracias
a JDom. Sin embargo, nuevamente el desconocimiento de esta herramienta provocó que aparecieran errores en la aplicación, debidos sobre todo al hecho de que,
en determinadas ocasiones, trataba de leer subelementos del XML no existentes.
Por ejemplo, si no se incluía en el XML el subelemento “desinstalador” (porque no
se asignaba ningún icono al desinstalador) y la aplicación trataba de leer dicho subelemento, se producía un error.
Ante este problema se adoptaron tres posibles soluciones, que se pasan a describir
a continuación:
o Mantener el subelemento en el XML con una cadena vacía de modo que la aplicación pueda leerlo sin que se produzcan errores, aunque no proporcione ninguna información.
o Incluir en el elemento padre un atributo (de tipo “Yes/No”) que indique si hay
que tener en consideración la información almacenada en sus hijos.
o Hacer que la aplicación lea un subárbol del XML que incluya a los elementos
que puedan omitirse en determinadas ocasiones, de modo que sea la propia lógica de la aplicación la que determine qué elementos son los que finalmente se
incluyen.
En función de la situación, se eligió una solución u otra, atendiendo principalmente
a la probabilidad de que el subelemento se pudiera omitir: si el subelemento iba a
quedar pocas veces vacío (como es el caso del icono del desinstalador), directamente se recurría a la cadena vacía; si eran varios los subelementos que podían
omitirse, se optaba por el atributo en el elemento padre; en otro caso, se consideraba la tercera opción (nótese que es la más laboriosa, tanto para el programador
como para la máquina).
La utilización de ficheros jar para la ejecución de los archivos Java compilados ocasionó que se invirtiera cierto tiempo en investigar acerca de cómo ejecutarlos. Los
ficheros de manifiesto, que pueden entenderse simplemente como ficheros en los
que se indica cuál es el archivo en el que se encuentra la clase que contiene al método principal, son los que subsanaron tal dificultad.
El instalador que se va a crear deberá ser capaz de determinar para qué usuarios se
tiene que instalar el programa. Esta funcionalidad se implementó mediante el uso
de ‘System.getProperties(“user.name”)’, lo cual recoge el nombre del usuario actual del sistema operativo.
Otro gran problema fue la creación de los accesos directos. Resulta sencillo crear
un acceso directo en Windows de modo directo (con el ratón, por ejemplo), pero
¿cómo crear un acceso directo de modo programado desde la línea de comandos?
En Windows no existe ningún mandato que nos permita realizar tal cosa.
Los accesos directos son, en realidad, archivos que hacen referencia a otro archivo
situado en cualquier ubicación, caracterizándose por tener extensión .lnk. No obstante, es obvio que para crear un acceso directo no basta con añadir esta extensión
a un determinado archivo, sino que habrá que referirse al directorio en el que se
encuentran el archivo base y el icono que representará tal acceso directo.
55
Tras largas horas de investigación, la solución vino dada por el uso de un programa
externo capaz de crear accesos directos desde la línea de comandos, llamado
Shortcut.exe, al cual basta con introducirle como parámetros los comentados más
arriba.
Una dificultad menor, pero difícil de solventar, es la que ocasionaba la eliminación
del sistema del propio archivo de desinstalación. ¿Cómo borrar un archivo desde el
mismo archivo que debe ser borrado? Todo desinstalador que se precie debería ser
capaz de eliminar también los archivos relativos a la desinstalación del programa,
incluidos ellos mismos.
Las pruebas e investigaciones iniciales mostraron que era poco probable que, bajo
cualquier circunstancia, un archivo jar se pudiera eliminar a sí mismo, y que en caso de que fuera posible, sería difícil de conseguir (habría que esperar a que el archivo se cerrara, o bien cerrarlo nosotros mismos, antes de intentar eliminarlo). Por
tanto, la conclusión que se extrajo de esto fue que debía ser necesariamente otro
archivo el que se encargara de eliminar el archivo jar del desinstalador. Ahora bien,
del mismo modo, dicho archivo debía ser capaz de eliminarse a sí mismo.
Pues bien, los archivos ejecutables por lotes de Windows (de extensión .bat) tienen
esta propiedad. Por ello, la solución consistió en la creación de un script que esperara el tiempo necesario a que se cerrara el archivo jar de desinstalación, procediera a borrarlo y después, se auto-eliminara del sistema. Este script simplemente intentaba borrar el archivo reiteradas veces hasta que éste se cerraba y lo lograba,
momento en el que procedía con su auto-eliminación.
Hay que indicar que este script es ubicado durante la desinstalación en el directorio
C:\, debido a que este directorio es muy probable que exista en el ordenador del
usuario final (se trata de la carpeta que contiene habitualmente los archivos del
disco duro de la máquina). Su nombre es destruir.bat.
No solo la eliminación del propio desinstalador causó problemas. También otros archivos intermedios necesarios para el correcto funcionamiento de la aplicación que
deben ser borrados durante el proceso de instalación ocasionaron contratiempos a
la hora de ser eliminados, debido de nuevo a que la propia aplicación intentaba borrarlos antes de que se cerraran. Por razones desconocidas, con determinados archivos (no todos), la táctica de esperar hasta que éstos se cerraran no funcionaba si
se programaba desde Java, por lo que se recurrió a su eliminación desde otro script
(en este caso, el temp.bat).
La modificación del registro de Windows es otro de los problemas que hubo que
afrontar, no solo por el desconocimiento inicial acerca de para qué se utilizaba y
cómo se podía cambiar, sino también por el peligro que conllevaba realizar tal acción; es recomendable no cambiar ningún valor del registro de cualquier ordenador, salvo que sea estrictamente necesario.
56
La aplicación debía ofrecer dos maneras diferentes de modificar el registro: a gusto
del usuario o mediante guías, o pistas, que permitieran al usuario creador cambiar
aquellos registros que más se suelen utilizar a la hora de realizar instalaciones de
programas. Puesto que lo primero se puede entender desde el punto de vista de la
programación como una generalización de lo segundo (para modificar el registro,
hay que indicar siempre la ruta que se desea cambiar, el atributo a cambiar, el tipo
de dato que se introduce y el nuevo valor que tendrá el atributo; y esos son los parámetros que se consideran en el segundo método), hubo que reestructurar parte
del código (ya que, al principio, no se pensó en la posibilidad de modificar el registro a gusto del usuario), de modo que un mismo método Java sirviera para insertar
en el registro datos mediante cualquiera de las dos opciones anteriores. El método
Java que se encarga de tal tarea es la acción insertarEnRegistro.
Como mejora con respecto a ciertos creadores de instaladores, como IzPack, el
programa añade una nueva funcionalidad: es capaz de proporcionar al usuario final
un ejecutable en lugar de un simple archivo jar, de modo que si el usuario final tiene instalada la JRE de Java en su equipo, el .exe ejecuta directamente el jar, y si no,
instala antes Java. Para lograr este objetivo, la aplicación crea durante la instalación un archivo C++, llamado arch.cpp, el cual comprueba si existe alguna versión
de la JRE de Java instalada en la máquina haciendo una llamada al sistema con el
mandato:
pid=system("java -version>nul 2>&1");
En caso de que exista alguna versión, system devolverá el valor 0; en otro caso, devolverá un valor distinto de 0. Así, podremos distinguir de forma unívoca si realmente está instalado Java en el equipo mediante el valor de la variable pid. Notemos que el mandato java –version muestra la versión actual de Java por consola y,
puesto que esto no debería ser leído por el usuario final, hemos de redireccionar la
salida a nul.
Tras esto, y solo en caso de que no haya ninguna versión de Java instalada, el código C++ ejecuta el instalador de la correspondiente JRE (en el caso de nuestro creador de instaladores, dicho instalador corresponde a la versión 6 – Actualización 18).
Por último, independientemente de si Java está instalado, el código C++ ejecuta el
jar del instalador tras esconder la molesta consola que acompaña a sus programas.
Otro aspecto que hubo que corregir está relacionado con el subdirectorio de la carpeta de instalación en el que debían copiarse los archivos. En versiones primitivas
del creador de instaladores, los archivos de la instalación no se podían copiar en
otro sitio que no fuera el directorio de destino, aunque hubiéramos querido ubicarlos en una subcarpeta de dicho directorio al tratarlos de forma individual (por
ejemplo, para hacer un acceso directo a ese archivo en concreto).
El error se corrigió añadiendo a la estructura del XML un subelemento más al elemento “origen”, llamado “destino”, en el cual se indica la ruta dentro del directorio
de destino en la que se va a copiar el archivo. La aplicación guarda esta ruta en la
variable destShorcut, en caso de que exista en el XML (el subelemento “destino”
podría omitirse, en cuyo caso el lugar en el que se copia el archivo sería la propia
carpeta de instalación).
57
La creación del fichero auto-ejecutable que extrae los archivos de la instalación y la
ejecuta requirió varias horas de investigación. En un principio se pensó que bastaba
con la creación de un fichero jar que almacenara todos los archivos del programa
que se debían instalar y que ejecutara el instalador que tuviera dentro (lo cual se
habría podido conseguir con un simple doble clic, gracias a los ficheros de manifiesto). No obstante, se reconsideró tal idea, debido a que es posible que el usuario final no tenga ninguna máquina virtual de Java instalada en su máquina, o aunque la
tenga, carezca de la noción de lo que es un archivo jar.
El archivo auto-ejecutable se consiguió gracias al programa 7-Zip, ya que permite
crearlo desde la línea de comandos. Para construirlo, es necesario completar dos
pasos: creación del fichero comprimido con los archivos requeridos durante la instalación y creación del archivo auto-ejecutable. Para este segundo paso, además de
conocer la sintaxis específica del programa, es necesario disponer en la carpeta de
la aplicación de dos archivos más, sin contar el fichero de compresión creado en el
primer paso: el 7zS.sfx y el config.txt. Éste último fichero de texto es muy importante, ya que con él se especifica, entre otras cosas, el archivo que se debe ejecutar
nada más descomprimir el fichero de extensión .7z. Será el propio programa 7-Zip
el que se encargue de gestionar la eliminación de los ficheros extraídos una vez se
hayan utilizado tras la descompresión.
El continuo tratamiento con cadenas de texto indujo la confección de dos métodos
Java que se encargan de modificar adecuadamente dichas cadenas con el fin de
que la aplicación funcione sin errores. Estos métodos son nombreFichero y
cambiarBarra. El primero recibe una ruta determinada y devuelve el nombre del fichero al que hace referencia; este nombre coincidirá con el token que se encuentra
en último lugar, tras la última doble barra de la cadena inicial (\\). El segundo se
encarga de cambiar cualquier doble barra \\ que le llega en la cadena introducida
como parámetro por una barra simple (/), y es útil para ejecutar el mandato específico que invoca al programa 7-Zip.
En cuanto a la interfaz de usuario, hay bastantes aspectos a destacar de su implementación. Uno de ellos es la obtención de todos los paquetes disponibles para
presentarlos ante el usuario final. Hay que tener en cuenta que los paquetes se
pueden repetir tantas veces como quiera el usuario creador y que pueden existir
archivos que no están asociados a ningún paquete. Esto se traduce en que nuestro
código se tendrá que encargar de copiar en el archivo properties como claves solo
aquellos paquetes que no se hayan copiado ya en este archivo, sin incluir en él ningún valor nulo (pues esa es la representación de los archivos que no están asociados a ningún paquete en el vector que recoge los nombres de los paquetes). El método que se encarga de esta labor es generarInstallConfig, perteneciente a la clase
Construct.
Otro aspecto a considerar con respecto a la interfaz es la forma de determinar qué
paquetes se instalarán finalmente y cuáles no. Para ello, contamos con que en la
clase Instalador disponemos de un vector que recoge el nombre de los paquetes
para cada archivo definido (null para el caso de los archivos que no pertenecen a
ningún paquete) y otro con valores booleanos que indica para cada archivo si se
instala o no.
58
Recordemos que un archivo que no tiene ningún paquete asociado se deberá instalar obligatoriamente, por lo que nuestra estrategia consistirá en suponer inicialmente que todos los archivos se van a instalar (aunque la decisión del usuario creador sea diferente) para después cambiar el valor del vector de booleanos en las
componentes correspondientes a los archivos cuyos paquetes no se instalarán por
decisión del usuario final. Así, en el momento que se confirma la instalación, la clase InterfazGrafica busca únicamente aquellos paquetes que no se van a instalar y
sus nombres son pasados como parámetro al método setInstPaq de la clase
Instalador para cambiar a false el valor de aquellas casillas del vector de booleanos
que cumplan que su archivo asociado pertenece al paquete introducido como
parámetro.
Pero sin duda, lo más complejo de resolver con respecto a la interfaz es de qué modo se podrán mostrar en ella los paquetes a instalar; no sólo por los nombres tan
diversos que pueden tener, sino sobre todo por la cantidad indefinida de paquetes
que se pueden definir. Esta última circunstancia lleva a la necesidad de tener que
construir en la interfaz casillas de verificación (checkboxes) para los paquetes de
manera dinámica (en tiempo de ejecución) en caso de no declarar un número máximo de ellos, pues a priori no sabemos cuántos se declararán en el fichero XML.
Sin embargo, debido al tamaño limitado de la ventana de la interfaz gráfica, creí
poco recomendable permitir la declaración de un número ilimitado de paquetes,
por lo que finalmente se decidió acotar el número máximo de paquetes a 10, los
cuales son suficientes para llevar a cabo con éxito la inmensa mayoría de todas las
posibles instalaciones, además de construir y añadir las casillas de verificación a la
interfaz de manera estática.
Una vez adoptada la decisión de acotar el número de paquetes, la solución pasa
por construir 10 métodos que añadan cada uno una casilla a la interfaz y por contar
cuántos paquetes hay exactamente de verdad. De esto último se encarga el método contarPaquetes, el cual además añade el nombre de estos paquetes a un vector
para facilitar su posterior gestión. Para determinar el número de paquetes, este
método cuenta en realidad el número de claves del archivo de configuración
install.properties diferentes a las que siempre aparecerán, a saber: “Ruta”, “Inicio”,
“Escritorio”, “Todos” y “Programas”. Después de todo esto, será fácil determinar
los métodos getCheck que serán invocados para añadir las correspondientes casillas de verificación a la interfaz del usuario final (tantos como paquetes hayan sido
declarados).
59
4.5. Pruebas
En este proyecto, debido a sus peculiaridades y a su modo de desarrollo, no ha habido
una única fase de pruebas, sino que éstas han tenido lugar cada vez que se ha diseñado una solución para cada nuevo requisito a implementar. En este apartado resumiremos los resultados de las pruebas que más significativas resultaron, así como las modificaciones que causaron en el código.
4.5.1.
Pruebas de comprobación de la funcionalidad
Estas pruebas se basaron simplemente en determinados cambios que se introdujeron
en el fichero XML de configuración; los cambios que pueda introducir el usuario final
con respecto a la configuración inicial son equivalentes a los que pueda introducir el
usuario creador del instalador.
Antes de esto, hay que indicar que el resto de pruebas realizadas tuvieron un resultado
satisfactorio. Fueron pruebas para comprobar que…
El nombre que iba a tener el instalador era el deseado. Para ello, se modificó el
atributo “nombre” del elemento “instalador” del fichero XML. Resultado: el archivo
auto-ejecutable que hace las veces de instalador tenía como nombre el especificado, con la extensión .exe.
Los archivos o directorios cuyas rutas se indicaban en el subelemento “archivo” del
XML y que formaban parte de la instalación se copiaban en los lugares previstos.
Los accesos directos asociados a algunos de estos archivos se creaban en los lugares especificados en los atributos “programas”, “escritorio”, “inicio”, “menuInicio”
y “aplicaciones” del elemento “origen” del XML, así como que estos accesos directos iban acompañados por el icono cuya ruta quedaba especificada en el subelemento “icono” del elemento “origen”, siempre que se decidiera que el acceso directo estuviera acompañado por algún icono.
En caso de que se quisiera copiar un archivo que tuviera necesariamente que estar
dentro de alguna carpeta que se hubiera creado en el directorio de la instalación,
el archivo se copiaba en la ruta adecuada, la cual quedaba completamente determinada por el subelemento “destino” del elemento “origen” del XML.
La carpeta de instalación quedaba ubicada en la ruta que aparecía en el subelemento “destino” del elemento “lugaresInstalacion”, y que esta carpeta tenía el
nombre indicado en el subelemento “programas” del mismo elemento.
Se creaba un nuevo grupo de programas, con el mismo nombre que la carpeta de
instalación, si el atributo “incluir” del elemento “programas” tenía el valor “Yes”, y
que no se creaba en caso contrario.
60
Se modificaba adecuadamente el registro de Windows de acuerdo a los valores de
los atributos de los elementos “instalacion” y “desinstalacion” y al texto presente
en los subelementos del elemento “desinstalación” en caso de que el valor del atributo “modificar” del elemento “registro” fuera “Yes”, y que no se producían cambios en el registro en caso contrario.
El registro de Windows también se modificaba correctamente, considerando la información almacenada en el elemento “customize”, en caso de que existiera en el
fichero XML; es decir, que se cambiaba la ruta del registro indicada en el atributo
“ruta”, que el tipo del valor cambiado era el especificado en el atributo “tipo”
(REG_DWORD, en caso de que el valor de este atributo fuese la cadena vacía), que
la clave del registro modificada era la misma que el valor del atributo “clave” y que
el nuevo valor de esa clave coincidía con el del atributo “valor”.
La instalación era válida para todos los usuarios del equipo en caso de que el atributo “todos” del elemento “usuarios” valiera “Yes”, mientras que solo era válida
para el usuario actual en caso contrario.
El icono que acompañaba al acceso directo del desinstalador se encontraba en la
ruta establecida por el subelemento “icono” del elemento “desinstalador” en caso
de que éste tuviera un valor distinto de la cadena vacía, y que el acceso directo carecía de icono en otro caso.
Se ejecutaban los archivos e/o instaladores indicados en el elemento “ejecutable”,
en caso de que fuese necesaria su puesta en marcha tras completarse la instalación, así como que su ejecución tenía lugar gracias al programa especificado en el
atributo “prog” del mismo elemento (que contendría a la cadena vacía en caso de
que en realidad no fuera preciso ningún programa).
La aplicación soportaba que hubiera varios elementos del XML del mismo tipo (como es el caso de los elementos “origen”, “customize” y “ejecutable”) y que funcionaba correctamente atendiendo a la información residente en cada uno de ellos.
En pruebas realizadas en equipos diferentes al mío, la aplicación funcionaba bien,
de modo que se actualizaban adecuadamente las variables del sistema PATH y
CLASSPATH y se ejecutaba la instalación de la JRE de Java en caso de no disponer
de ella.
Como hemos indicado antes, la ejecución de ciertas pruebas dieron lugar a la detección de algunos errores existentes en la aplicación que tratábamos de desarrollar en
este proyecto. A continuación, detallaremos tanto los fallos encontrados como la solución para corregirlos en ese momento.
61
Prácticamente cada vez que se tenía la necesidad de que un fichero escribiera una
determinada ruta en otro fichero, o con menos frecuencia cuando el método principal tenía que leer alguna ruta del fichero XML de configuración, al ejecutar el instalador aparecía un error (en el primer caso) o ni siquiera se llegaban a compilar
correctamente los archivos Instalador.java o Desinstalador.java (en el segundo caso). La causa del error era el tratamiento especial que en Java se le tiene que dar al
símbolo de la contrabarra (\), ya que se trata de un carácter especial, lo cual hacía
que no sirviera introducir las rutas en su formato normal (en las que los directorios
aparecen separados por una sola barra invertida).
La solución que se adoptó consistió en añadir contrabarras adicionales a cada una
de las rutas que se escribían en los ficheros creados por la aplicación, una por cada
fichero en el que se tuviera que escribir dicha ruta. Por ejemplo, si una ruta tenía
que escribirse en dos ficheros durante el proceso de compilación o ejecución de la
aplicación, era obligatorio escribir hasta 4 contrabarras entre directorio y directorio
con el fin de evitar tratar a este símbolo como un carácter especial.
Este problema no solo tuvo lugar con la barra invertida, sino también con cualquier
carácter especial en Java (las comillas, etcétera). Para estos casos, la solución fue
equivalente a la anterior.
Otro problema surgió con los espacios en blanco. En determinadas ocasiones, era
preciso introducir nombres de directorios o rutas completas como parámetros de
programas ejecutados desde la línea de comandos (por ejemplo, el Shortcut.exe). Si
estos nombres o rutas tenían espacios en blanco, el programa fallaba, pues entonces deberían haber estado encerrados entre comillas. Es evidente que dichos fallos
no fueron detectados hasta que esta clase de programas no se incorporaron al proceso de desarrollo, aunque se corrigieron de forma sencilla encerrando entre comillas dichos nombres y rutas en los archivos Java correspondientes (añadiendo las
contrabarras que fuesen necesarias, según el punto anterior, pues las comillas son
tratadas como caracteres especiales).
En el fichero XML de configuración existen algunos elementos y atributos que no se
pueden omitir. Si así fuera, ocurriría un error en tiempo de ejecución dentro de las
clases Instalador y Desinstalador, pues nuestra aplicación tratará bajo cualquier circunstancia de leer sus valores, de forma que si no existiesen se produciría una
excepción.
Los encargados de que el fichero XML de configuración esté definido de modo correcto con el fin de preservar errores de este tipo en nuestra aplicación es o bien el
fichero DTD o el fichero XML-Schema, ya que ambos están asociados al XML con
ese fin. Pero, ¿qué ocurriría si esos ficheros estuvieran mal diseñados? ¿Qué pasaría si en ellos se declararan atributos opcionales que en realidad debieran ser obligatorios? La respuesta es que el usuario creador de la instalación podría dejar sin
incluir estos elementos o atributos en el XML sin que los ficheros DTD o XMLSchema advirtieran nada, y aún así producirse excepciones y errores en nuestra
aplicación, algo no deseable.
62
Las pruebas que detectaron estos errores consistieron en omitir en el XML parte de
los atributos que, en un principio, eran considerados por el DTD y el XML-Schema
como opcionales. La solución consistió en declarar como obligatorios aquellos atributos que ocasionaban errores o excepciones por su omisión.
Otro error se producía al no declarar ningún icono para el acceso directo del desinstalador. La forma de especificar esto en el fichero XML es dejar vacío el subelemento “icono” del elemento “desinstalador”. No obstante, cuando se hacía esto, se
producía una excepción en tiempo de ejecución que, aún así, no impedía que la
aplicación se comportara de acuerdo a lo especificado (pues finalmente se construía el acceso directo).
Lo que producía este error, cuyas causas no fueron fáciles de deducir, era en realidad un error de programación que describiremos en las siguientes líneas.
El atributo iconDesinst de la clase Construct.java recoge la ruta relativa en la que se
encuentra el icono que acompaña al acceso directo del jar del desinstalador, de
forma que, para detectar si se ha declarado algún icono que represente al acceso
directo del desinstalador, es necesario comparar su valor con la cadena vacía (pues
el subelemento “icono” del elemento “desinstalador” es obligatorio en el fichero
XML): tal icono existirá si su valor es distinto de la cadena vacía. Pues bien, en el código realmente se comparaba su valor con el de null, y puesto que null es distinto
que la cadena vacía, la aplicación intentaba crear el acceso directo (con el consiguiente error). Una vez corregida la errata, todo funcionó del modo apropiado.
Por último, apuntaremos en las siguientes líneas un comportamiento inesperado
de nuestra aplicación que tuvo lugar al probar la creación de la instalación de un
programa desarrollado por Jónathan Heras, miembro del Departamento de Matemáticas y Computación de la Universidad de La Rioja. Este comportamiento consistía en que, durante unos segundos después de completarse la instalación del programa en cuestión, aparecían en el escritorio (lugar en el que se precisaba la creación de un acceso directo a un archivo del programa) hasta 3 accesos directos iguales. No obstante, tras esos instantes, desaparecían los accesos directos sobrantes.
El resto de requisitos se cumplían en este caso.
Hasta la fecha no se ha encontrado una explicación a este fenómeno. Sin embargo,
hay que apuntar que sólo se ha producido en el ordenador del miembro colaborador (en el que, por cierto, ya estaba previamente instalado el programa, algo que
jamás ocurriría en una situación normal).
No solo se han realizado pruebas con esta aplicación (fKenzo). También se ha trabajado con el programa TutorMates de Addlink Research, S.L. Recordemos que es
posible que nuestro programa sea el encargado de construir el instalador de esta
aplicación en un futuro.
63
4.5.2.
Pruebas de la interfaz de usuario
Las pruebas para comprobar el correcto funcionamiento de la interfaz de usuario
se centraron en comprobar que la información introducida en ella se tenía en cuenta a la hora de realizarse el proceso de la instalación, en que era capaz de mostrar
la configuración elegida por defecto por el usuario creador y en que al desinstalador se le proporcionaba realmente la información adecuada para revertir los cambios producidos por el instalador. La mayor parte de estas pruebas resultaron satisfactorias; en las siguientes líneas explicaremos los problemas que surgieron con las
restantes y las soluciones que se adoptaron para solucionarlos.
Las contrabarras volvieron a plantear dificultades en la implementación de la interfaz. En esta ocasión, provocaban que el archivo destruir.bat necesario para borrar
el directorio de instalación no actuara del modo correcto. En concreto, lo que ocurría consistía en que se escribían en este archivo rutas en las cuales parte de algunos de sus directorios se separaban mediante doble barra, cuando debían escribirse con barra simple para que los mandatos funcionaran bien. Esto se debía a que,
por la necesidad de escribir esas mismas rutas en otros archivos, se requería que
estuviesen separados sus directorios por la doble contrabarra.
La solución que se adoptó fue recoger en una variable la ruta con sus directorios
separados por una sola contrabarra y escribir esta representación de la ruta en el
archivo destruir.bat. Dicha representación podía conseguirse de forma inmediata
leyendo la ruta directamente del fichero de configuración install.properties.
El fichero properties también ocasionó varias dificultades. Una de ellas era la obtención de sus claves para mostrarlas debidamente en la interfaz de usuario. Resulta que al leer una clave formada por varias palabras de un archivo de propiedades
mediante el método keys(), se devuelve únicamente la primera palabra de la clave
(ignorándose el resto). Esto hacía que el nombre de los paquetes no se mostrara de
forma correcta en la interfaz y que se perdiera información en el proceso de instalación de los paquetes.
La solución consistió en escribir el nombre de los paquetes en el archivo de propiedades separando las palabras que lo conformaban por guiones bajos ‘_’ en lugar de
por espacios en blanco. Después, el método cambiarBarraBaja de la clase
InterfazGrafica se encargaría de hacer los cambios necesarios con el fin de que los
nombres de los paquetes se mostraran separados por espacios en blanco. Esa es la
razón por la cual nunca deberíamos nombrar a un paquete con barras bajas.
64
Pero el contratiempo más importante con respecto al archivo de propiedades fue
el hecho de que, por alguna razón, se añadía al jar del desinstalador antes de que
fuera modificado con los cambios producidos por el usuario final tras ejecutar el
instalador, haciendo que el desinstalador nunca obtuviera los parámetros correctos para revertir los cambios en el sistema. Tras algunas pruebas, se comprobó que
este error no sucedía si los datos del archivo de configuración se guardaban en otro
archivo distinto al inicial, el install.properties. A este nuevo archivo se le denominó
desinstall.properties, y es realmente este fichero de propiedades el que va a usar
siempre el desinstalador para obtener los datos de la instalación y llevar a cabo la
desinstalación de manera correcta.
Por último, apuntaremos que al ejecutarse la interfaz gráfica aparecía siempre al
fondo y en segundo plano una consola vacía que permanecía abierta durante todo
el proceso de instalación, hasta el momento en el que ésta terminaba. La consola
aparecía como consecuencia de la ejecución del archivo Setup.exe, escrito en C++,
aunque en un principio se pensara que el responsable de que se mostrara era Java.
Puesto que no es deseable la aparición de tan molesta e innecesaria consola, se tomó la decisión de tratar de ocultarla después de la posible instalación de la JRE de
Java (de la cual también se encarga el programa Setup.exe), pues la aplicación sí
que usa la ventana para informar al usuario durante este proceso. El código en C++
que nos proporcionó la solución es el siguiente:
HWND hide;
AllocConsole ();
hide = FindWindowA("ConsoleWindowClass",NULL);
ShowWindow (hide, 0);
Para la ejecución de este código, es necesario incluir el paquete windows.h de C++.
65
4.6. Gestión del proyecto
Tras la finalización del proyecto, podemos decir que se han cumplido los plazos previstos para su entrega, pero no la realización del número de horas estimado para su elaboración. Es decir, a pesar de que finalmente no ha habido ningún retraso, de forma
paradójica tampoco se ha invertido el tiempo total previsto para la realización del PFC
(se ha pasado de dedicarle 540 horas a unas 305; esto es, un poco más de la mitad).
La explicación a este hecho radica en la planificación que se ha seguido durante el desarrollo de nuestra aplicación, consistente en dos pasos sucesivamente repetidos: estudio de una nueva funcionalidad del creador de instaladores IzPack e implementación
de la misma. Así, puesto que las horas invertidas no alcanzan a las planificadas inicialmente, se ha obtenido una aplicación cuyas prestaciones son menores de lo que se esperaba, pues no satisface todos los requisitos que cumple IzPack (porque no ha dado
tiempo a estudiarlos e implementarlos todos). En resumen, se ha completado la labor
que se ha podido realizar en el tiempo estipulado al comienzo del proyecto, hasta lo
que ha dado tiempo a hacer.
Esto no quiere decir que el proyecto sea deficiente en algún sentido. Las funcionalidades que se han implementado representan el grueso de la aplicación, sus entresijos,
siendo por tanto la parte más difícil del desarrollo. Esto significa que lo no implementado se refiere a detalles de menos importancia en referencia a la programación, tales
como:
Pantallas de presentación y cierre de la instalación.
Incorporación de una barra de progreso en los procesos de instalación y desinstalación que informe al usuario del grado de avance en el que se encuentran.
Posibilidad de cancelar la instalación o la desinstalación mientras se están llevando
a cabo.
Incorporación de una interfaz que sirva para mostrar información relativa a la aplicación que se desea instalar.
Presentación de los paquetes de archivos que se van a instalar seguro.
Descripción de los paquetes de archivos que se pueden instalar.
Cálculo del espacio disponible en el disco duro.
Lo relativo a la barra de progreso y la cancelación de la instalación o desinstalación en
el transcurso de su ejecución puede resolverse mediante la creación de hilos de ejecución (llamados comúnmente threads) en Java, y requeriría un poco de estudio por mi
parte para implementarlo (conozco el concepto de hilo de ejecución, pero no la forma
de programarlo en Java). Lo mismo puede decirse con respecto al cálculo del espacio
en disco, pero una vez estudiado cómo se puede obtener este dato, sería muy fácil
mostrarlo. Lo demás no supondría ningún esfuerzo adicional. En consecuencia, el esfuerzo que debería realizar para incorporar al proyecto estas funcionalidades es netamente menor en comparación al invertido con las implementadas.
66
La razón por la que se han invertido un poco más de la mitad de las horas previstas al
inicio en la realización del PFC es simple: su elaboración ha tenido que ser compaginada durante todo el ciclo académico con el último curso de la doble titulación; de ahí
que las 3 horas que se pensaban dedicar a esta tarea cada día fuesen demasiadas para
lo que se pretendía hacer. Al final, el tiempo real invertido cada semana acabó por no
superar las 8 horas, incluyéndose la mayor parte de ellas durante los fines de semana.
He de apuntar que, además, sólo he podido disfrutar de una dedicación exclusiva a la
realización del PFC durante el último mes, tras la finalización de los exámenes de junio.
Por otro lado, otras razones por las que no ha dado tiempo a realizar todo lo previsto
pueden ser la falta de experiencia ante un proyecto de tal magnitud y el hecho de usar
herramientas desconocidas para mí hasta su comienzo, hándicaps que tuvieron una
gran influencia sobre todo al principio, como es natural.
Aunque bien es cierto que existía la posibilidad de retrasar la entrega del proyecto a
septiembre o incluso al siguiente curso académico para mejorarlo, se acabó desechando tal opción, pues prefería dar prioridad a la continuidad de mi formación académica
frente a prolongar más tiempo el PFC. Por otro lado, tanto Julio Rubio como yo consideramos que se han superado con creces los objetivos más básicos del proyecto, siendo ésta la razón más sustancial por la que se decidió presentarlo en el momento
actual.
67
4.7. Conclusiones
4.7.1.
Concordancia entre resultados y objetivos
En líneas generales, los resultados obtenidos satisfacen los objetivos que se determinaron al comienzo del proyecto. El creador de instaladores desarrollado es capaz de ofrecer al usuario un abanico de posibilidades suficientemente amplio como para crear
cualquier tipo de instalación con la configuración que más le convenga, pues le permite crear accesos directos en los directorios más utilizados a tal efecto, modificar a su
antojo los valores del registro de Windows (facilitando, incluso, el acceso a las rutas del
registro que cambian con más frecuencia durante las instalaciones), dar un nombre al
instalador, elegir el directorio de instalación, crear automáticamente un nuevo grupo
de programas, indicar para qué usuarios será válida la instalación, permitir la ejecución
de instaladores de productos externos inmediatamente después de la instalación…
Además de estas funcionalidades y debido al uso que hace de la tecnología Java, nuestro creador de instaladores también consigue incorporar una versión de la máquina
virtual de Java (JRE) que se instalará en el equipo del usuario que ejecuta la instalación
si éste no disponía previamente de ella. Por consiguiente, la aplicación desarrollada en
este proyecto supera en este aspecto a ciertos creadores de instaladores (como
IzPack), ya que éstos no ofrecen esta posibilidad al usuario a pesar de estar implementados en lenguaje Java. Otro aspecto que consigue mejorar con respecto a IzPack (o,
por lo menos, corregir) está relacionado con la modificación del registro de Windows:
IzPack también satisface este requisito, pero con errores en determinadas ocasiones,
lo que hace que algunos usuarios de este producto desconfíen de esa funcionalidad.
Aunque quizás la forma que utiliza nuestro producto para llevar a cabo tal cometido
pueda resultar menos cómoda para el usuario, lo que sí se ha comprobado es que es
fiable y libre de errores.
4.7.2.
Lecciones aprendidas
Este proyecto me ha servido, sobre todo, para aumentar mis capacidades de trabajo
de investigación. Se trata de un proyecto eminentemente tecnológico, basado en la
realización de un producto completamente original y novedoso que, aunque en el fondo intente emular a un software ya existente y conocido, ha nacido desde el ingenio y
la búsqueda de ideas que resolvieran las dificultades de implementación a las que me
he ido enfrentando.
68
En cuanto a la planificación, este proyecto también es muy válido para apreciar en su
verdadera medida las ventajas que proporcionan las metodologías de desarrollo más
valoradas en la Ingeniería del Software. En este caso, debido a la naturaleza del proyecto, no ha quedado otro remedio que abordar el desarrollo de la aplicación sin haber
especificado de antemano todas las funcionalidades que era preciso implementar, lo
cual resultó muchas veces incómodo y arriesgado, pues a la hora de implementar nuevos requisitos era muy probable que hubiera que hacer cambios adicionales en el código, aumentando la probabilidad de que se produjeran errores o de que no los encontráramos. Además, estos cambios en el código suponían un esfuerzo extra difícil de
medir a priori y que causaban demasiada inseguridad en el programador, el cual tenía
que disponer de la valentía y el coraje suficientes como para modificar el código escrito asumiendo los anteriores riesgos. Todas estas dificultades no habrían tenido lugar si
la metodología usada hubiera especificado todos los requisitos desde el principio.
Otro motivo de aprendizaje fue el hecho de trabajar con herramientas y programas de
software desconocidos para mí al comienzo del proyecto. Esto me permitió obtener
una mayor confianza de cara al futuro a la hora de manipular y manejar software de
manera autodidacta. Esta capacidad es importante, pues es posible que me vea obligado a aprender a utilizar nuevos programas y herramientas por mí mismo y sin la ayuda de nadie que me instruya en determinadas situaciones. Además, algunas de las herramientas a las que me refiero son frecuentemente utilizadas en el ámbito de la programación, hasta el punto que las llegué a estudiar durante el último curso de la carrera (como la modificación del PATH y el CLASSPATH o el uso de JDom), por lo que la experiencia ha podido resultar muy útil para mí.
4.7.3.
Líneas de ampliación posibles
Puesto que este proyecto se basa en la emulación de un creador de instaladores existente, es probable que no se hayan implementado algunas de las funcionalidades que
proporciona. Otra posible línea de ampliación para este proyecto es la incorporación
de un soporte multilingüe, de modo que cada instalación pueda mostrar interfaces
gráficas en diferentes idiomas, así como la implementación de un soporte multiplataforma que permita configurar instalaciones también en otros sistemas operativos distintos de Windows, como Linux o Macintosh. La consecución de estas mejoras estarían
seguramente basadas en el diseño de una base de datos que recogiera cada uno de los
mensajes mostrados en la interfaz en los diferentes idiomas disponibles y cada uno de
los mandatos utilizados traducidos al lenguaje de programación propio de los diferentes sistemas operativos considerados. Por último, otra línea de mejora podría centrarse en la construcción de una interfaz para el usuario creador del instalador, de forma
que ya no tendría que verse obligado a construir un fichero XML de configuración para
realizar su tarea. De hecho, realmente se da la existencia de ciertos creadores de instaladores que incorporan tal interfaz.
Por supuesto, cabe recordar que el proyecto puede mejorarse implementando las funcionalidades que proporciona IzPack y que finalmente no se consideraron por falta de
tiempo. En concreto, estas funcionalidades han quedado recogidas en el apartado 4.6,
Gestión del proyecto.
69
4.8. Bibliografía
1) Juan Diego Gutiérrez Gallardo: Manual imprescindible de XML. Anaya Multimedia,
2005.
2) Ejemplos de instaladores creados mediante IzPack:
http://www.adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=IzPack.
3) Página oficial de IzPack: http://izpack.org.
4) Funcionamiento de CLASSPATH y jar:
http://www.chuidiang.com/java/classpath/classpath.php.
5) Crear un archivo jar ejecutable:
http://login.osirislms.com/index.php?modname=foro&op=message&idThread=28.
6) Página oficial de JDom: http://www.jdom.org.
7) Ejemplos de uso de JDom:
http://www.javahispano.org/contenidos/archivo/48/jdom1.pdf.
8) Determinar el usuario actual del sistema:
http://stackoverflow.com/questions/473446/java-current-machine-name-andlogged-in-user.
9) Página para la descarga del programa Shortcut.exe:
http://optimumx.com/download/#Shortcut.
10) Información del registro de Windows: http://support.microsoft.com/kb/256986/es.
11) Página oficial de 7-Zip: http://www.7-zip.org.
12) Crear un archivo auto-extraíble mediante 7-Zip:
http://prudentialscatterbrain.hp.infoseek.co.jp/7z4.20_MANUAL/switches/sfx.htm, http://it.megocollector.com/?p=16.
13) Especificación de la API de Java:
http://download.oracle.com/docs/cd/E17476_01/javase/1.3/docs/api/overviewsummary.html
70
4.9. Anexos
4.9.1.
ANEXO I: Manual de instrucciones del usuario creador
INSTRUCCIONES DE USO:
1º) En la misma carpeta que se proporciona (la que contiene el Make.bat) se añaden los
archivos que se utilizarán durante la instalación: iconos, carpetas que se copiarán,
programas o instalaciones externos que se deben ejecutar en el transcurso de la
instalación...
2º) También en la misma carpeta, debe crearse un archivo XML de nombre Instalador.xml.
La estructura que debe tener dicho archivo está especificada en Instalador.dtd y en
Instalador.xsd. A continuación se indica el significado de cada atributo y elemento:
•
Elemento instalador: raíz del documento.
Atributos:
nombre: lleva el nombre que tendrá el instalador.
•
Elemento fuentes: puede contener varios elementos "origen".
•
Elemento origen: cada uno contiene un fichero que se copiará en el destino.
Atributos:
programas: indicar "Yes" si se desea instalar el fichero en el grupo de programas de la
aplicación; "No", en caso contrario.
escritorio: indicar "Yes" si se desea hacer un acceso directo en el escritorio; "No", en
caso contrario.
inicio: indicar "Yes" si se desea que el programa se cargue al arrancar Windows; "No",
en caso contrario.
menuInicio: indicar "Yes" si se desea hacer un acceso directo en la carpeta de
programas del menú Inicio; "No", en caso contrario.
aplicaciones: indicar "Yes" si se desea hacer un acceso directo en la carpeta de
aplicaciones del menú Inicio; "No", en caso contrario.
Subelementos:
paquete: conjunto de archivos que se instalan como un todo: si se decide que un
archivo de un paquete debe ser instalado, el resto de archivos de ese paquete también
se instalarán. Dos archivos diferentes pertenecen al mismo paquete si el valor de este
elemento es el mismo en ambos casos. Incluye el atributo obligatorio "defecto", que
puede tomar como valor "Yes" o "No": "Yes", si se desea instalar por defecto este
paquete; "No", en caso contrario. El número máximo de paquetes soportados es 10. El
nombre de los paquetes nunca deberá contener ninguna barra baja ('_').
71
archivo: ruta del archivo (dentro de la carpeta del creador de instaladores) que se
copiará en la carpeta de destino. Los subdirectorios se separan mediante \\ (esto será
válido para cualquier ruta de aquí en adelante en este documento).
icono: ruta del icono (si existiera) que se asociará al archivo anterior (en caso de que
admitiera un acceso directo). Si un archivo para el que se va a crear un acceso directo
no tiene ningún icono asociado, este elemento puede dejarse vacío u omitirse.
destino: útil solamente si se desea copiar un archivo dentro de una carpeta que se
instalará en el directorio de destino. Por ejemplo, si se desea copiar la carpeta
<miCarpeta> en el destino de modo que esta carpeta contiene una subcarpeta llamada
<subCarpeta> que a su vez contiene el archivo <miapp> y deseamos copiar este último
archivo dentro de la anterior subcarpeta, hemos de escribir en "destino" lo siguiente:
<miCarpeta>\\<subCarpeta>. Si no consideramos el subdirectorio <subCarpeta> en el
anterior ejemplo, bastaría con escribir <miCarpeta>. Por último, si el archivo <miapp>
no se encuentra dentro de ningún directorio, el subelemento "destino" debe omitirse
(o dejarse en blanco).
•
Elemento lugaresInstalacion: contiene información acerca de los lugares en los que se
instalará la aplicación. No contiene texto de ningún tipo: solo subelementos.
•
Elemento destino: contiene la ruta de la carpeta de instalación.
•
Elemento programas: contiene el nombre de la carpeta de instalación.
Atributos:
incluir: "Yes" si se desea crear un grupo de programas dentro del menú Inicio. El
nombre del grupo sería el mismo que se indica en el elemento "programas" (es decir,
el de la carpeta de instalación). "No", en caso contrario.
•
Elemento registro: contiene solo subelementos que incorporan la información de
modificación del registro de Windows.
Atributos:
modificar: "Yes" si se desea modificar el registro; "No", en caso contrario. Si se indica
"No", se obviará la información que puedan contener los subelementos.
•
Los elementos instalacion y desinstalacion tienen como atributos las claves de registro de
instalación y desinstalación de Windows. Además, “desinstalacion” incluye subelementos
en los que se muestran los valores de algunas de esas claves (si son distintos de "Yes" o
"No").
•
Elemento customize: permite modificar el registro libremente, a gusto del usuario.
Atributos:
ruta: guarda la ruta del registro que se va a modificar.
tipo: tipo de dato del valor que se introducirá en el registro. El tipo por defecto es
REG_SZ.
clave: guarda la clave de la ruta del registro que se modificará.
72
valor: Cadena que se almacenará en la clave indicada del registro.
•
Elemento usuarios: indica si la aplicación se instalará para todos los usuarios o solo para el
actual.
Atributos:
todos: valor "Yes", para todos los usuarios; valor "No", sólo para el actual.
•
Elemento desinstalador: solamente incluye un subelemento.
Subelementos:
icono: Guarda la ruta del icono que se mostrará con el acceso directo del
desinstalador. En caso de no existir tal icono, el elemento debe dejarse vacío.
•
Elemento ejecutable: incluye la ruta de aquellos programas, ejecutables o instalaciones
externos a la instalación de nuestra aplicación que deben ejecutarse durante el transcurso
de ésta.
Atributos
prog: guarda el programa con el que debe abrirse el ejecutable o instalador, en caso de
que sea necesario.
NOTA: Para asegurar el correcto funcionamiento de la aplicación, es necesario que el
documento XML sea completamente acorde a la DTD a la que está asociado; en otro caso,
su comportamiento no tendrá por qué ser el esperado.
3º) Se modifica la variable del sistema PATH con la ruta del directorio bin de la JDK de Java
que está instalada en su equipo. Por ejemplo, si tiene instalada la versión 1.6.0_17 en el
directorio "Java" de "Archivos de Programa", escriba en la línea de comandos:
SET PATH=%PATH%;c:\Archivos de programa\Java\jdk1.6.0_17\bin
Es necesario que su equipo disponga de la JDK de Java para que funcione esta aplicación.
4º) Se ejecuta Make.bat.
El resultado es un ejecutable .exe con el nombre del instalador. Dicho ejecutable se
encargará de extraer los archivos de instalación, ejecutar la instalación, modificar el
registro de Windows y gestionar la posterior eliminación de los archivos extraídos.
También se incluye un desinstalador que eliminará todos los archivos copiados en la
carpeta de instalación y los accesos directos, el cual además eliminará las entradas
correspondientes del registro. Además, en caso de que el equipo en el que tiene lugar la
instalación no tenga instalada ninguna versión de la JRE de Java, se instalará en él la
versión 6 – update 18.
73
4.9.2.
ANEXO II: Cronología del Proyecto Fin de Carrera
1/10/2009: Busco información sobre algunos creadores de instaladores, centrándome en aquel al que tendré que emular, IzPack. Por ahora, me interesa conocer su
funcionalidad, por encima del resto de sus características (4 horas).
Por otro lado, comienzo a estudiar por mi cuenta el lenguaje XML (el cual hasta
ahora es desconocido para mí), ya que será imprescindible para llevar a cabo el PFC
(los creadores de instaladores han de ser configurables precisamente a través de ficheros XML). (5 horas).
8/10/2009: Siguiendo con mi iniciación en XML, me hago con un libro que enseña
las nociones más básicas: “XML: Manual imprescindible”, de Juan Diego Gutiérrez
Gallardo. Con esto, aprendo la utilidad de XML para guardar y organizar los datos
(7 horas).
24/10/2009: Finalizo mi “primer” creador de instaladores, el cual simplemente
construye el código necesario para copiar un fichero de texto en cualquier directorio existente. Se trata del creador de instaladores más sencillo que puede haber,
pero su filosofía es la misma que utilizará la versión definitiva: generar código fuente en un fichero Java, el cual hará las veces del instalador tras compilarlo y ejecutarlo (en este sencillo caso, dicho instalador se llama “Instalador.java” y se limita a
copiar el fichero indicado en la ruta existente especificada). (5 horas).
Durante la elaboración de esta primitiva versión del creador de instaladores, me
surgieron las primeras dificultades y dudas. Una de ellas fue el modo de compilar el
fichero “Instalador.java” (esto es, el instalador en sí) de un modo automático y fácil; por ejemplo, con doble clic. El problema lo resolví mediante la construcción de
un archivo ejecutable por lotes (.bat), en el cual se incluían las órdenes necesarias
para compilar (mediante javac.exe) y ejecutar (mediante java.exe) el instalador.
Otro problema, muy ligado al anterior, era que el sistema no encontraba la ruta del
javac.exe, debido a una incorrecta configuración de la variable de entorno
CLASSPATH. Tras resolver esto, el fichero .bat se ejecutaba sin presentar más dificultades. Por último, apuntaré que el modo de copiar el fichero en el directorio fue
a través de la creación de un búfer de datos, el cual leía una determinada cantidad
de bytes del fichero para escribirlos en el fichero de destino (3 horas).
25/10/2009: Consigo que la aplicación lea de un fichero XML tanto el nombre del
archivo que se quiere instalar como la ruta de la instalación, así como el nombre
que se desea que tenga el instalador. Esto sólo fue posible tras la instalación de
JDom en mi equipo, válido para facilitar el acceso a ficheros XML que deben ser leídos por programas en Java. Además, consigo crear desde el programa el .bat referido anteriormente, el cual compila y ejecuta el instalador (5 horas).
74
13/11/2009: Realizo mi primer instalador mediante IzPack. Dicho instalador se encarga de instalar una pequeña aplicación en Java en los directorios que se le dictan.
El objetivo de aprender a manejar IzPack se debe a dos razones: conocer con más
profundidad la funcionalidad de este programa para aplicarla a mi creador de instaladores y crear el instalador definitivo de TutorMates, si la empresa decidiera que
lo haga yo (lo cual supondría una remuneración económica por esta labor). (6
horas).
Con el fin de crear la primera instalación en IzPack fue necesario obtener los conocimientos más básicos acerca de los ficheros jar (cómo crearlos y cómo ejecutarlos,
por ejemplo), ya que la propia instalación se ejecuta a través de estos ficheros (3
horas).
15/11/2009: Consigo que mi aplicación para crear instaladores construya automáticamente un desinstalador de la aplicación que se pretende instalar, basado en un
algoritmo recursivo (con el fin de poder borrar posibles subdirectorios, así como todos los ficheros creados). Del mismo modo, también es capaz de construir un
fichero jar en el que se comprimen y empaquetan tanto el instalador como el desinstalador a los que me he referido anteriormente, lo cual permite la ejecución de
la aplicación en cualquier ordenador que tenga instalada la máquina virtual de
Java. Además, se consiguió que ambos se ejecutaran mediante doble clic gracias a
la construcción de los correspondientes ficheros jar ejecutables (acompañados de
sus ficheros manifest, que indican dónde encontrar la clase que contiene al método
principal). (4 horas).
23/11/2009: El creador de instaladores puede hacer que el instalador copie archivos en el escritorio, así como que instale la aplicación para todos los usuarios o solo
para el usuario actual (mediante el uso de ‘System.getProperties(“user.name”)’). (4
horas).
27/11/2009: La aplicación permite crear una carpeta con un determinado nombre
tanto en la ruta especificada como en el menú “Programas”, siendo esto último opcional. También es opcional la creación de la copia del archivo de la aplicación en el
escritorio (3 horas).
1/12/2009: La aplicación permite instalar varios archivos (no solo uno) tanto en la
ruta especificada como en el menú “Programas”, de modo que en el escritorio,
además, se pueda instalar una copia del archivo principal de la aplicación (5 horas).
5/12/2009: Finalizo el Documento de Objetivos del Proyecto (DOP), primer documento válido para la memoria del PFC (12 horas).
8/12/2009: El instalador se puede ejecutar mediante un ejecutable .exe. Para ello,
fue necesaria la creación de un archivo C++ para compilarlo desde el fichero Java,
cuyo código permite la creación del instalador (haciendo lo mismo que hacía el
.bat). (4 horas). Además, permite que cualquier fichero de los que se desea instalar
pueda aparecer en el escritorio, si así se indica (1 hora).
75
12/12/2009: Las copias de los ficheros en el escritorio o en el menú Programas son
sustituidas por accesos directos, lo cual permite ahorrar una gran cantidad de espacio en memoria. Para lograr esto, tuve que investigar acerca de cómo crear en
Windows estos accesos directos. Necesité para ello la ayuda de una herramienta,
llamada “shortcut.exe” (5 horas de investigación más 6 horas de implementación y
pruebas).
21/12/2009: El desinstalador permite la eliminación de todas las carpetas y archivos de la instalación, incluyendo al propio desinstalador. Esto fue posible gracias a
la creación de un script que es capaz de borrarse a sí mismo y que además ejecutaba los mandatos necesarios para que las carpetas que no eran eliminadas por el
desinstalador fuesen borradas por el propio sistema operativo. El script es creado
desde el desinstalador (15 horas de investigación más 3 horas de implementación y
pruebas).
25/12/2009: El creador de instaladores permite que todos los archivos que se utilizarán en la instalación (iconos, ficheros jar, etcétera) puedan estar ubicados en
cualquier subdirectorio de la carpeta en la que se encuentra (y no necesariamente
en la misma carpeta), siempre y cuando esto se indique adecuadamente en el fichero XML del que se leen las características de la instalación (2 horas).
26/12/2009: El instalador también permite crear accesos directos en el menú aplicaciones (todos los programas), en la carpeta Inicio y en el menú Inicio, si así se especifica (2 horas).
10/01/2010: El creador de instaladores permite definir los datos que se modificarán en el registro de Windows, una vez instalada la aplicación, así como borrar las
entradas introducidas en el registro al desinstalarla. Las entradas que se añaden y
las claves que se modifican son:
o HKLM\Software\<Programa>
Install_Dir (opcional)
o HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\<Programa>
DisplayIcon (opcional)
DisplayName
DisplayVersion (opcional)
HelpLink (opcional)
InstallLocation
NoModify (opcional)
NoRepair (opcional)
UninstallString
URLInfo (opcional)
(3 horas de investigación + 6 horas de implementación).
17/01/2010: El registro de Windows puede modificarse a gusto del cliente. Además, el programa mantiene las opciones de modificación del registro por defecto
(3 horas). Por otro lado, el creador de instaladores permite copiar directorios enteros en el lugar especificado (1 hora).
76
12/02/2010: El creador de instaladores permite ejecutar archivos externos a la instalación, tales como ficheros de texto (tipo readme) o incluso otros instaladores (de
programas que pueden ser necesarios para que el que queremos instalar funcione
correctamente). (4 horas).
13/02/2010: El programa añade una nueva funcionalidad con respecto a IzPack: es
capaz de proporcionar al usuario final (el que a la sazón instalará la aplicación) un
ejecutable en lugar de solamente un archivo jar, de modo que si el usuario final tiene instalada la JRE de Java en su equipo, el .exe ejecuta directamente el jar, y si no,
instala antes Java. La versión del JRE de Java que se instala es la 6ª, actualización
18. (3 horas de investigación + 5 horas de implementación y pruebas).
16/02/2010: Nueva mejora a la hora de crear accesos directos: el programa permite crear shortcuts a archivos que se encuentran dentro de directorios, y no solo a
archivos que se copian individualmente. Del mismo modo, permite indicar en qué
ubicación dentro de la carpeta de instalación se desea copiar el archivo. Esta mejora surgió a raíz de las peticiones de Jónathan Heras como usuario de mi aplicación
(3 horas).
23/02/2010: El creador de instaladores genera un único fichero auto-ejecutable
que es capaz de descomprimir los archivos que almacena para llevar a cabo la instalación, ejecutar el instalador y gestionar la eliminación de los archivos tras la instalación. Para este fin, se usó el programa 7-zip, que es software open-source (11
horas de investigación + 5 horas de implementación y pruebas). Del mismo modo,
se creó un fichero de texto con las instrucciones de uso del creador de instaladores
y se reorganizaron algunos archivos dentro de la carpeta de la aplicación (2 horas).
25/02/2010: Se genera un manual de instrucciones en formato de texto que permita conocer al usuario cómo manejar la aplicación, lo que es capaz de hacer y los requisitos necesarios para su correcto funcionamiento (1,5 horas).
5/03/2010: Se realiza la documentación del análisis de requisitos (2 horas).
12/03/2010: Se genera la documentación de los casos de uso, la cual incluye la descripción de cada uno de ellos y el diagrama de casos de uso (4 horas).
16/03/2010: Se documenta la interfaz de usuario, en la que se incluyen momentáneamente algunos prototipos de baja calidad (3 horas). Además, se mejora la aplicación de modo que la carpeta con los archivos de la instalación pueda ubicarse en
un directorio nuevo definido por el usuario, y no necesariamente en uno ya existente (1 hora de implementación y pruebas).
19/03/2010: Se modela y representa la interfaz de usuario mediante un diagrama
de estados o statechart, de modo que se clarifique su comportamiento y su modo
de ejecución (2,5 horas).
77
1/04/2010: Se crea un XML-Schema que representa, de un modo más gráfico del
que se podría lograr con un DTD, la estructura que debe tener el fichero XML de
configuración (2 horas).
5/04/2010: Se termina de documentar la interfaz del usuario creador. Esta nueva
documentación incluye una descripción de la estructura que tiene que poseer el fichero XML para que la aplicación funcione correctamente, las precondiciones y
poscondiciones que debe cumplir y una explicación de por qué se descartó la creación de una interfaz gráfica para el usuario creador (3,5 horas).
7/04/2010: Se realiza la documentación del diseño (6 horas).
2/05/2010: Se añade a la documentación del diseño un diagrama de colaboración
que representa la interacción entre los archivos que participan durante el proceso
de instalación y desinstalación (2,5 horas).
23/06/2010: Se documenta la implementación del proyecto (5 horas).
24/06/2010: Se modifica el Documento de Objetivos del Proyecto, de acuerdo a los
acontecimientos que se han ido sucediendo durante los meses que ha durado el
proyecto. Básicamente, los cambios introducidos se refieren a la eliminación de la
funcionalidad relacionada con el soporte multilingüe, que no se considerará por
falta de tiempo. (1 hora).
26/06/2010: Se documentan las pruebas del proyecto (5 horas). Por otro lado, se
realizan las últimas pruebas, encaminadas a determinar la correcta funcionalidad
de la aplicación, lo cual causa modificaciones tanto en el código como en los ficheros DTD y XML-Schema (3 horas).
27/06/2010: Se redactan la introducción y las conclusiones del proyecto (3 horas).
30/06/2010: Se termina la redacción de la primera versión de la memoria, que incluye toda la documentación realizada anteriormente (12 horas).
7/07/2010: Se implementa la interfaz del usuario creador. Para ello, fue necesario
hacer el diseño de la interfaz (8 horas); construir la interfaz en Swing (10 horas); investigar acerca de cómo mostrar un árbol de directorios para que el usuario final
pueda elegir la ruta de la carpeta de instalación (3 horas), para ocultar la consola
de C++ (3 horas), para centrar en la pantalla la ventana (2 horas) y para incluir una
barra de progreso en la interfaz (aunque después no se consiguiera poner en marcha) (5 horas); programar la funcionalidad de la interfaz (16 horas); realizar los
cambios pertinentes en el código para crear el archivo de propiedades
install.properties (6 horas) y realizar la fase de pruebas (7 horas).
13/07/2010: Se añade a la memoria la documentación de la interfaz del usuario final (17 horas). Además, se revisa la memoria y se realizan los cambios pertinentes
en ella, inducidos por la creación de la interfaz (15 horas).
15/07/2010: Se prepara la presentación del PFC (6 horas).
78
Descargar