domingo, 5 de septiembre de 2010

SubVersion, Eclipse y las ramas de desarrollo. (III) Crear la rama




Vamos a ponernos en situación: tenemos un proyecto y hemos decidido abrir dos vías de desarrollo. Los motivos pueden ser muchos: queremos hacer pruebas de implementación de unas nuevas librerías sin afectar al resto del equipo; queremos continuar con el desarrollo de una fase posterior dejando la rama principal (trunk) al mantenimiento de la fase recién entregada; puede haber mil motivos por los que queramos tener dos caminos paralelos en el desarrollo.

El caso es que, por el motivo que sea, hemos decidido abrir una rama, un branch que diríamos en nuestro querido espanglis. Y nos toca implementar esa decisión en el SVN. Pues nada, ahí vamos. Nos hemos creado 6 ficheros en el proyecto, que resumen los posibles casos que se pueden dar en una situación real:

- Fichero sin modificar en trunk ni en branch
- Fichero modificado en trunk y no en branch
- Fichero modificado en branch y no en trunk
- Fichero modificado en trunk y en branch
- Fichero borrado en trunk
- Fichero borrado en branch


Como es lógico, no va a haber una receta universal para estos archivos. Es decir, en el momento de juntar nuevamente las dos ramas, tendremos que dedicar unos segundos para saber qué tenemos que hacer con cada uno de los posibles conflictos que tengamos, y en ocasiones esto no es fácil. Recordemos que el término conflicto se utiliza (tanto en SVN como en cualquier otro software de control de versiones) para referirnos a un fichero que ha sido modificado simultáneamente por dos personas. Para intentar profundizar en el ejemplo, hemos creado esos seis ficheros por duplicado, una vez en el paquete ganatrunk y otra en el paquete ganabranch. Vamos a ello.



Creación del branch


Desde Eclipse podremos hacer todas las operaciones que vayamos a necesitar, y empezamos con el botón derecho sobre el nombre del proyecto, Team y Branch/Tag. Lo primero es indicar dónde queremos hacer la copia, y eso se lo tendremos que decir a mano. Con el botón Select... nos aparece la pantallita que vemos en la captura, abajo a la izquierda, y ahí escogemos la carpeta branches. Conviene añadir un nivel de subdirectorio más, ya que en branches, posiblemente queramos volver a crear más ramas en el futuro. Así que cuando escojamos la carpeta branches y le demos a aceptar, modificaremos manualmente la URL del campo Copy to URL: y le daremos un nombre de un nuevo directorio dentro de branches: yo le he dado el original nombre de branch01, así que la ruta de mi branch va a ser file:///svn/repo/HelloSVN/branches/branch01. La casilla Create any intermediate folders that are missing (crear todas las carpetas intermedias inexistentes) conviene marcarla también.

La siguiente ventana nos pide el número de revisión desde el que queremos abrir la vía alternativa. Esto depende de la complejidad y del estado del proyecto; para proyectos sencillos como el que nos ocupa, basta con decirle que lo haga desde la HEAD, es decir, desde la última versión del repositorio.
En la última ventana sólo nos pide el comentario para el repositorio: ya sabéis que las buenas prácticas recomiendan añadir siempre un comentario en cada commit que hagamos. Lo importante de esta ventana es la casilla que hay justo debajo del comentario, la que dice Switch working copy to new branch/tag. (conectar la copia local a la nueva rama/etiqueta). Si sois de los programadores que os toca trabajar en el branch recién creado, deberéis marcar esta casilla, si vais a seguir con el desarrollo de la rama principal trunk, no deberéis marcarla. En nuestro caso vamos a mezclar un poco las cosas: vamos a tener en el mismo workspace dos proyectos, uno apuntando al trunk y otro al branch. Este proyecto lo vamos a dejar apuntando al trunk, por lo que no marcamos la casilla. Botón de Finish y... ya tenemos la rama creada.

Visualizamos la rama


Ya tenemos la rama creada, lo que significa que en el repositorio tenemos dos proyectos, que podemos considerar totalmente independientes: el que hay en la carpeta trunk y el que está en branches/branch01. Vamos a abrirnos en el workspace otro proyecto pero apuntando a la rama. Queda claro que en una situación real, no debería haber un ordenador con los dos proyectos abiertos, ya que sería muy fácil editar el archivo del proyecto que no debes editar. Pero aquí lo vamos a hacer así, sólo con el motivo de poder ver el estado de los dos proyectos de un vistazo.

Así que nos vamos a File -> Import -> SVN -> Checkout Projects from SVN, buscamos la carpeta file:///svn/repo/HelloSVN/branches/branch01 y, para evitar confusiones con el proyecto anterior, vamos a llamar a éste HelloSVN_branch. Bueno, ya lo tenemos. Acabamos de abrir la rama, la via de desarrollo alternativa, y como debe ser al principio de la rama, actualmente los dos proyectos no se diferencian en nada. Si os fijáis en la imagen, tienen los dos los mismos archivos, la misma versión de los archivos (la 8), todo igual. En lo único que se diferencian es que uno está conectado a [HelloSVN/trunk] y el otro a [HelloSVN/branches/branch01].

Empezamos a modificar ficheros


Desde este momento, el equipo de programadores de la rama principal hará sus cambios en el proyecto trunk (el de arriba en la imagen) y el equipo de la rama secundaria lo hará en el proyecto branch (el de abajo). Como comentaba al principio del post, vamos a tener 6 tipos de posibles conflictos cuando unamos las dos ramas. Nos faltarían los ficheros que se añaden en una rama o en la otra, pero estos tienen una solución muy simple, por lo que nos olvidamos de ellos. Así que vamos a hacer las modificaciones oportunas en cada uno de ellos, borrando los que tengamos que borrar o modificando arriba o abajo, según sea el caso.

En la primera de las dos imágenes podéis ver los cambios que he hecho en el trunk: he borrado los 2 archivos FicheroParaBorrarEnPrincipal y he modificado FicheroParaModificarEnAmbas y FicheroParaModificarEnPrincipal, en los dos paquetes. Por otro lado he hecho algo parecido en el branch: he borrado FicheroParaBorrarEnRama y he modificado FicheroParaModificarEnAmbas y FicheroParaModificarEnRama, en ambos paquetes también. Y he hecho commit en ambos proyectos, por lo que ambos están sincronizados.

Dejamos para el último post el merge, es decir, la unión de las dos ramas.

sábado, 4 de septiembre de 2010

SubVersion, Eclipse y las ramas de desarrollo. (II) Subclipse y conexión a SVN


Como creo que ya he comentado en algún momento, estoy utilizando Eclipse Helios 3.6. Si estáis utilizando un Myeclipse o alguna otra versión de Eclipse, puede que no encontréis las cosas en el mismo lugar que pongo aquí, pero el modo de hacerlo suele ser bastante parecido. Empezamos por lo primero, instalamos Subclipse y nos conectamos a un repositorio.

Subclipse

Este es el nombre del plugin que nos permite interactuar con un repositorio Subversion desde dentro del Eclipse. Es muy recomendable poder acceder al repositorio sin tener que salir al explorador de Windows, ya que así podemos hacer un commit inmediatamente después de hacer cualquier cambio en cualquier fichero.

En el menú Help buscamos una opción Install New Software, y nos aparecerá una pantalla desde donde nos podemos bajar e instalar muchos de los plugins disponibles para Eclipse.Ponemos http://subclipse.tigris.org/update_1.6.x en el campo Work with y le damos al enter, y aparecerá lo que vemos en pantalla. Elegimos Subclipse y abajo el botón Next>.

En la siguiente pantalla nos aparece la lista de componentes que se van a instalar. No son todos necesarios,con instalar los que dice que son Required vale. Tras aceptar los términos de la licencia en la siguiente pantalla, pulsamos en Finish y dejamos que se instalen los componentes. Es posible que alguno de ellos no esté firmado, por lo que Eclipse nos pedirá confirmación de si queremos instalar un software sin firmar. Cosas de la seguridad. Una vez terminado el proceso, reiniciamos el Eclipse y listo.


Conexión al SVN

Como ya decíamos en el post anterior, vamos a suponer que disponemos de la URL del repositorio, un usuario y un password. Además suponemos que tenemos un proyecto Java ya creado en el Eclipse, en mi caso lo he llamado HelloSVN. Botón derecho sobre el proyecto, Team y Share Project; facilitamos la URL del repositorio, que suele ser una dirección a la que accederemos por http:// o por svn://. En mi caso file:///svn/repo, ya que estoy usando un repositorio alojado en la misma máquina. Si las carpetas no están creadas, podremos crearlas desde el Eclipse, en nuestro caso la dirección completa del proyecto va a ser file:///svn/repo/HelloSVN/trunk. Como es la primera conexión, la carpeta del repositorio está vacía, por lo que aprovechamos y hacemos un commit del estado actual del proyecto.

Ya tenemos todo preparado, en el siguiente post crearemos unos cuantos ficheros para poder ver cómo se comporta el Subversion cuando en cada una de las ramas se realizan diferentes acciones con un fichero.

lunes, 16 de agosto de 2010

SubVersion, Eclipse y las ramas de desarrollo. (I) Intro


Vamos a adentrarnos en ciertas complejidades del desarrollo de proyectos java que utilizan SubVersion como herramienta de control de versiones.La intención es ver cómo se gestionan las ramas (branches) en un proyecto de este tipo, y para ello vamos a crear un proyecto de ejemplo y una rama, haremos modificaciones en paralelo y acabaremos haciendo la fusión (merge)  de los cambios de la rama y del proyecto principal, que en la jerga SVN se denomina trunk.

SVN

Para los que no lo conozcáis, SubVersion (o SVN) es una herramienta de control de versiones, que gestiona los cambios en los ficheros de forma centralizada, lo que permite que haya diferentes usuarios (programadores en nuestro caso) realizando cambios sobre un proyecto, manteniendo el control de los archivos que han sido modificados por el resto de usuarios.

No quiero extenderme más en las características de SubVersion, por lo que a partir de aquí voy a suponer que tú, que me estás leyendo, tienes cierto conocimiento de la herramienta. En concreto, basta con tener los siguientes conceptos claros:

- Qué es un repositorio
- Qué es un checkout
- Qué es un commit
- Qué es un update

Si no entiendes bien estas cuatro cosas, creo que todavía estás bastante lejos de tener problemas con los branches, por lo que te recomiendo otras lecturas más ligeras :)

Repositorio

También voy a suponer que tienes acceso a un repositorio SVN para poder alojar el proyecto, las ramas, etc. La creación de un repositorio SVN en tu propio equipo es una tarea sencilla, sobre todo si te apoyas en herramientas denominadas clientes SVN, como por ejemplo TortoiseSVN, uno de los más utilizados y más simples para el entorno Windows. En entornos Linux el SVN se suele utilizar desde la línea de comando, lo que requiere cierta capacidad para memorizar las diferentes opciones de la herramienta, o tener el manual siempre cerca. Si me dan a elegir, me quedo con TortoiseSVN. Para no complicarnos más de lo necesario, dejamos para otro post la creación del repositorio, y suponemos que tenemos ya uno, es decir, disponemos de la URL del repositorio, un usuario y un password.

Branches

En proyectos de cierta envergadura se hace necesario el uso de ramas (branches) para permitir dos trayectorias de desarrollo paralelas. El ejemplo clásico es el de la aplicación que se encuentra en producción, en la que un equipo de programadores hace el mantenimiento correctivo mientras que otro equipo se encarga del desarrollo de la siguiente fase. Los mantenimientos deben realizarse a partir de la versión que se haya desplegado, y no deben verse afectados por las modificaciones realizadas por el desarrollo de la siguiente fase. Por otro lado, los desarrolladores de la siguiente fase deben poder realizar las modificaciones que consideren oportunas en un lugar distinto al que utilizan sus compañeros de mantenimiento para no afectar a la versión en producción, pero también deben tener la oportunidad de actualizar su copia de trabajo con las correcciones que realicen desde el mantenimiento.

Esto se soluciona con la creación de una rama (branch) que permite al equipo de mantenimiento seguir trabajando en el proyecto principal o trunk (también se le llama «rama principal») y a los desarrolladores de la siguiente fase en una ramificación del proyecto principal. A partir de aquí se podrían hacer varias ramas, ramas de ramas, etc, dependiendo de los requerimientos del proyecto. En este ejemplo no vamos a pasar de un caso simple en el que se pretende dejar claros los conceptos, con un proyecto principal y una rama, dejando para la cruda realidad las ramificaciones más complejas.

Estructura del repositorio

Como ya veremos más adelante, vamos a necesitar algún sitio en el repositorio para hacer esa segunda copia a la que vamos a llamar rama. En principio no hay nada establecido en cuanto a dónde hacerla o cómo gestionar las ramas; sin embargo hay una estructura que se ha convertido ya casi en un estándar, que es la siguiente:

  • repositorio:dir_raiz
    • Proyecto1
      • trunk
        • código...
      • branches
        • branch1
          • código...
        • ...
      • tags
    • Proyecto2
      • trunk
      • branches
      • tags 
    • ...

Es decir:
  • Del directorio raiz del repositorio cuelgan las carpetas, que se corresponden con los proyectos
  • En cada proyecto existen 3 carpetas
    • trunk, en donde se encuentra el código de la rama principal
    • branches es el directorio donde vamos a crear las ramas. Cada vez que creamos una rama, crearemos un directorio dentro de esta carpeta.
    • tags, lo pongo aquí para que nadie lo eche en falta, pero no lo vamos a utilizar para las ramas. Lo veremos en próximos posts.
Próximo paso

Vamos a empezar poco a poco. Lo primero, la instalación del SubClipse.

sábado, 14 de agosto de 2010

JAD y JadClipse, para los que nos gusta complicarnos la vida


Si todavía no conoces JAD, te estás perdiendo una de las formas más brutales de aprender Java. JAD es el acrónimo de JAva Decompiler, una utilidad que permite decompilar cualquier archivo java previamente compilado (los *.class). JAD es realmente útil en algunas ocasiones, pero no es muy "user-friendly" ya que se maneja por línea de comando, y eso no es muy práctico. La buena noticia se llama JadClipse, el plugin para Eclipse que permite entrar en el código fuente de las clases de librerías de las que no dispongamos de su código fuente. Para poder ver el código de esas clases desde Eclipse necesitamos las dos utilidades, JAD y JadClipse. Empezemos por JAD.

JAD

Encontrar esta utilidad ha sido complicado en algunos momentos, ya que la última versión tiene fecha de 2001. Hace algún tiempo el autor tenía una página personal desde la que podías descargarlo, pero aquello desapareció. En el momento de escribir este artículo se puede descargar del siguiente enlace:


Si quieres una versión anterior o para una plataforma que no sea Windows, visita esta página y encontrarás lo que buscas.

Como ya habrás visto, el enlace descarga un archivo ZIP, y al abrirlo encontramos únicamente dos archivos: un "readme.txt" y el jad.exe, el que andamos buscando. Si quieres conocer un poco de la historia del JAD o te interesa utilizarlo desde línea de comandos, puedes abrir el readme.txt y empaparte de eso, pero si buscas ejecutarlo desde el Eclipse, sólo tienes que copiar el jad.exe en algún directorio que esté en el path del equipo. Yo suelo copiarlo en C:\WINDOWS\SYSTEM32, y me olvido de él.

JadClipse

Ya tenemos el JAD, pero lo que queremos es utilizarlo desde el Eclipse. Y para eso está JadClipse, un proyecto Open Source (CPL) alojado en sourceforge.net. Disponen de una wiki de visita aconsejada, aunque el enlace más utilizado actualmente (agosto de 2010) es el JadClipse para las versiones de Eclipse >= 3.3M6. Yo lo he instalado en un Eclipse 3.6 (Helios) sin problema.

El enlace descarga un archivo jar, que tendremos que copiar en la carpeta de plugins del Eclipse (la subcarpeta plugins del directorio en donde instalaste Eclipse). Tras esto, cerramos el Eclipse si lo teníamos abierto, y la próxima vez que lo arranquemos ya tendremos el JadClipse listo para utilizar.

Si no funciona

La instalación debería ser tan sencilla como esto, pero si no funciona, puedes verificar algunas cosas:
  • Si la instalación ha ido bien, deberías tener una página de configuración del JadClipse en las opciones de Eclipse (Window -> Preferences -> Java -> JadClipse). Si esa página no está ahí, verifica que copiaste el archivo jar (en mi caso se llama net.sf.jadclipse_3.3.0.jar) en el directorio correcto ("directorio de instalación del eclipse"\plugins)
  • Si existe la página de configuración pero no te decompila los archivos class, verifica que éstos están asociados con el JadClipse. Busca en la página de asociaciones de archivos en las opciones del Eclipse (Window -> Preferences -> General -> Editors -> File Associations), y mira que los archivos *.class tengan como editor por defecto al "JadClipse Class File Viewer".
  • Si esto también está correcto, sólo queda por probar que el JadClipse encuentra al JAD. En la página de configuración del JadClipse (Window -> Preferences -> Java -> JadClipse), en la caja "Path to decompiler" debe poner la ruta al archivo jad.exe. Si lo copiaste en C:\WINDOWS\SYSTEM32, bastaría con que en esa cajita pusiese "jad". Si lo copiaste en otro sitio, por ejemplo en C:\Utilidades, escribe en esa cajita C:\Utilidades\jad.exe.
¡Que lo disfrutes!





martes, 8 de junio de 2010

Estructura de un WAR. Web Applications y Web Archives


¿Qué es un WAR?

WAR es el acrónimo de Web ARchive. Es una especificación que nos dice cómo hay que empaquetar una Aplicación Web para que pueda ser ejecutada por los servidores de aplicaciones. Y una Aplicación Web es el conjunto de los recursos que son necesarios para que el servidor de aplicaciones haga lo que queremos que haga. En esta colección se incluyen las páginas HTML, JSP, imágenes, clases java, librerías, applets... todo lo que necesita nuestra aplicación.

Estructura del WAR

Para que una Aplicación Web sea portable, necesitamos como mínimo que los servidores que la ejecuten encuentren todo lo necesario para que funcione, y esto sólo lo podemos conseguir si todos los servidores buscan las cosas en el mismo sitio. Hay cuatro tipos de archivos que los servidores van a buscar:
- Clases java
- Librerías
- Recursos html
- Un archivo especial, el descriptor del despliegue (Deployment Descriptor) de la aplicación

Cada uno de estos tipos de archivo tiene su sitio en el archivo WAR:
/WEB-INF/classes contiene las clases java
/WEB-INF/lib contiene las librerías java
/WEB-INF/web.xml es el descriptor de despliegue
...y el resto de recursos (html, jsp, imágenes, etrc) se ubican en el raíz. No hay una estructura definida para estos archivos. Podemos ubicar estos archivos como queramos, aunque un poco de organización no viene mal. Pero esto entra en el terreno de las buenas prácticas más que en el de la especificación de los archivos WAR. Como curiosidad, el class loader de la aplicación debería devolver un NOT FOUND cuando intentemos buscar un recurso web en el directorio WEB-INF.

En la próxima entrada veremos el deployment descriptor (web.xml) con más detalle.



jueves, 3 de junio de 2010

Instalar Java


Lo primero que necesitamos es poner a punto la máquina. Y si vamos a utilizar Struts o Spring, tenemos que comenzar instalando el SDK de Java. Muchos de los que os hayáis acercado hasta aquí pensaréis que esta entrada no es necesaria, ya que para utilizar Struts o Spring son necesarios unos conocimentos básicos de la plataforma Java, y no os falta razón. Pero quiero empezar desde el principio, así que ahí va la instalación de Java, aunque estoy seguro que este post será uno de los menos leídos del blog.

Nos bajamos el JDK de la página de SUN, si solo fuéramos a ejecutar aplicaciones Java nos bastaría con el entorno de ejecución (Java Runtime Environment, JRE), pero como vamos a querer desarrollar necesitamos el Kit de Desarrollo (Java Development Kit, JDK), en el que viene incluido también el JRE. Si tenemos especificaciones de versión del JDK, tendremos que buscar esa versión en la página de Sun. Aunque la estructura de la web de Sun puede cambiar, actualmente las versiones anteriores están en http://java.sun.com/javase/downloads/previous.jsp. Y si no tenemos especificaciones, con la última versión de la JDK deberia bastarnos. El JDK actual es el «JDK 6 update 20», y el enlace a la página de descarga, http://java.sun.com/javase/downloads/widget/jdk6.jsp. Nos pide un usuario y un password, pero podemos evitarlo pinchando en «Skip this step».

La instalación es sencilla, sólo debemos ir dando al next - next - next para completarla, y una vez terminada ya tenemos listo nuestro equipo para ejecutar programas java. No hay cambios visibles en el equipo, apenas un icono más en el Panel de Control y . Lo que sí podremos necesitar es la ubicación de la instalación, que por defecto es, para el JDK 1.6.0 update 20:

C:\Archivos de Programa\Java\jdk1.6.0_20

Y para el JRE 6:

C:\Archivos de Programa\Java\jre6

Ya estamos listos para instalar más cosas...

lunes, 31 de mayo de 2010

Bienvenid@s


Hola a tod@s, ¡Bienvenid@s! En esta primera entrada no vamos a hablar de nada técnico, sólo quiero agradeceros que hayáis venido a este humilde blog, en el que pretendo ir almacenando las soluciones que encuentro a problemas simples (y no tan simples) como desarrollador en Java. Este blog va a ser muy práctico, se intentará hablar lo justo de la teoría ya que de eso se han escrito ya miles de páginas en la web, así que vamos a ir a ver siempre cómo se hacen las cosas directamente, sin rodeos. Vamos a empezar con una configuración básica, y con el problema más básico, cómo instalar java. Posteriormente iremos haciendo cosas cada vez más complicadas. El objetivo final es hablar de dos de los frameworks más utilizados en este mundo, Spring y Struts, pero antes de eso vamos a ir configurando el equipo con todo lo necesario, y en el camino iremos solucionando ya algún problema que otro...

Sin más rodeos, empezamos a dar Respuestas Java.
:)