UNIVERSIDADE DA CORUÑA Departamento de Tecnoloxías da Información e as Comunicacións (TIC) Diseño e Implementación de una Aplicación Web Java EE con Arquitectura MVC Generalidades PFC3 Juan Raposo Santiago http://www.tic.udc.es/~jrs [email protected] Enero 2008 Índice • Enfoque para el Proyecto Herramientas Arquitectura • Generalidades Metodología Proceso Unificado Estándar de Codificación Java • Generalidades Herramientas Apache Maven 2 IDE Eclipse JUnit Enero 2008 PFC3 2 UNIVERSIDADE DA CORUÑA Departamento de Tecnoloxías da Información e as Comunicacións (TIC) Enfoque para el proyecto Enfoque Estándar de codificación Herramientas Arquitectura Enfoque para el Proyecto • Para la realización de la aplicación software del proyecto se aconseja un enfoque basado en iteraciones, de manera que cada iteración incorpora más funcionalidad, hasta que en la última iteración se termina con un software que implementa toda la funcionalidad. En cada iteración se hace análisis, diseño, implementación y pruebas. Enfoque opuesto al concepto tradicional de analizar todo, diseñar todo, implementar y probar todo. • Se divide el problema en iteraciones, y en cada iteración se hace todo el ciclo de vida tradicional. En la primera iteración se aborda lo más complicado, intentando obtener en poco tiempo una arquitectura software que permitirá incorporar el resto de la funcionalidad en subsiguientes iteraciones – “línea base”. • Objetivo: detectar problemas de diseño y/o implementación cuanto antes, y no al final, cuando ya sería demasiado costoso (en tiempo y dinero) rehacer todo el diseño y el código. El resto de las iteraciones van introduciendo funcionalidad menos crítica, y no deberían causar cambios importantes a la línea base. Enero 2008 PFC3 4 Estándar de Codificación • Normalmente en proyectos grandes se suele seguir un estándar de codificación, de manera que el aspecto del código sea el mismo, independientemente de qué programador lo haya escrito. Facilita el mantenimiento del software. • Código de calidad y fácilmente legible. • Un estándar de codificación define: Reglas para nombrar clases, atributos y métodos, normas de identación, etc. • Un documento muy sencillo (breve), pero muy utilizado en el mundo Java son las Java Code Conventions, definidas por Sun Microsystems. http://java.sun.com/docs/codeconv/index.html Enero 2008 PFC3 5 Herramientas • Modelado UML: MagicDraw (instalado en Laboratorios de Docencia FIC) Poseidon for UML Rational Rose • Desarrollo: • HTTP HTML + CSS / XML Java SE 1.6.0 + Apache Struts 1.2.9 + Standard TagLibs 1.1.2 JUnit 4.4 Apache Maven 2 IDE Eclipse Otras: AJAX, Spring, JPA, Hibernate, EJB3, ... Bases de Datos: MySQL 5.0 ó PostgreSQL 8.1 • Servidor Web: Apache Tomcat 6.0.x / Jetty Enero 2008 PFC3 6 Arquitectura del Sistema Capa 1 Navegador Capa 2 Int. Modelo web Capa 3 Base de datos Serv. ap. web Navegador Internet/ Intranet Navegador Enero 2008 PFC3 7 Capas de una Aplicación Web Java EE: MVC+Layers Vista Controlador HTML/CSS + JSP + JSTL Apache Struts ActionForm + Action Factory Interfaces con Casos de Uso (lógica de negocio) Modelo Business Delegate Session Facade CTO Plugin: Plain | RMI | EJB | … Factory Interfaces para Acceso a Datos DAO/TO Plugin: JDBC | XML | … Enero 2008 PFC3 8 UNIVERSIDADE DA CORUÑA Departamento de Tecnoloxías da Información e as Comunicacións (TIC) Generalidades Metodología Introducción al Proceso Unificado El proceso Unificado de Desarrollo de Software. Ivar Jacobson, Grady Booch, James Rumbaugh. Addison Wesley, 2001. Java Code Conventions Sun Microsystems, Java Code Conventions,http://java.sun.com/docs/codeconv/index.html. Introducción al Proceso Unificado (I) • Un proceso de desarrollo de software es el conjunto de actividades necesarias para transformar los requisitos de un usuario en un sistema software: Requisitos del usuario • Proceso Procesode dedesarrollo desarrollo de deSoftware Software Sistema software Proceso Unificado: Más que un proceso de desarrollo de software. Marco de trabajo genérico que puede especializarse para una gran variedad de sistemas software, para diferentes áreas de aplicación, diferentes tipos de organizaciones, diferentes niveles de aptitud y diferentes tamaños de proyecto. Basado en componentes software, interconectados a través de interfaces bien definidas. Utiliza el Lenguaje Unificado de Modelado (Unified Modeling Language, UML) para preparar todos los esquemas de un sistema software. Enero 2008 PFC3 10 Introducción al Proceso Unificado (II) • Orígenes: Modelo original Objectory definido por Ivan Jacobson (1987). Rational Software compra la empresa de Objectory (1995). Surge la primera versión de UML (1997). Se publica la primera versión del Proceso Unificado de Rational RUP (junio 1998). • Características del Proceso Unificado: Dirigido por casos de uso. Centrado en la Arquitectura. Iterativo e incremental. • Guiado por riesgos. Enero 2008 PFC3 11 Introducción al Proceso Unificado (III) • Dirigido por Casos de Uso. Se centra en la funcionalidad que el sistema debe poseer para satisfacer las necesidades de un usuario (persona, sistema externo, dispositivo) que interactúa con él. Casos de uso como el hilo conductor que orienta las actividades de desarrollo. Casos de Uso <<defineNecesidades>> Análisis Recopilar, Clarificar y Validar los requisitos Enero 2008 <<realiza>> <<verifica>> Diseño Pruebas Realizar los casos de uso Verificar que se satisfacen los casos de uso PFC3 12 Introducción al Proceso Unificado (IV) • Centrado en la Arquitectura. Concepto similar a la arquitectura de un edificio: • Varios planos con diferentes aspectos del edificio. • Tener una imagen completa del edificio antes de que comience la construcción. Arquitectura en software: • Diferentes vistas del sistema: estructural, funcional, dinámico, etc. • Plataforma en la que va a operar. • Determina la forma del sistema. • Arquitectura: determina la forma del sistema. • Casos de uso: determinan la función del sistema. Enero 2008 PFC3 13 Introducción al Proceso Unificado (V) • Iterativo e Incremental: Descomposición de un proyecto grande en mini-proyectos. Cada mini-proyecto es una iteración. Las iteraciones deben estar controladas. Cada iteración trata un conjunto de casos de uso. • Ventajas del enfoque iterativo: Detección temprana de riesgos. Administración adecuada del cambio. Mayor grado de reutilización. Mayor experiencia para el grupo de desarrollo. • Guiado por riesgos: Se detectan los riesgos graves para asegurarlos lo antes posible. El objetivo es detectar los problemas lo antes posible para darles solución rápidamente. Enero 2008 PFC3 14 Rational Unify Process (RUP) - Dimensiones • Estática - Flujos de trabajo. • Roles Actividades Artefactos Flujo de Trabajo QUIÉN? CÓMO? QUÉ? CUÁNDO? Dinámica El Proceso Unificado se repite a lo largo de una serie de ciclos que constituyen la vida de un sistema. • Ciclo: cada ciclo una nueva versión del producto. • Fase: Etapas de un ciclo que finalizan en un HITO. • Iteración: Proceso de ingeniería sobre una funcionalidad limitada del sistema. En cada fase se realizan una o más iteraciones a través de los flujos de tareas: requisitos no procedimentales (de eficiencia) y casos de uso, Análisis (opcional), Diseño, Implementación y Pruebas. • Entradas al proceso: Lista de características: descripción informal (2 páginas) de lo que se espera del desarrollo. Modelo de dominio (Opcional). Modelar con UML el entorno en el que operará el producto. Enero 2008 PFC3 15 Dimensión Estática del Proceso (I) • Rol Definición del comportamiento y responsabilidades de los participantes. Propietario de una serie de artefactos. • Actividad Unidad de trabajo que puede ejecutar un individuo en un rol específico. Tiene un propósito claro y se expresa en términos de “actualizar” artefactos. La granularidad de la actividad es generalmente de horas o pocos días. Ejemplos de actividades: • Planear una iteración (administrador del proyecto). • Encontrar caso de uso y actores (analista del dominio). • Revisión del diseño (probador). Enero 2008 PFC3 16 Dimensión Estática del Proceso (II) • Artefacto Pieza de información producida, modificada y utilizada en un proceso. Productos tangibles del proyecto. Utilizados por los roles como entrada para la realización de sus actividades. Resultado de las actividades realizadas por los roles. • Flujo de Trabajo Forma de describir la secuencias de actividades que producen resultados y las interacciones entre cargos. En términos de UML se puede utilizar: diagrama de actividades, de secuencia, de colaboración. Enero 2008 PFC3 17 Dimensión Dinámica del proceso ciclo fase Concepción Elaboración hito 1 Iter. 1 Construcción hito 2 Iter. 2 hito 3 Iter. 3 Iter. 4 Iter. 5 Transición hito 4 Iter. 6 Hito: punto en el tiempo donde se evalúan los objetivos logrados y se pueden tomar decisiones críticas Enero 2008 PFC3 18 Desarrollo Iterativo Construcción Iteración de desarrollo 1 Análisis Enero 2008 Iteración de desarrollo 2 Iteración de desarrollo n Perfeccionar el plan Sincronizar Artefactos Diseño Implementación PFC3 Pruebas 19 Fase de Concepción • Objetivo: Definir la razón de ser y el alcance del proyecto. Estudio de oportunidad. Visión = QUÉ + PARA QUÉ + CUÁNTO • Actividades: Especificación de los criterios de éxito del proyecto. Definición de los requisitos. Estimación de los recursos necesarios. Cronograma inicial de fases. • Artefactos: Documento de definición del proyecto. Enero 2008 PFC3 20 Fase de Elaboración • • Objetivo: Establecer un plan de proyecto y una arquitectura correcta del sistema. Actividades: • Artefactos: • Análisis del dominio del problema. Definición de la arquitectura básica. Análisis de riesgos. Planificación del proyecto. Modelo del dominio. Modelo de procesos. Modelo funcional de alto nivel. Arquitectura básica. Al final de la fase de elaboración se establece la línea base de la arquitectura. Los riesgos de la lista de riesgos están mitigados (con solución, implementada o no). En realidad, además de la línea base de la arquitectura también se habrán implementado aquellos elementos necesarios asociados a los casos de uso de la línea base, pero que no son críticos (no existían dudas para su realización). Enero 2008 PFC3 21 Fase de Construcción / Transición • Fase de Construcción. Objetivo: Desarrollar el sistema a lo largo de una serie de iteraciones. Actividades: • Análisis. • Diseño. • Implementación / Codificación. – El flujo de tareas de implementación se divide en Builds: consolidación del trabajo de los desarrolladores (punto de encuentro del trabajo de varios diseñadores). • Pruebas (individuales, de integración). • Fase de Transición. Pruebas beta (de usuario). Enero 2008 PFC3 22 Ciclo de Vida del Proceso Unificado Ágil - AUP Enero 2008 PFC3 23 Resumen Java Code Conventions (I) • Extensiones de ficheros: .java, .class • Un fichero por clase pública o interfaz. Puede incluir clases privadas, pero siempre después de la pública. • Estructura de un fichero con código fuente: Comentarios de inicio. /* * Classname, Programmer(s), Date * Version info * Copyright notice * Description */ Paquete y lista de imports necesarios. Enero 2008 PFC3 24 Resumen Java Code Conventions (II) • Estructura de un fichero con código fuente (continuación): Declaración de clase o interfaz. • • • • /** ... */ Comentario Javadoc de Clase o Interfaz. Declaración “class” o “interface”. /* ... */ Comentario de implementación, si es necesario. Variables de Clase (static). – public > protected > private • Variables de instancia. – public > protected > private • Constructores. • Métodos. – • • • Agrupados por funcionalidad para facilitar el entendimiento del código. Identación, 4 espacios (con algunas excepciones para mejorar legibilidad). Longitud de línea como mucho 80 caracteres. División de líneas: después de una coma. antes de un operador. dar preferencia a divisiones de nivel superior. alinear la nueva línea con el comienzo de la expresión del mismo nivel en la línea anterior. si al aplicar estas reglas el código queda poco legible, utilizar 8 espacios. Enero 2008 PFC3 25 Resumen Java Code Conventions (III) • Comentarios: Javadoc /** ... */, Bloque/línea /* ... */, Fín de línea // ... • Declaraciones: Una por línea. Definir variables al comienzo de bloques “{ }” (más claro) e inicializarlas cuando se definen si es posible. • Excepción: bucles for Evitar declaraciones locales para ocultar declaraciones de niveles superiores. Clases e interfaces: • No utilizar espacio entre el nombre del método y el paréntesis de inicio de lista de parámetros. • La llave de inicio aparece al final de la línea de declaración de la sentencia. • La llave de fin aparece al comienzo de línea, identada con el inicio de la sentencia que cierra. – Excepción: métodos vacíos Æ {} • Los métodos se separan por una línea en blanco. Enero 2008 PFC3 26 Resumen Java Code Conventions (IV) • Sentencias: Una por línea. Sentencias compuestas Æ entre “{}” • Sentencias incluidas deben de ser identadas. • “{“ aparecerá al final de la línea de inicio del bloque; y “}” al principio de línea, identado con el inicio del bloque. • En sentencias if-then-else o bucles, se utilizará siempre “{}” aunque el bloque esté compuesto por una sola sentencia. – Esto facilita el mantenimiento del código (por ejemplo, si en el futuro se añade una nueva línea al bloque, el programador podría olvidarse de añadir las llaves). Sentencias return no deben especificarse entre paréntesis, salvo por claridad. Sentencias if, for, while, do/while, switch, try/catch Enero 2008 PFC3 27 Resumen Java Code Conventions (V) if (condition) { statements; } for (initialization; condition; update) { statements; } if (condition) { statements; } else { statements; } for (initialization; condition; update); if (condition) { statements; } else if (condition) { statements; } else if (condition) { statements; } while (condition) { statements; } while (condition); do { statements; } while (condition); try { statements; } catch (ExceptionClass e) { statements; } finally { statements; } Enero 2008 PFC3 switch (condition) { case ABC: statements; /* falls through */ case DEF: statements; break; case XYZ: statements; break; default: statements; break; } 28 Resumen Java Code Conventions (VI) • Dos líneas en blanco: • Entre secciones de un fichero fuente. • Entre definiciones de clases e interfaces. • Una línea en blanco: • • • • Entre métodos. Entre definición de variables locales y la primera sentencia. Antes de un comentario de bloque o de línea. Entre secciones lógicas de un método. • Espacios en blanco: Antes de un paréntesis, salvo que sea la invocación de un método. Después de una coma, en una lista de argumentos. Para separar los operandos de todos los operadores binarios excepto “.” (no aplicable a operadores unarios). Para separar las expresiones de una sentencia for Los casts deben de ir seguidos por un espacio. Enero 2008 PFC3 29 Resumen Java Code Conventions (VII) • Convenciones de nombrado (nombres representativos) Clases: • Deben de ser nombres, con la primera letra de cada palabra involucrada en ese nombre, en mayúsculas. Interfaces: • Ídem clases. Métodos: • Deben de ser verbos, con la primera letra de cada palabra involucrada en mayúsculas, salvo la de la primera. Variables: • Palabras, con la primera letra de cada palabra involucrada en mayúsculas, salvo la de la primera. • Nombres comunes para variables temporales son i,j,k (numéricas) c,d,e (caracteres). Constantes: • En mayúsculas, separando cada palabra involucrada en el nombre por el carácter subrayado “_”. Paquetes (no incluido en Java Code Conventions): • Palabras simples y en minúsculas. Enero 2008 PFC3 30 Resumen Java Code Conventions (VIII) • Prácticas de Programación (salvo casos justificados): Variables de clase o instancia no deben de ser públicas. Evitar acceder a variables de clase desde instancias de objetos. Las constantes numéricas deben de definirse previamente en lugar de utilizarlas como literales (salvo inicializaciones como -1, 0, 1). Asignación de variables: • Evitar asignaciones múltiples en la misma sentencias (difícil de leer). • No utilizar el operador de asignación en lugares en los que pueda ser fácilmente confundido con el operador de igualdad. • No utilizar asignaciones embebidas para intentar optimizar la ejecución. Esa es tarea del compilador. Es buena práctica utilizar paréntesis en expresiones que combinan múltiples operadores, aunque no sean necesarios por las reglas de precedencia de los mismos. Estructurar el programa de forma que sólo haya una sentencia return. En sentencias con “?”, si la expresión condicional contiene un operador binario, es recomendable ponerlo entre paréntesis. Comentarios especiales: • XXX – Marca algo que tiene algún problema pero funciona. • FIXME – Marca algo como que no funciona correctamente. • TODO – Marca algo como que está por terminar. Enero 2008 PFC3 31 Java Code Conventions ... Ejemplo (I) /* * Firstname Lastname * * Copyright (c) 1993-1996 Sun Microsystems, Inc. All Rights Reserved. * */ package java.blah; import java.blah.blahdy.BlahBlah; /** * Class description goes here. * * @version 1.10 04 Oct 1996 * @author Firstname Lastname */ public class Blah extends SomeClass { /* A class implementation comment can go here. */ /** classVar1 documentation comment */ public static int classVar1; /** * classVar2 documentation comment that happens to be * more than one line long */ private static Object classVar2; /** instanceVar1 documentation comment */ public Object instanceVar1; Enero 2008 PFC3 32 Java Code Conventions ... Ejemplo (II) /** instanceVar2 documentation comment */ protected int instanceVar2; /** instanceVar3 documentation comment */ private Object[] instanceVar3; /** * ...method Blah documentation comment... */ public Blah() { // ...implementation goes here... } /** * ...method doSomething documentation comment... */ public void doSomething() { // ...implementation goes here... } /** * ...method doSomethingElse documentation comment... * @param someParam description */ public void doSomethingElse(Object someParam) { // ...implementation goes here... } } Enero 2008 PFC3 33 UNIVERSIDADE DA CORUÑA Departamento de Tecnoloxías da Información e as Comunicacións (TIC) Generalidades Herramientas Herramientas de Gestión de Proyectos Software Maven 2 IDE Eclipse Pruebas de Aplicaciones Software JUnit Gestión de Proyectos - Apache Maven 2 (I) • Herramienta de Gestión de proyectos Software. Open Source. • Proyecto Apache (http://maven.apache.org). • Utilizada en otros desarrollos. Desarrollada en Java. • Otras herramientas existentes: • Shell-based (gnumake, nmake, …) – Ejecutan comandos específicos del sistema operativo Æ (no reutilizables en diferentes plataformas). – Formatos 'estrictos' (ej. tabuladores en Makefiles). • Ant – enfoque basado en tareas – Crear el script build con las tareas a ejecutar. – Ejecutar los targets. • Maven1 – enfoque declarativo (más alto nivel que Ant) – Describir el proyecto y configurar plugins. – Ejecutar plugins existentes (goals). • Maven2 – convenciones de nombrado – Convenciones de nombrado. – Sistema de plugins. – Sistema de dependencia entre paquetes similar al del “mundo linux” de un repositorio. Enero 2008 PFC3 35 Apache Maven 2 (II) • Núcleo de Maven: POM (Project Object Model). Contiene una descripción detallada del proyecto, incluyendo información de versiones, gestión de configuración, dependencias, recursos de la aplicación y de pruebas, miembros del equipo, ... Fichero XML situado en el directorio raíz del proyecto Æ pom.xml • Documentación Maven 2: Maven en 5 minutos. • http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html Maven en 30 minutos. • http://maven.apache.org/guides/getting-started/index.html Enero 2008 PFC3 36 Apache Maven 2 (III) • Ventajas estandarización en gestión de proyectos: No se pierde tiempo reinventando estructuras de directorios, convenciones ni personalizando scripts para cada proyecto. Maven permite redefinir la estructura de directorios estándar pero es conveniente respetarla por las siguientes razones: • El fichero pom.xml será más pequeño y sencillo. • Hace que el proyecto sea más fácil de entender y facilita el mantenimiento futuro por otros. • Facilita la integración de plugins (asumen también la estructura por defecto). Enero 2008 PFC3 37 Apache Maven 2 – pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>es.udc.fbellas.j2ee</groupId> <artifactId>standardutil</artifactId> <packaging>jar</packaging> <version>2.2.0</version> <name>J2EE-Examples Standard Util Subsystem</name> <url>http://www.tic.udc.es/~fbellas/teaching/is</url> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.0.5</version> <scope>test</scope> </dependency> </dependencies> </project> Enero 2008 PFC3 38 Apache Maven 2 – Ciclo de Vida • Fases de construcción de un proyecto: “compile”, “test”, “deploy”, … En Ant se crean “targets” con esos nombres que implementen esa semántica. En Maven 1 se invocan plugins (goals) existentes. • Un lenguaje de Scripting basado en XML, Jelly, permite definir nuevos goals o modificar el comportamiento de los existentes. En Maven 2 se estandariza el conjunto de fases del ciclo de vida del proyecto, y al ejecutar una de ellas se ejecutarán los plugins correspondientes. • Es posible implementar nuevos plugins a asociar a las diferentes fases, como clases Java. Para compilar: mvn compile Enero 2008 PFC3 39 Apache Maven 2 – Dependencias • En el fichero pom.xml se definen los recursos de los que depende un proyecto. Maven automáticamente descarga los recursos de repositorios remotos en repositorios locales. • Local a la máquina (estructura de directorios en base al groupid y artifactid del recurso): – Maven 1 Æ $HOME/.maven/repository – Maven 2 Æ $HOME/.m2/repository • Gestión de Dependencias Transitivas: Maven 1 obliga a que cada proyecto defina todos los jars necesarios, directa o indirectamente por la aplicación. Con Maven 2 sólo es necesario especificar los jars que la aplicación necesita de forma directa; Maven 2 gestiona las dependencias de las librerías utilizadas, para incluirlas de forma automática. • Ámbitos de Dependencias – en función de las fases (Maven 2) compile Æ necesaria en todas las fases (valor por defecto). provided Æ necesaria para compilar pero no para instalar (e.g. servlet API). runtime Æ necesaria sólo para ejecutar (e.g. JDBC drivers). test Æ necesaria sólo para pruebas (e.g. JUnit API). Enero 2008 PFC3 40 Apache Maven 2 – Configuración Proxy • Dos opciones: Creando un fichero settings.xml en el directorio $HOME/.m2 (repositorio local) con la siguiente información (ej. fichero /opt/ISyADOO0708/SoftwareLocal/templates/IS/settings.xml). <?xml version="1.0" encoding="UTF-8"?> <settings> <proxies> <proxy> <active/> <protocol>http</protocol> <port>3128</port> <!-- <host>proxy</host> --> <host>proxy-wifi.ucv.udc.es</host> <id/> </proxy> </proxies> </settings> Ejecutar Maven indicando la configuración de proxy en cada comando como parámetros. mvn -Dhttp.proxyHost=proxy -Dhttp.proxyPort=3128 ... Enero 2008 PFC3 41 Ejemplos - Estructura Maven 2 pom.xml pom.xml MySQLCreateTables.sql PostgreSQLCreateTables.sql ConfigurationParameters.properties Enero 2008 PFC3 42 Ejemplos - Plugins de Maven 2 – Assembly <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptors> <descriptor>src/main/assembly/src.xml</descriptor> </descriptors> </configuration> </plugin> Enero 2008 <assembly> <id>src</id> <formats> <format>zip</format> <format>tar.gz</format> <format>tar.bz2</format> </formats> <fileSets> <fileSet> <includes> <include>**/*</include> </includes> <excludes> <exclude>**/target/**</exclude> </excludes> </fileSet> </fileSets> </assembly> PFC3 43 Ejemplos - Plugins de Maven 2 – SQL • http://mojo.codehaus.org/sql-maven-plugin/ <!-- Setting SQL Plugin --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>sql-maven-plugin</artifactId> <dependencies> <!-- specify the dependent JDBC driver here --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-jdbcdriver-version}</version> </dependency> </dependencies> <!-- common configuration shared by all executions --> <configuration> <!– MySQL --> <driver>com.mysql.jdbc.Driver</driver> <url>jdbc:mysql://localhost/j2ee</url> <username>j2ee</username> <password>j2ee</password> <autocommit>true</autocommit> <onError>continue</onError> <fileset> <basedir>${basedir}</basedir> <includes> <include>src/sql/MySQLCreateTables.sql</include> </includes> </fileset> </configuration> </plugin> Enero 2008 PFC3 44 Ejemplos - Plugins de Maven 2 – Jetty • http://docs.codehaus.org/display/JETTY/Jetty+Documentation <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <configuration> <jettyEnvXml>../src/main/jetty/jetty-env.xml</jettyEnvXml> <scanIntervalSeconds>5</scanIntervalSeconds> <!-- Log to the console. --> <requestLog implementation="org.mortbay.jetty.NCSARequestLog"> <!-- This doesn't do anything for Jetty, but is a workaround for a Maven bug that prevents the requestLog from being set. --> <append>true</append> </requestLog> </configuration> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-jdbcdriver-version}</version> </dependency> … </dependencies> </plugin> Enero 2008 PFC3 45 Ejemplos - Plugins de Maven 2 – Jetty • jetty-env.xml <?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"> <Configure class="org.mortbay.jetty.webapp.WebAppContext"> <!-- PostgreSQL --> <!-- … --> <!-- MySQL --> <New id="J2EE-ExamplesDS-MySQL" class="org.mortbay.jetty.plus.naming.Resource"> <Arg>jdbc/J2EE-ExamplesDS</Arg> <Arg> <New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"> <Set name="url">jdbc:mysql://localhost/j2ee</Set> <Set name="user">j2ee</Set> <Set name="password">j2ee</Set> </New> </Arg> </New> </Configure> Enero 2008 PFC3 46 Ejemplos - Compilación • Linux, Windows // Mysql, PostgreSQL. • Configuración por defecto: Linux, Mysql, Base de Datos j2ee (default port), usuario j2ee, password j2ee • Arrancar la base de datos. • Utilizar maven para crear las tablas en la base de datos y compilar los ejemplos. cd j2ee-examples-2.2.0-src mvn sql:execute install Enero 2008 PFC3 47 Eclipse IDE (http://www.eclipse.org) Compile Run Debug Plugins - Maven - Subclipse - Tomcat -… n o i dit E itors t c je ... ed ro, SQL, P ls L o PX, XM o b T P, JS rer WeTML, aJSse explo - H tab a -d . - .. Enero 2008 PFC3 48 Eclipse - Crear Proyectos • Creación de la configuración de proyectos para eclipse (en función de la información del pom.xml): mvn eclipse:eclipse • Configuración de Eclipse para importar cada subsistema de los ejemplos como un proyecto. Arrancar eclipse. • eclipse& Crear un nuevo proyecto Java: • File > New > Project >> Java / Java Project – Wizard New Java Project • Especificar nombre del proyecto (Project name): standardutil – Ponerle el mismo nombre que tiene en maven para que se resuelvan bien las dependencias entre proyectos. • Seleccionar "Create project at external location“. • Especificar directorio HOME del proyecto (Browse to j2ee-examples2.2.0/standardutil directory). • Click sobre "Finish". Enero 2008 PFC3 49 Eclipse - Configurar Proyectos Enero 2008 PFC3 50 Eclipse & Maven2 • Para cargar un proyecto eclipse generado a partir de “mvn eclipse:eclipse” es necesario definir la variable de entorno M2_REPO para que apunte al directorio en el que se encuentre el repositorio de MAVEN 2. Windows: • C:/Documents and Settings/<userName>/.m2/repository Linux: • $HOME/.m2/repository • Para añadir la variable de entorno M2_REPO a Eclipse Window > Preferences > Java > Build Path > ClassPath variables. Enero 2008 PFC3 51 Depuración de Aplicaciones en Java • La opción -g del compilador provoca que se añada código (bytes codes) para poder seguir la traza de la ejecución de un programa. • La aplicación resultante genera eventos que pueden ser procesados por una aplicación externa (ej. un IDE) • Java dispone de una API estándar que permite interceptar estos eventos y acceder al entorno de ejecución de una aplicación compilada con la opción -g. • Ej. Un IDE puede registrarse en la aplicación para recibir los eventos correspondientes a los puntos de ruptura que establezca el desarrollador, y posteriormente permitirle al usuario visualizar el entorno de ejecución. Enero 2008 PFC3 52 Eclipse - Ejecución y Depuración de clases • Ejecución de una clase: Run > Run As > Java Application > Seleccionar la clase a ejecutar y los argumentos. • La salida se muestra en la consola de eclipse. Se puede seleccionar una clase en la jerarquía de clases y botón derecho + Run As > Java Application • Depuración: Eclipse posee una perspectiva para depuración de aplicaciones. • Permite seguir la traza de ejecución de una aplicación, establecer puntos de interrupción y visualizar el estado de las variables en un instante determinado. Run > Debug As > Java Application Botón derecho + Debug As > Java Application • Otros Window > Show View > Other > Connectivity > Data Source Explorer Enero 2008 PFC3 53 Eclipse - Ejecución de Pruebas de Unidad • • Los ejemplos no usan JUnit JDBCTutorial: Iniciar la base de datos. Ejecución desde Eclipse. es.udc.fbellas.j2ee.jdbctutorial.InsertExample es.udc.fbellas.j2ee.jdbctutorial.SelectExample es.udc.fbellas.j2ee.jdbctutorial.PreparedStatementExample es.udc.fbellas.j2ee.jdbctutorial.TransactionExample fbellas-1 fbellas-2 es.udc.fbellas.j2ee.jdbctutorial.Transference1Example fbellas-1 fbellas-2 es.udc.fbellas.j2ee.jdbctutorial.Transference2Example fbellas-1 fbellas-2 es.udc.fbellas.j2ee.jdbctutorial.Transference3Example fbellas-1 fbellas-2 es.udc.fbellas.j2ee.jdbctutorial.Transference4Example fbellas-1 fbellas-2 • En el resto de subsistemas, para ejecutar las pruebas de unidad: Descomentar los métodos main de las clases a probar. Puede haber que descomentar los imports que haya debajo del comentario // For Testing. Enero 2008 PFC3 54 Eclipse: Plugin Maven 2 • Creación de una nueva configuración “maven” para eclipse: Run > External Tools > Open External Tools Dialog .. > Maven Build botón derecho + "New" Especificar el nombre de la nueva configuración de maven. Main: Especificar el directorio donde se encuentra el pom.xml a utilizar. Goals: Indicar los goals a ejecutar en esta configuración. • “Select” para elegir una de las fases del ciclo de vida. • Ejecución de una configuración “maven” para eclipse: Run > External Tools > Nombre de Tarea a Ejecutar. • Organización de configuraciones preferidas: Run > External Tools > Organize Favourites • Botón derecho sobre un pom.xml + Run As > Maven build … Enero 2008 PFC3 55 Creación Inicial de un Proyecto (I) • Creación del esqueleto de un proyecto. + mvn archetype:create -DarchetypeArtifactId=maven-archetype-quickstart -DgroupId=es.udc.j2eeapp -DartifactId=j2ee-app + + + + + cd j2ee-app cd src mkdir main/resources mkdir test/resources Copiar j2ee-examples/jdbctutorial/src/main/resources/ConfigurationParameters.properties a main/resources y test/resources + mvn eclipse:eclipse + Importar el proyecto desde Eclipse: "File -> New -> Java Project". Elegir nombre de proyecto (e.g. j2ee-app) y la opción "Create project from existing source" (elegir directorio que se creó el proyecto). NOTA: sustituir j2ee-app por el nombre del proyecto Enero 2008 PFC3 56 Creación Inicial de un Proyecto (II) • Hacer modificaciones básicas al proyecto desde Eclipse. + Ajustar configuración proyecto: "Project -> Properties -> Java Compiler -> Error/Warnings": * Potential programming problems: "Serializable class without serialVersionID (Ignore)". * Generic Types: "Uncheck generic type operation (Ignore)" y "Usage of a raw type (Ignore)". Enero 2008 PFC3 57 Creación Inicial de un Proyecto (III) • Hacer modificaciones básicas al proyecto desde Eclipse. + Reemplazar la sección <dependencies> del pom.xml con: <dependencies> <dependency> <groupId>es.udc.fbellas.j2ee</groupId> <artifactId>standardutil</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.4</version> <scope>test</scope> </dependency> </dependencies> + cd j2ee-app + mvn eclipse:eclipse proyecto) Enero 2008 (por seguridad, hacer un refresh [F5] del PFC3 58 Pruebas de Unidad / Integración • ¿Qué es una prueba de unidad? Prueba individual de hardware o software, o grupos de unidades relacionadas. • Normalmente, un test de unidad es un código que prueba una “unidad”: que puede ser una clase, un componente, un módulo o una función. • Las pruebas se crean y se ejecutan mientras se desarrolla el software. • Las pruebas de unidad no son pruebas funcionales, de aplicación. • Las pruebas de unidad no son interactivas. En general, el objetivo de las pruebas de unidad es comprobar que los diferentes componentes del SW funcionan de forma aislada y que ante cambios en el código continuan funcionando. • Un Framework de pruebas de unidad proporciona: Un mecanismo para organizar y agrupar varios tests. Una forma sencilla de invocar tests. Un indicación clara de qué tests han sido exitosos o fallidos. Una forma estándar para escribir tests y especificar resultados esperados. Enero 2008 PFC3 59 ¿Qué es Junit? • JUnit es un framework para escribir pruebas de unidad repetibles en Java. http://www.junit.org/ Open Source. Programado por Erich Gamma y Kent Beck. • Características: Utiliza aserciones para comprobar resultados esperados. Enero 2008 PFC3 60 Junit 4.x - Pruebas de Unidad (I) • • Requiere Java SE 5.0. Utiliza anotaciones @Test para marcar un método como un caso de prueba. Parámetro timeout (falla si tarda más de ese tiempo en ejecutarse). Parámetro expected especifica el tipo de excepción a lanzar para que sea exitoso. • Comprobaciones: Pueden realizarse varias comprobaciones (aserciones) por método. La clase Assert proporciona un conjunto de métodos estáticos para realizar comprobaciones (pueden lanzar un objeto con mensajes de fallo). Assert.assertEquals(Object, Object) Æ Compara utilizando el método "equals". • Si no se redefine, el método equals de un Object realiza una comparación por referencia; es necesario redefinir el método equals de una clase para la que se desee comparación por contenido. – La clase String y las correspondientes a los tipos básicos lo tienen redefinido Î comparan por contenido. Enero 2008 PFC3 61 Junit 4.x - Pruebas de Unidad (II) import static org.junit.Assert.assertEquals; public class AdditionTest { private int x = 1; private int y = 1; @Test public void addition() { int z = x + y; assertEquals(2, z); } @Test(expected=ArithmeticException.class) public void divideByZero() { int n = 2 / 0; } } import static org.junit.Assert.assertEquals; public class AccountServiceTest { ... @Before public void setUpTestDataWithinTransaction() throws Exception { testAccount = new Account(1, 10); accountService.createAccount(testAccount); } @Test public void testFindAccount() throws InstanceNotFoundException { Account account = accountService.findAccount(testAccount.getAccountId()); assertEquals(testAccount, account); } } Enero 2008 PFC3 62 Junit 4.x - Inicialización y Borrado de Datos de Prueba • La idea de hacer las pruebas con JUnit es que sean "pruebas automáticas". • Por tanto, cuando se ejecute, debe hacer con anterioridad todo lo que sea necesario (crear datos) y con posterioridad restaurar el estado inicial (eliminar datos). Utiliza anotaciones @Before y @After para definir los métodos a ejecutar antes y después de la ejecución de cada prueba. Utiliza anotaciones @BeforeClass y @AfterClass para definir los métodos a ejecutar antes y después de la ejecución del conjunto de pruebas de una clase. @Before protected void setup() { ... } @BeforeClass protected void setup() { ... } @After protected void tearDown() { ... } @AfterClass protected void tearDown() { ... } Enero 2008 PFC3 63 Código de pruebas • Las clases que implementan las pruebas suelen implementarse en el mismo paquete que la clase que prueban, pero en un directorio de fuentes diferente. Enero 2008 PFC3 64 Referencias • Asignatura “Integración de Sistemas”. Facultade de Informática. Universidade da Coruña • http://www.tic.udc.es/~fbellas/teaching/is • Asignatura “Proyecto de Fin de Carrera”. Facultade de Informática. Universidade da Coruña. • http://www.tic.udc.es/~jrs/teaching/pfc3 Enero 2008 PFC3 65