<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Diario de Programación &#187; maven</title>
	<atom:link href="http://blog.chuidiang.com/tag/maven/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.chuidiang.com</link>
	<description>Programación e informática en general</description>
	<lastBuildDate>Wed, 25 Jan 2012 23:17:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Jugando con Proguard</title>
		<link>http://blog.chuidiang.com/2010/10/20/jugando-con-proguard/</link>
		<comments>http://blog.chuidiang.com/2010/10/20/jugando-con-proguard/#comments</comments>
		<pubDate>Wed, 20 Oct 2010 13:06:19 +0000</pubDate>
		<dc:creator>Chuidiang</dc:creator>
				<category><![CDATA[Herramientas]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[proguard]]></category>

		<guid isPermaLink="false">http://blog.chuidiang.com/?p=852</guid>
		<description><![CDATA[&#160;Estos d&#237;as estoy jugando con Proguard, una herramienta que coge nuestro jar en java y realiza b&#225;sicamente tres tareas: ofuscarlo, optimizarlo y eliminar sobrantes. Por supuesto, estas tareas son independientes y podemos realizar unas s&#237; y otras no a nuestro gusto. Tiene plugin para maven, por lo que si usamos maven, podemos realizar cualquiera de [...]]]></description>
			<content:encoded><![CDATA[<p><img alt="Candado de c&oacute;digo ofuscado" width="400" height="413" vspace="10" hspace="10" align="right" src="http://www.elgrantlapalero.com/catalogo/images/pt_110.jpeg" />&nbsp;Estos d&iacute;as estoy jugando con <a href="http://proguard.sourceforge.net/">Proguard</a>, una herramienta que coge nuestro jar en java y realiza b&aacute;sicamente tres tareas: ofuscarlo, optimizarlo y eliminar sobrantes. Por supuesto, estas tareas son independientes y podemos realizar unas s&iacute; y otras no a nuestro gusto. Tiene <a href="http://pyx4me.com/pyx4me-maven-plugins/proguard-maven-plugin/">plugin para maven</a>, por lo que si usamos maven, podemos realizar cualquiera de estas tres tareas autom&aacute;ticamente al generar nuestro jar.</p>
<p><strong>Ofuscado</strong></p>
<p>La parte de ofuscado es sencilla, s&iacute;mplemente coge los paquetes, las clases y los m&eacute;todos y les cambia el nombre por a, b, c, etc. As&iacute;, en vez de persona.setId(7), si descompilamos ver&iacute;amos a.b(7). Es decir, se puede seguir descompilando pero el c&oacute;digo es mucho menos claro.</p>
<p>Tiene opciones para decirle qu&eacute; clases o m&eacute;todos no debe ofuscar. Son candidatos claros a no ofuscar el m&eacute;todo main() de la clase principal e incluso el nombre de esa clase, para que luego la m&aacute;quina virtual java sepa qu&eacute; debe ejecutar. Los m&eacute;todos write() y read(9 de serializaci&oacute;n, etc. Tambi&eacute;n, en el caso de que estemos intentando ofuscar una librer&iacute;a, se deben no ofuscar las clases que se usen desde el programa principal.</p>
<p>Curiosamente, proguard es bastante inteligente y tiene en cuenta la relexi&oacute;n de java. Si ve que usamos cosas como Class.forname(), o Class.getDeclaredMethod()&#8230;., nos avisa con un error si intentamos ofuscar las clases a las que hace referencia esa reflexi&oacute;n.</p>
<p><strong>Optimizado</strong></p>
<p>Con esto no me he metido a fondo, porque no hay muchas posibilidades de ver qu&eacute; es lo que hace. Entiendo que limpia nuestro c&oacute;digo ineficiente, borrando variables locales no usadas o arreglando cualquier cosa que tenga que ver con la efectividad de nuestro c&oacute;digo.</p>
<p><strong>Eliminar sobrantes</strong></p>
<p>Esta es la funcionalidad que no esperaba de la herramienta y que m&aacute;s me ha llamado la atenci&oacute;n. Elimina de nuestro jar todas las clases que no usamos y borra todos los m&eacute;todos que no se usan en el resto de clases. &iquest;Y c&oacute;mo sabe si lo usamos o no?. Pues por la clase que le hemos dicho que contiene el main(). Empieza a tirar de ah&iacute; y borra todo lo que no se use. El resultado es que en muchas ocasiones obtendremos un jar mucho m&aacute;s peque&ntilde;o si llevamos tiempo trabajando en el proyecto y somos reacios a borrar clases y m&eacute;todos que no se usan &quot;por si acaso me hacen falta m&aacute;s adelante&quot;.</p>
<p>Y ya lo m&aacute;ximo, al integralo en maven, el proceso queda totalmente autom&aacute;tico, por lo que una vez configurado en nuestro pom.xml, podemos olvidarnos de que usamos esa herramienta y seguir con nuestros comandos de maven t&iacute;pico mvn package, mvn install, mvn deploy, etc. Eso s&iacute;, ojo al hacer el javadoc.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chuidiang.com/2010/10/20/jugando-con-proguard/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>jax-ws y maven</title>
		<link>http://blog.chuidiang.com/2010/09/29/jax-ws-y-maven/</link>
		<comments>http://blog.chuidiang.com/2010/09/29/jax-ws-y-maven/#comments</comments>
		<pubDate>Wed, 29 Sep 2010 12:17:33 +0000</pubDate>
		<dc:creator>Chuidiang</dc:creator>
				<category><![CDATA[Herramientas]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[axis2]]></category>
		<category><![CDATA[jax-ws]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://blog.chuidiang.com/?p=847</guid>
		<description><![CDATA[&#160;Siguiendo con los web services y yo, he estado probando herramientas como axis2 y jax-ws. Por supuesto, nada me ha funcionado a la primera y llevo casi dos d&#237;as pele&#225;ndome con esto para arrancar un &#34;hola mundo&#34; Con axis2 el problema es que se me ocurri&#243; hacerme mi propia clase de ejemplo, sin copiar la [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;Siguiendo con los web services y yo, he estado probando herramientas como <a href="http://ws.apache.org/axis2/">axis2</a> y <a href="https://jax-ws.dev.java.net/">jax-ws</a>. Por supuesto, nada me ha funcionado a la primera y llevo casi dos d&iacute;as pele&aacute;ndome con esto para arrancar un &quot;hola mundo&quot;</p>
<p>Con axis2 el problema es que se me ocurri&oacute; hacerme mi propia clase de ejemplo, sin copiar la de los tutoriales. Al final descubro que no soporta enumerados de java y qu&eacute; casualidad, a m&iacute; se me hab&iacute;a ocurrido poner uno de los m&eacute;todos con un par&aacute;metro enumerado. Una vez conseguido arrancar un servidor y hacerme un cliente, el servidor me da error cuando intento acceder al web service desde el ciente. Ante las pocas pistas que daba el error, decid&iacute; dejar axis-2 de momento y probar con jax-ws.</p>
<p>Con jax-ws me cree un proyecto maven y me puse a ello. Pues bien, las dependencias maven te&oacute;ricas seg&uacute;n la documentaci&oacute;n son estas&nbsp;<a href="https://jax-ws.dev.java.net/guide/Using_JAX_WS_from_Maven.html">https://jax-ws.dev.java.net/guide/Using_JAX_WS_from_Maven.html</a>&nbsp;. Creo el proyecto, arranco el servidor y todo aparentemente correcto. Accedo desde un navegador a http://localhost:8080/MiServicio?WDSL con el que te&oacute;ricamente deber&iacute;a obtener el fichero WSDL del servicio&#8230; y el servidor da error. Buscando el error por google, me encuentro con esto&nbsp;<a href="http://forums.java.net/jive/message.jspa?messageID=222799">http://forums.java.net/jive/message.jspa?messageID=222799</a>&nbsp;Parece que la librer&iacute;a sjsxp de la que depende seg&uacute;n maven el jax-ws no es correcta y hay que coger la versi&oacute;n 1.0.1 en vez de la 1.0. As&iacute; que me toca &quot;tunear&quot; el pom.xml y hacer esta &ntilde;apa</p>
<blockquote>
<p>&nbsp;</p>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>&lt;dependency&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>&lt;groupId&gt;com.sun.xml.ws&lt;/groupId&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>&lt;artifactId&gt;jaxws-rt&lt;/artifactId&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>&lt;version&gt;2.1.1&lt;/version&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>&lt;exclusions&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">				</span>&lt;exclusion&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">					</span>&lt;groupId&gt;com.sun.xml.stream&lt;/groupId&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">					</span>&lt;artifactId&gt;sjsxp&lt;/artifactId&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">				</span>&lt;/exclusion&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>&lt;/exclusions&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>&lt;/dependency&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>&lt;dependency&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>&lt;groupId&gt;com.sun.xml.stream&lt;/groupId&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>&lt;artifactId&gt;sjsxp&lt;/artifactId&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">			</span>&lt;version&gt;1.0.1&lt;/version&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">		</span>&lt;/dependency&gt;</div>
</blockquote>
<div>Dicho de otra forma, poner la dependencia de jaxws-rt, decirle que no me traiga su sjsxp y luego poner la dependencia del que yo quiero. Esto ha funcionado bien y ya tengo el servidor arrancado. Ahora toca pelearse con el cliente&#8230;. espero no tener demasiados problemas. Luego volver&eacute; con axis2.</div>
<div>&nbsp;</div>
<div>Y aunque todav&iacute;a tengo que probar m&aacute;s, de momento me gusta mucho m&aacute;s jax-ws que axis2. Los scripts de axis2 generan montones de clases que luego tampoco facilitan tanto la creaci&oacute;n de un cliente. jax-ws tambi&eacute;n genera clases, pero parece que son menos y adem&aacute;s quedan &quot;ocultas&quot;, ya que genera los .class que luego se empaquetan en el war o jar.</div>
<div>&nbsp;</div>
<div>Lo segundo que no me ha gustado de axis2 es que aparentemente no tiene posibilidad de hacer un main() que arranque un servidor web con los webservices, dependemos de un Tomcat ajeno con una webapp axis2 instalada sobre la que desplegamos nuestros web services. Bueno, s&iacute; tiene un servidor, pero seg&uacute;n la documentaci&oacute;n puede usarse sin garant&iacute;as, ya que no est&aacute; soportado. jax-ws permite hacerse un main y publicar el servicio de una forma tan f&aacute;cil como esta</div>
<blockquote>
<div>public static void main(String [] args) {<br />
&nbsp;&nbsp; Endpoint.publish(&quot;http//localhost:8080/MiServicio&quot;, new MiWebService());<br />
&nbsp;&nbsp; // Aqui puedes seguir haciendo cosas.<br />
}</div>
</blockquote>
<div>Bueno, no es nada grave si quieres publicar webservices en internet. Pero en mi caso, necesito que el servidor aparte de publicar los webservices, haga m&aacute;s cosas.</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.chuidiang.com/2010/09/29/jax-ws-y-maven/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Pros y contras de maven</title>
		<link>http://blog.chuidiang.com/2010/06/19/pros-y-contras-de-maven/</link>
		<comments>http://blog.chuidiang.com/2010/06/19/pros-y-contras-de-maven/#comments</comments>
		<pubDate>Sat, 19 Jun 2010 17:31:53 +0000</pubDate>
		<dc:creator>Chuidiang</dc:creator>
				<category><![CDATA[maven]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.chuidiang.com/?p=810</guid>
		<description><![CDATA[&#160;Llevamos ya varios a&#241;os usando maven y nos hemos acostumbrado a &#233;l. Recordamos ahora c&#243;mo ten&#237;amos antes los proyectos y nos asombramos de la mejora conseguida. Sin embargo, no todo es bueno con maven, tiene sus pegas. Ventajas de maven Hay principalmente tres grandes cosas que hemos conseguido con maven y sin las que ahora [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;Llevamos ya varios a&ntilde;os usando maven y nos hemos acostumbrado a &eacute;l. Recordamos ahora c&oacute;mo ten&iacute;amos antes los proyectos y nos asombramos de la mejora conseguida. Sin embargo, no todo es bueno con maven, tiene sus pegas.</p>
<h2>Ventajas de maven</h2>
<p>Hay principalmente tres grandes cosas que hemos conseguido con <a href="http://maven.apache.org/">maven</a> y sin las que ahora no ser&iacute;amos capaces de trabajar.</p>
<p>La primera es que ahora todos nuestros proyectos est&aacute;n organizados igual. Esto, por supuesto, puede conseguirse con disciplina y sin necesidad de maven, pero en grupos numerosos de desarrolladores es m&aacute;s f&aacute;cil de conseguir si la herramienta te obliga a seguir una estructura o al menos, si te obliga a hacer un esfuerzo importante si te quieres salir de esa estructura. Se acab&oacute; el &nbsp;hacer scripts de compilado, el preguntar a otro cuando cambias de proyecto d&oacute;nde est&aacute;n las cosas, el dejar ficheros o iconos por cualquier lado. Ahora cualquiera puede pasar de un proyecto a otro y sabe manejarse por la estructura sin ning&uacute;n problema.</p>
<p>La segunda gran ventaja son los jar. Al dejar todos los jar de los proyectos en un repositorio centralizado (usamos <a href="http://nexus.sonatype.org/">nexus</a>) y usar versiones SNAPSHOT de maven, todos tenemos siempre disponibles los &uacute;ltimos jars. Antes era necesario que cada uno compilase los jar que &nbsp;necesitara o se los pidiera a alguien que los tuviera, o que alguien se acordara de meterlos en el sistema de control de versiones. Eso ya no es necesario, maven/nexus se encarga de que todos tengamos siempre los &uacute;ltimos jars.</p>
<p>Y la tercera gran ventaja es la herramienta de integraci&oacute;n continua (<a href="https://hudson.dev.java.net/">Hudson</a>), que todas las noches saca los fuentes del sistema de control de versiones, los compila y pone los jars en nexus. Al ser hudson el encargado de meter los jar en nexus, estos siempre est&aacute;n actualizados y siempre est&aacute; disponible la &uacute;ltima versi&oacute;n para todo el mundo. Y al ser hudson el que compila en un servidor separado, eliminamos por un lado los t&iacute;picos errores de c&oacute;digo que s&oacute;lo compila en el PC del desarrollador Fulanito porque inadvertidamente ha puesto un path suyo local en alg&uacute;n sitio, o se ha olvidado de meter algo en el sistema de control de versiones. Este Hudson nos sirve adem&aacute;s para obtener de &eacute;l las versiones de instalaci&oacute;n tanto para el entorno de producci&oacute;n como para pruebas. Ya no dependemos de que alguien tenga todo lo necesario para generar estas versiones y de que ese alguien est&eacute;.</p>
<h2>Pegas con maven</h2>
<p>Pero no todo son ventajas. La gran y enorme pega de maven es su dependencia de que haya internet o al menos red, para acceder al servidor de Hudson. Los problemas con la red suelen ser relativamente frecuentes: se va el servidor de nexus por el motivo que sea, se cae alg&uacute;n proxy o router, etc, etc. En esos casos, se nos queda un poco parado el tema de compilado. S&iacute;, maven tiene una ejecuci&oacute;n off-line, pero no funciona todo lo bien que debiera. Si le falta algo, se empe&ntilde;a en ir a buscarlo a trav&eacute;s de la red.</p>
<p>Y esta dependencia de la red se nos hace especialmente grave cuando vamos a instalaciones del cliente en los que no hay internet ni, por supuesto, acceso a nuestro nexus. Si queremos llevarnos un entorno de desarrollo para depurar, corregir alg&uacute;n bug y compilar en las instalaciones del cliente, nos obliga a llevarnos toda una copia de repositorios, o montar el proyecto de forma totalmente independiente de maven. Hay comandos de maven que ayudan a hacer toda esta copia, como <a href="http://maven.apache.org/plugins/maven-dependency-plugin/go-offline-mojo.html">dependency:go-offline</a>, pero hay que acordarse de hacerlo.</p>
<p>Es bastante molesto tambi&eacute;n el tema de plugins de maven. A veces y sin saber el motivo, maven decide que debe actualizar plugins a versiones m&aacute;s modernas. En la mayor&iacute;a de los casos esto no afecta demasiado, pero a veces si coincide con alg&uacute;n tipo de problema de red o el estar off-line, nos hace imposible compilar.</p>
<p>En fin, desde luego las ventajas compensan con creces los inconvenientes y ni se nos pasa por la cabeza dejar de usar maven, pero a veces algunos problemas misteriosos pueden tenerte de pelea con ellos toda una ma&ntilde;ana.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chuidiang.com/2010/06/19/pros-y-contras-de-maven/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Subiendo &#8220;extraños&#8221; al repositorio de maven</title>
		<link>http://blog.chuidiang.com/2010/03/11/subiendo-extranos-al-repositorio-de-maven/</link>
		<comments>http://blog.chuidiang.com/2010/03/11/subiendo-extranos-al-repositorio-de-maven/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 14:42:27 +0000</pubDate>
		<dc:creator>Chuidiang</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[dependency]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[packaging]]></category>

		<guid isPermaLink="false">http://blog.chuidiang.com/?p=730</guid>
		<description><![CDATA[&#160;Cuando usamos maven entre varios desarrolladores en proyectos m&#225;s o menos grandes, es normal que montemos un repositorio de jars, estilo nexus o archiva. Cuando ejecutamos el comando mvn deploy, maven sube nuestro jar reci&#233;n compilado a este repositorio y lo hace accesible para los dem&#225;s desarrolladores. Sin embargo, es posible subir a este tipo [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;Cuando usamos <a href="http://maven.apache.org/index.html">maven</a> entre varios desarrolladores en proyectos m&aacute;s o menos grandes, es normal que montemos un repositorio de jars, estilo <a href="http://nexus.sonatype.org/">nexus</a> o <a href="http://archiva.apache.org/">archiva</a>. Cuando ejecutamos el comando <em>mvn deploy</em>, maven sube nuestro jar reci&eacute;n compilado a este repositorio y lo hace accesible para los dem&aacute;s desarrolladores.</p>
<p>Sin embargo, es posible subir a este tipo de repositorios ficheros que no sean .jar, podemos subir cualquier tipo de fichero. El comando <em>mvn deploy:deploy-file</em> con los par&aacute;metros adecuados, nos permite subir un fichero cualquiera.</p>
<p>&iquest;Para qu&eacute; queremos subir ficheros que no sean .jar?. Sup&oacute;n que como parte de nuestro proyecto java usamos <a href="http://java.sun.com/docs/books/jni/">JNI</a> con una librer&iacute;a .dll cuyos fuentes en C/C++ tambi&eacute;n desarrollamos nosotros. No parece una buena forma de compartir la .dll reci&eacute;n generada meti&eacute;ndola en nuestro <a href="http://es.wikipedia.org/wiki/Control_de_versiones">sistema de control de versiones</a>. Aunque podr&iacute;amos hacerlo as&iacute;, es m&aacute;s elegante usar el sistema de control de versiones para ficheros fuente o de texto que generemos a mano y no usarlo para los &quot;artefactos&quot; que construye nuestro proyecto, como ejecutables, librer&iacute;as, etc. La soluci&oacute;n entonces consiste en subir esa .dll reci&eacute;n generada al repositorio de jars, aunque no sea un jar. El comando puede parecerse a esto (no pongo todos los par&aacute;metros, que ser&iacute;a muy largo)</p>
<blockquote>
<p>mvn deploy:deploy-file -DgroupId=&#8230; -DartifactId=libreria -Dversion=1.0 <strong>-Dpackaging=dll</strong> -Dfile=libreria.dll -Durl=&#8230;.</p>
</blockquote>
<p>Y esto subir&iacute;a la .dll al repositorio de jars. La parte interesante de este asunto est&aacute; en el <em>-Dpackaging=dll</em>. Esto hace que maven ponga al fichero la extensi&oacute;n .dll para subirlo y lo subir&aacute; con el nombre <em>libreria-1.0.dll</em>, independientemente del nombre que tenga la .dll antes de subirla.</p>
<p>Y ahora viene otra parte interesante. En nuestro proyecto java podemos poner, en el pom.xml, la dependencia en runtime de esa librer&iacute;a que acabamos de subir</p>
<blockquote>
<p>&lt;dependency&gt;<br />
&nbsp;&nbsp; &lt;groupId&gt;&#8230;&lt;/groupId&gt;<br />
&nbsp;&nbsp; &lt;artifactId&gt;libreria&lt;/artifactId&gt;<br />
&nbsp;&nbsp; &lt;version&gt;1.0&lt;/version&gt;<br />
&nbsp;&nbsp; &lt;type&gt;dll&lt;/type&gt;<br />
&nbsp;&nbsp; &lt;scope&gt;runtime&lt;/scope&gt;<br />
&lt;/dependency&gt;</p>
</blockquote>
<p>Aqu&iacute;, nuevamente, la gracia est&aacute; en poner <em>&lt;type&gt;dll&lt;/type&gt;</em>, ya que esto hace saber a maven y al repositorio de jars que en realidad estamos buscando un fichero .dll, que hab&iacute;amos subido previamente con <em>-Dpackaging=dll</em></p>
<p>Por supuesto, la ejecuci&oacute;n del comando&nbsp;<em>mvn deploy:deploy-file</em> podemos a&ntilde;adirla al proceso de compilado de nuestros fuentes C/C++ y podemos poner version 1.0-SNAPSHOT, de forma que se suban versiones de desarrollo nuevas cada vez que se compile y que el resto de desarrolladores puedan disponer de ellas.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chuidiang.com/2010/03/11/subiendo-extranos-al-repositorio-de-maven/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rangos de dependencias con maven</title>
		<link>http://blog.chuidiang.com/2010/03/04/rangos-de-dependencias-con-maven/</link>
		<comments>http://blog.chuidiang.com/2010/03/04/rangos-de-dependencias-con-maven/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 19:33:59 +0000</pubDate>
		<dc:creator>Chuidiang</dc:creator>
				<category><![CDATA[maven]]></category>
		<category><![CDATA[dependencias]]></category>
		<category><![CDATA[versiones]]></category>

		<guid isPermaLink="false">http://blog.chuidiang.com/?p=722</guid>
		<description><![CDATA[&#160;En maven todos estamos acostumbrados a poner las dependencias y en concreto, a poner la versi&#243;n concreta que queremos de la dependencia. Por ejemplo, si nuestro proyecto depende de log4j, solemos poner algo como esto &#60;dependency&#62; &#160;&#160; &#60;groupId&#62;log4j&#60;/groupId&#62; &#160;&#160; &#60;artifactId&#62;log4j&#60;/artifactId&#62; &#160;&#160; &#60;version&#62;1.2.13&#60;/version&#62; &#60;/dependency&#62; es decir, ponemos la versi&#243;n concreta que deseamos de log4j, en esta [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;En <a href="http://maven.apache.org/">maven</a> todos estamos acostumbrados a poner las dependencias y en concreto, a poner la versi&oacute;n concreta que queremos de la dependencia. Por ejemplo, si nuestro proyecto depende de <a href="http://logging.apache.org/log4j/">log4j</a>, solemos poner algo como esto</p>
<blockquote>
<p>&lt;dependency&gt;<br />
&nbsp;&nbsp; &lt;groupId&gt;log4j&lt;/groupId&gt;<br />
&nbsp;&nbsp; &lt;artifactId&gt;log4j&lt;/artifactId&gt;<br />
&nbsp;&nbsp; &lt;version&gt;1.2.13&lt;/version&gt;<br />
&lt;/dependency&gt;</p>
</blockquote>
<p>es decir, ponemos la versi&oacute;n concreta que deseamos de log4j, en esta caso, la 1.2.13</p>
<p>Pues bien, es menos conocido, quiz&aacute;s porque la documentaci&oacute;n de maven es algo escasa, pero <a href="http://docs.codehaus.org/display/MAVEN/Dependency+Mediation+and+Conflict+Resolution">podemos indicar a maven un rango de dependencias</a>, de forma que maven traer&aacute; la m&aacute;s moderna disponible. Para ello se utiliza la notaci&oacute;n matem&aacute;tica para rangos de valores, donde se abre par&eacute;ntesis o corchete, se pone el n&uacute;mero de versi&oacute;n inicial, coma, el n&uacute;mero de versi&oacute;n final y se cierra par&eacute;ntesis o corchete. Un corchete indica que la versi&oacute;n inicial o final es v&aacute;lida, mientras que un par&eacute;ntesis indica que no es v&aacute;lida. Dejar en blanco uno de los n&uacute;meros de versi&oacute;n indica que no hay l&iacute;mite por ese lado. As&iacute;, por ejemplo</p>
<blockquote>
<p>[1.2, 1.5) &nbsp; &nbsp; Cualquier versi&oacute;n entre la 1.2 y la 1.5, incluyendo la 1.2 (corchete al principio), pero excluyendo la 1.5 (par&eacute;ntesis al final)</p>
<p>[1.3, ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Versi&oacute;n 1.3 o superior, incluyendo la 1.3</p>
<p>[1.0, 2.0) &nbsp; &nbsp; Cualquier versi&oacute;n 1.x.x, pero inferior a la 2.0</p>
</blockquote>
<p>En realidad maven admite hasta tres n&uacute;meros en la versi&oacute;n m&aacute;s un &quot;cualificador&quot;. El cualificador es un nombre cualquiera que se pone detr&aacute;s del n&uacute;mero de versi&oacute;n separado por un gui&oacute;n. Por ejemplo, imagina que en nuestro proyecto entregamos una versi&oacute;n al cliente FEDERICO y creamos una versi&oacute;n congelada para ese cliente. Su n&uacute;mero de versi&oacute;n podr&iacute;a ser 1.2.3-FEDERICO. O m&aacute;s com&uacute;n, si es una &quot;Release Candidate&quot;, le ponemos 1.2.3-rc, o si es una beta, pues 1.2.3-beta.</p>
<p>No lo he probado, pero imagino que esto permite poner cosas como</p>
<blockquote>
<p>[1.2, )-FEDERICO</p>
</blockquote>
<p>de forma que maven traer&aacute; cualquier versi&oacute;n 1.2 o superior que tenga el cualificador FEDERICO, es decir, que sea del cliente FEDERICO.</p>
<p>Considero esto realmente interesante, porque en un proyecto grande en el que hay muchos jar desarrollados por la gente de nuestro equipo y en los que cada jar tiene sus responsables, cada responsable puede subir su n&uacute;mero de versi&oacute;n cuando lo considere adecuado y los dem&aacute;s traer&aacute;n autom&aacute;ticamente o no esa versi&oacute;n seg&uacute;n lo que pongan en las dependencias. Si yo no quiero traerme los cambios que haga Juan en su jar, s&iacute;mplemente pongo que quiero la versi&oacute;n 1.4. Pero si me interesa traerme siempre su versi&oacute;n m&aacute;s moderna, entonces pongo [1.0, ).</p>
<p>Aunque supongo que es bastante conocido, aprovecho para poner aqu&iacute; cual es el significado de esos tres n&uacute;meros de versi&oacute;n. Si la versi&oacute;n es a.b.c, los n&uacute;meros se incrementan normalmente siguiendo los siguientes criterios:</p>
<ul>
<li>a se suele incrementar cuando el cambio es tan importante que hace la nueva versi&oacute;n incompatible con las anteriores. Si guardas datos con una versi&oacute;n 2.0 de un programa, posiblemente no puedas leer esos datos con la versi&oacute;n 1.0 del mismo programa (normalmente al rev&eacute;s si suele ser posible).</li>
<li>b se suele cambiar cuando no hay p&eacute;rdida de compatibilidad, pero s&iacute; se han a&ntilde;adido nuevas funcionalidades. Por ejemplo, las versiones 1.3 y 1.4 pueden usar los mismos datos guardados indistintamente, pero la 1.4 permite imprimirlos mientras que la 1.3 no.</li>
<li>c se suele cambiar cuando se han arreglado errores respecto a la anterior. Por ejemplo, la 1.2.3 puede caerse cuando el usuario pulsa el bot&oacute;n A, luego minimiza la ventana y le da a la tecla de tabulador. La 1.2.4 ya no tiene ese error.</li>
</ul>
<p>Por supuesto, esto es una convenci&oacute;n m&aacute;s o menos aceptada, pero desde luego no es obligatoria.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chuidiang.com/2010/03/04/rangos-de-dependencias-con-maven/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>javadoc con UML</title>
		<link>http://blog.chuidiang.com/2010/03/03/javadoc-con-uml/</link>
		<comments>http://blog.chuidiang.com/2010/03/03/javadoc-con-uml/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 18:42:07 +0000</pubDate>
		<dc:creator>Chuidiang</dc:creator>
				<category><![CDATA[Herramientas]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[UML]]></category>
		<category><![CDATA[javadoc]]></category>
		<category><![CDATA[umlgraph]]></category>

		<guid isPermaLink="false">http://blog.chuidiang.com/?p=718</guid>
		<description><![CDATA[Hurgando por ah&#237; me he encontrado con UMLGraph, una herramienta que genera gr&#225;ficos UML a partir de unos textos que los describen. Lo bueno es que, al menos para el diagrama de clases, el texto que describe el diagrama UML es exactamente igual que un fuente java. Dicho de otra forma, si ponemos en el [...]]]></description>
			<content:encoded><![CDATA[<p>Hurgando por ah&iacute; me he encontrado con <a href="http://www.umlgraph.org/">UMLGraph</a>, una herramienta que genera gr&aacute;ficos <a href="http://es.wikipedia.org/wiki/Lenguaje_Unificado_de_Modelado">UML</a> a partir de unos textos que los describen. Lo bueno es que, al menos para el diagrama de clases, el texto que describe el diagrama UML es exactamente igual que un fuente java. Dicho de otra forma, si ponemos en el fichero &quot;<em>class UnaClase extends UnPadre {}</em>&quot;, obtendremos un diagrama con una cajita UnaClase que hereda (flechita con tri&aacute;ngulo) de una cajita UnPadre. Puedes ver el ejemplo <a href="http://www.umlgraph.org/doc/cd-intro.html">aqu&iacute;</a>. Esto lo hace ideal para generar los gr&aacute;ficos UML de clases a partir de c&oacute;digo fuente ya hecho.</p>
<p>Otro punto interesante es que viene con la posibilidad de invocar javadoc usando UMLGraph, de forma que en nuestro javadoc se generar&iacute;a diagramas de clases incrustados. UMLGraph viene con un <a href="http://java.sun.com/javase/6/docs/technotes/guides/javadoc/doclet/overview.html">doclet</a> que se puede usar desde el comando javadoc de java y de esta forma, javadoc generar&aacute; la documentaci&oacute;n de la forma habitual, pero incluyendo un gr&aacute;fico de UML. En la descripci&oacute;n de un package, pondr&aacute; todas las clase incluidas en ese package y las relaciones entre ellas. En la descripci&oacute;n de una clase pondr&aacute; un dibujo de dicha clase con las relaciones (herencias, dependencias, etc) con otras clases del paquete o de otros paquetes. En la figura puedes ver un ejemplo de javadoc generado con el doclet de UMLGraph.</p>
<p><a href="http://blog.chuidiang.com/wp-content/uploads/javadoc-uml.png"><img alt="javadoc con grafico UML" width="500" height="390" src="http://blog.chuidiang.com/wp-content/uploads/javadoc-uml.png" /></a></p>
<p>Un detalle a tener en cuenta es que para que UMLGraph pueda generar los ficheros gr&aacute;ficos es necesario tener instalado previamente&nbsp;<a href="http://www.graphviz.org/">GraphViz</a>.</p>
<p>En el diagrama de clases podr&iacute;an configurarse muchas cosas, poner notas asociadas a las clases, poner otro tipo de cajas que no sean de clases, m&eacute;todos que deben o no mostrarse, etc. La pega de ello es que ir&iacute;a configurado en c&oacute;digo a base de <a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html">anotaciones</a>, por lo que el c&oacute;digo quedar&iacute;a algo &quot;guarreado&quot; para luego ver el dibujo bonito.</p>
<p>Tambi&eacute;n pueden hacerse <a href="http://www.umlgraph.org/doc/seq-intro.html">diagramas de secuencia</a>, pero desgraciadamente la sintaxis del fichero de texto que lo describe ya no es java, as&iacute; que no deja de ser una forma alternativa de hacer el diagrama. Puede ser interesante, por ejemplo, si guardamos los diagramas de secuencia en un sistema de control de versiones (como <a href="http://subversion.tigris.org/">subversion</a>). Siempre ocupa menos y es m&aacute;s interesante para ver diferencias con versiones anteriores un fichero de texto que no un gr&aacute;fico o un proyecto entero de alguna herramienta compleja de generaci&oacute;n de gr&aacute;ficos UML (<a href="http://www.borland.com/us/products/together/index.html">Together</a>, <a href="http://www-01.ibm.com/software/rational/uml/">Rational</a>,&#8230;).</p>
<p>Y otra cosa que a m&iacute; siempre me viene bien, es que UMLGraph est&aacute; subido al <a href="http://mirrors.ibiblio.org/pub/mirrors/maven2/gr/spinellis/UmlGraph/4.6/">repositorio ibiblio de maven</a> y tiene plugin para el mismo. De esta forma, <a href="http://maven.apache.org/pom.html">configurando el fichero pom.xml de nuestro proyecto maven</a> (en concreto, configurando el plugin de javadoc para que use el doclet de UMLGraph), podemos generar el javadoc con gr&aacute;ficos UML directamente desde maven. La configuraci&oacute;n ser&iacute;a algo parecido a esto</p>
<blockquote>
<p>&lt;reporting&gt; <br />
&nbsp;&nbsp; &lt;plugins&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp;&lt;plugin&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &lt;artifactId&gt;maven-javadoc-plugin&lt;/artifactId&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &lt;configuration&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;source&gt;1.5&lt;/source&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;aggregate&gt;true&lt;/aggregate&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;doclet&gt;gr.spinellis.umlgraph.doclet.UmlGraphDoc&lt;/doclet&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;docletArtifact&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;groupId&gt;gr.spinellis&lt;/groupId&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;artifactId&gt;UmlGraph&lt;/artifactId&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;version&gt;4.6&lt;/version&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/docletArtifact&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;additionalparam&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-inferrel -inferdep -quiet -hide java.* <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-collpackages java.util.* -qualify <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-postfixpackage -nodefontsize 9 <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -nodefontpackagesize 7 <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/additionalparam&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/configuration&gt; <br />
&nbsp;&nbsp; &nbsp; &nbsp; &lt;/plugin&gt; <br />
&nbsp;&nbsp; &nbsp;&lt;/plugins&gt; <br />
&lt;/reporting&gt;</p>
</blockquote>
<p>Con esto, un simple <em>mvn javadoc:javadoc</em> nos generar&iacute;a la documentaci&oacute;n javadoc de nuestro proyecto maven, gr&aacute;ficos UML incluidos.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chuidiang.com/2010/03/03/javadoc-con-uml/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>OutOfMemoryError con test de maven</title>
		<link>http://blog.chuidiang.com/2010/02/24/outofmemoryerror-con-test-de-maven/</link>
		<comments>http://blog.chuidiang.com/2010/02/24/outofmemoryerror-con-test-de-maven/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 07:54:35 +0000</pubDate>
		<dc:creator>Chuidiang</dc:creator>
				<category><![CDATA[maven]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[outofmemoryerror]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://blog.chuidiang.com/?p=716</guid>
		<description><![CDATA[&#160; El otro d&#237;a me salto un OutOfMemoryError al ejecutarse un test autom&#225;tico desde maven. Te&#243;ricamente, para evitar problemas de memoria con maven basta con poner la variable de entorno MAVEN_OPTS con los par&#225;metros que le queremos pasar a la m&#225;quina virtual de java, en concreto, los de aumento de memoria set MAVEN_OPTS=-Xmx512m De hecho, [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;</p>
<p>El otro d&iacute;a me salto un <a href="http://java.sun.com/javase/6/docs/api/java/lang/OutOfMemoryError.html">OutOfMemoryError</a> al ejecutarse un test autom&aacute;tico desde <a href="http://maven.apache.org/">maven</a>. Te&oacute;ricamente, para evitar problemas de memoria con maven basta con poner la variable de entorno MAVEN_OPTS con los <a href="http://java.sun.com/javase/6/docs/technotes/tools/windows/java.html">par&aacute;metros que le queremos pasar a la m&aacute;quina virtual de java</a>, en concreto, los de aumento de memoria</p>
<blockquote>
<p>set MAVEN_OPTS=-Xmx512m</p>
</blockquote>
<p>De hecho, tengo esa variable puesta por defecto en el entorno y estaba correctamente inicializada. Pero el OutOfMemoryException persiste. As&iacute; que a buscar en google.</p>
<p>Al final encuentro que maven arranca una m&aacute;quina virtual java separada para ejecutar los test y que el par&aacute;metro MAVEN_OPTS s&oacute;lo afecta a la m&aacute;quina virtual en la que corre maven y no a la m&aacute;quina virtual en la que se ejecutan los test. El plugin de maven que se encarga de ejecutar los test autom&aacute;ticos se llama <a href="http://maven.apache.org/plugins/maven-surefire-plugin/">maven-surefire-plugin</a> y tiene <a href="http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html">su propia configuraci&oacute;n</a>. La variable argLine permite indicar, entre otras cosas, la cantidad de memoria que queremos que se asigne a la m&aacute;quina virtual java en la que se ejecutan los test. Para ello, debemos ejecutar as&iacute;</p>
<blockquote>
<p>mvn -DargLine=-Xmx512m test</p>
</blockquote>
<p>o bien, configurarlo en el mismo pom.xml del proyecto</p>
<blockquote>
<p>&lt;project&gt;<br />
&lt;build&gt;<br />
&lt;plugins&gt;<br />
&nbsp;&nbsp; &#8230;<br />
&nbsp;&nbsp; &lt;plugin&gt;<br />
&nbsp;&nbsp; &nbsp;&nbsp; &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;<br />
&nbsp;&nbsp; &nbsp;&nbsp; &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp; &nbsp;&nbsp; &lt;configuration&gt;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;argLine&gt;-Xmx512m&lt;/argLine&gt;<br />
&nbsp;&nbsp; &nbsp;&nbsp; &lt;/configuration&gt;<br />
&nbsp;&nbsp; &lt;/plugin&gt;<br />
&nbsp;</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.chuidiang.com/2010/02/24/outofmemoryerror-con-test-de-maven/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Archiva vs Nexus</title>
		<link>http://blog.chuidiang.com/2009/11/25/archiva-vs-nexus/</link>
		<comments>http://blog.chuidiang.com/2009/11/25/archiva-vs-nexus/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 18:04:16 +0000</pubDate>
		<dc:creator>Chuidiang</dc:creator>
				<category><![CDATA[archiva]]></category>
		<category><![CDATA[nexus]]></category>
		<category><![CDATA[hudson]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://blog.chuidiang.com/?p=684</guid>
		<description><![CDATA[&#160; En su d&#237;a nos instalamos un repositorio propio para nuestros jar, de forma que estuvieran accesibles para todos los desarrolladores. Para ello usamos archiva, y ha funcionado m&#225;s o menos bien con sus cosillas. Hace adem&#225;s las veces de proxy con los repositorios de maven que hay por internet. De esta forma, cada desarrollador [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;</p>
<p>En su d&iacute;a nos instalamos un repositorio propio para nuestros jar, de forma que estuvieran accesibles para todos los desarrolladores. Para ello usamos <a href="http://blog.chuidiang.com/2008/10/21/jugando-con-archiva/">archiva</a>, y ha funcionado m&aacute;s o menos bien con sus cosillas. Hace adem&aacute;s las veces de proxy con los repositorios de maven que hay por internet. De esta forma, cada desarrollador &uacute;nicamente debe configurar maven para que busque los jars en el repositorio de archiva y es este el que se encarga de acceder a internet y buscarlos si es necesario.</p>
<p>No hace mucho descubr&iacute; que hab&iacute;a otra herramienta similar llamada <a href="http://nexus.sonatype.org/">nexus</a>. Como archiva nos hac&iacute;a cosas raras de vez en cuando (no tra&iacute;a las cosas de los repositorios de internet, no s&eacute; muy bien si por culpa de archiva o de nuestra conexi&oacute;n a internet, que va con proxy autentificado. Tambi&eacute;n dejaba ficheros tmp vac&iacute;os en el repositorio de vez en cuando). As&iacute; que hoy me he decidido a instalar nexus y probar.</p>
<p>La instalaci&oacute;n sencilla, un zip que te bajas, desempaquetas y tienes los scripts necesarios de windows, linux, solaris&#8230; para instalar nexus como servicio y arrancarlo y pararlo. Eso s&iacute;, hay dos versiones, la gratis con menos posibilidades de autentificaci&oacute;n/seguridad, y la de pago que tiene de todo. La gratis en principio tiene lo necesario: gesti&oacute;n de usuarios y permisos propia, funciones de proxy y repositorios propios.</p>
<p>La interface web mucho mejor que la de archiva. Bastante m&aacute;s bonita y agradable. R&aacute;pidamente me puse en ella a configurar nuestros repositorios, tanto los propios, como los repositorios que son proxy de los est&aacute;ndar de internet (que ya vienen configurados los de maven central, apache y codehaus).</p>
<p>Y vamos a las cosas que me han gustado y que me han decidido a intentar el cambio en serio:</p>
<ol>
<li>Es m&aacute;s estricto que archiva con los SNAPSHOTS y las releases. Archiva permite subir y bajar jars snapshots y no snapshots de repositorios snapshots y no snapshots indistintamente. Somos los desarrolladores los que tenemos que tener cuidado de d&oacute;nde subimos los jar. Nexus es m&aacute;s estricto, si intentamos subir un jar no snapshot a un repositorio que hemos marcado como snapshot, protesta. Y al rev&eacute;s tambi&eacute;n.</li>
<li>Permite programar tareas de mantenimiento peri&oacute;dicas y entre ellas, la que veo m&aacute;s &uacute;til en nuestro caso: permite que se limpien autom&aacute;ticamente las versiones snapshots m&aacute;s antiguas o indicar cu&aacute;ntos snapshots quieres como m&aacute;ximo por cada jar. En un entorno de desarrollo como el nuestro en el que <a href="http://blog.chuidiang.com/2008/09/18/hudson/">Hudson</a> genera y sube muchos snapshots gigantes todas las noches, una limpieza peri&oacute;dica se hace imprescindible.</li>
<li>Cuando configuras un repositorio como proxy de uno externo, tienes m&aacute;s visibilidad de si tiene o no conexi&oacute;n con el repositorio externo, si se ha bajado algo de &eacute;l y qu&eacute; se ha bajado.</li>
</ol>
<p>Para ser justos, estoy comparando una versi&oacute;n antigua de archiva, que instal&eacute; hace mucho, con la &uacute;ltima de nexus. Es posible que las versiones m&aacute;s modernas de archiva hayan mejorado o permitan hacer estas cosas que digo que hace nexus.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chuidiang.com/2009/11/25/archiva-vs-nexus/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Sobre dependencias</title>
		<link>http://blog.chuidiang.com/2009/05/08/sobre-dependencias/</link>
		<comments>http://blog.chuidiang.com/2009/05/08/sobre-dependencias/#comments</comments>
		<pubDate>Fri, 08 May 2009 14:38:03 +0000</pubDate>
		<dc:creator>Chuidiang</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://blog.chuidiang.com/?p=574</guid>
		<description><![CDATA[&#160; Un par de cosillas/problemillas que me he encontrado sobre las dependencias de unos jar con otros. Maven por un lado Sup&#243;n que tenemos un proyecto A con maven que tiene a su vez dos subproyectos B y C. Si le decimos a maven a trav&#233;s de los ficheros pom.xml que B necesita de C [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;</p>
<p>Un par de cosillas/problemillas que me he encontrado sobre las dependencias de unos jar con otros.</p>
<p><strong>Maven por un lado</strong></p>
<p>Sup&oacute;n que tenemos un proyecto A con <a href="http://www.chuidiang.com/java/herramientas/maven.php">maven</a> que tiene a su vez dos subproyectos B y C. Si le decimos a maven a trav&eacute;s de los ficheros pom.xml que B necesita de C para compilar y que C necesita de B para compilar, maven, obviamente, protesta. La excusa es que no sabe qu&eacute; debe compilar primero, ya que el uno depende del otro. Hasta aqu&iacute; todo parece correcto.</p>
<p>Supongamos ahora la misma estructura de proyectos de antes, pero esta vez decimos que B necesita a C para compilar y que C necesita de B s&oacute;lo en tiempo de ejecuci&oacute;n (runtime). Pues bien, maven protesta igualmente. Sin embargo, esta vez, la excusa ya no vale. Si B necesita de C para compilar y C s&oacute;lo necesita a B en runtime, entonces est&aacute; claro que se puede compilar primero C y luego B. Esto ya es algo que puede en un momento dado molestar, aunque quiz&aacute;s no sea muy correcto un proyecto con esta dependencia.</p>
<p>Pero ahora viene lo peor. Si en vez de un proyecto A con subproyectos B y C tenemos directamente dos proyectos maven independientes, B y C, maven te&oacute;ricamente ser&iacute;a capaz de detectar igualmente las dependencias. En el repositorio de jars que usemos estar&aacute;n los jar de B y C y sus ficheros pom.xml con las dependencias. Sin embargo, al ser independientes, NO protesta. En principio no podemos llegar a esta situaci&oacute;n directamente, ya que si B necesita de C para compilar y C necesita de B para compilar, no podemos compilar ninguno de los dos, ya que en ning&uacute;n caso estar&aacute; el jar del otro en el repositorio (ya que no hemos podido compilarlo). Pero s&iacute; podemos hacerlo poco a poco, en unos proyectos reales que evolucionan con el tiempo. Podemos empezar creando los proyectos B y C como indpendientes e ir compil&aacute;ndolos. Seg&uacute;n avanzan los proyectos, en un momento dado podemos necesitar la dependencia de B con C y la a&ntilde;adimos. Todo bien. Pero seg&uacute;n avanzamos m&aacute;s y por descuido, podemos a&ntilde;adir la dependencia de C con B&#8230;. y maven no protesta, puesto que encuentra los jar anteriores en el repositorio y no revisa las dependencias entre proyectos independientes.</p>
<p><strong>Usar muchas librer&iacute;as, por otro lado</strong></p>
<p>Este otro problema es m&aacute;s filos&oacute;fico que de una herramienta concreta, aunque me he tropezado con &eacute;l en la realidad. Sup&oacute;n que haces un proyecto java y decides usar librer&iacute;as de terceros, de esas libres que hay por ah&iacute;, por ejemplo, <a href="http://www.chuidiang.com/chuwiki/index.php?title=Ejemplo_b%C3%A1sico_con_Jasper_Report">jasperreport</a>, <a href="http://www.chuidiang.com/chuwiki/index.php?title=Ejemplo_sencillo_con_JFreeChart_:_Area%2C_Bar_y_Line">jfreechart</a>, <a href="http://www.chuidiang.com/chuwiki/index.php?title=Categor%C3%ADa:Ibatis">ibatis</a>, <a href="http://www.chuidiang.com/chuwiki/index.php?title=Ejemplo_sencillo_con_Hibernate">hibernate</a>, etc. Digamos, por ejemplo, que decides usar la A y la B. Pues bien, es bastante f&aacute;cil que ambas necesiten de alguna librer&iacute;a m&aacute;s de terceros, por ejemplo, <a href="http://www.chuidiang.com/chuwiki/index.php?title=Ejemplo_con_log4j">log4j</a>. Por generalizar, tanto A como B necesitan que nos descarguemos e incluyamos en nuestro proyecto a C. Sin problemas de momento.</p>
<p>Pero, &iquest;qu&eacute; pasa si A necesita C-1.0 y B necesita C-2.0 y las versiones 1.0 y 2.0 son incompatibles?. Pues b&aacute;sicamente que la hemos cagado. Para que todo vaya bien, necesitamos las dos versiones de la librer&iacute;a y tendremos problemas a la hora de configurar el classpath, porque muchas clases estar&aacute;n repetidas en ambas versiones y se encontrar&aacute; la primera que pongamos en el classpath, que puede ser la que no le gusta a la librer&iacute;a A y que de paso le sienta mal a la B. Y si ponemos s&oacute;lo una, A no funciona y si ponemos s&oacute;lo la otra, es B el que protesta.</p>
<p>Desgraciadamente, estas situaciones van siendo cada vez m&aacute;s comunes. Hay librer&iacute;as java como las apache-commons, log4j, etc que son muy, pero que muy utilizadas por much&iacute;simas librer&iacute;as de m&aacute;s alto nivel, como hibernate, jfreechart, etc. Todas estas librer&iacute;as de alto nivel no avanzan a la vez ni se actualizan con la misma frecuencia, por lo que puede ser normal que una necesite log4j-1.2.13 y otra log4j-1.2.15. Con log4j en concreto no hay mucho problema, pero s&iacute; hay otras m&aacute;s conflictivas. </p>
<p>A cuento con lo de <a href="http://blog.chuidiang.com/2009/04/25/%C2%BFelegancia-o-sencillez/">elegancia o sencillez</a>, este parece un motivo para ir m&aacute;s a la sencillez que a la elegancia. Las liber&iacute;as de alto nivel que pretendan ser compatibles con otras librer&iacute;as de alto nivel que no tienen nada que ver ellas, deber&iacute;an casi casi reinventar la rueda cada vez en vez de usar librer&iacute;as de m&aacute;s bajo nivel. O quiz&aacute;s estas librer&iacute;as de muy bajo nivel y mayoritariamente usadas deber&iacute;an venir pr&aacute;cticamente incluidas en el JDK de java.</p>
<p>No se, veo dif&iacute;cil soluci&oacute;n y preveo que a la larga la cosa ira empeorando. De momento es dif&iacute;cil tropezarse con estas situaciones, pero a m&iacute; ya me ha ocurrido alguna vez.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chuidiang.com/2009/05/08/sobre-dependencias/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>¿Elegancia o sencillez?</title>
		<link>http://blog.chuidiang.com/2009/04/25/%c2%bfelegancia-o-sencillez/</link>
		<comments>http://blog.chuidiang.com/2009/04/25/%c2%bfelegancia-o-sencillez/#comments</comments>
		<pubDate>Sat, 25 Apr 2009 15:49:17 +0000</pubDate>
		<dc:creator>Chuidiang</dc:creator>
				<category><![CDATA[trabajo]]></category>
		<category><![CDATA[assembly]]></category>
		<category><![CDATA[izpack]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://blog.chuidiang.com/?p=567</guid>
		<description><![CDATA[&#160; En el trabajo llevamos varios d&#237;as pele&#225;ndonos con la instalaci&#243;n de una versi&#243;n de nuestro software en uno de nuestros sistemas. El sistema consta de unas diez estaciones de trabajo solaris y unos veinte PCs con Windows. En todos ellos corren aplicaciones nuestras, en su mayor&#237;a java. Estas aplicaciones tienen algunas partes comunes, pero [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;</p>
<p>En el trabajo llevamos varios d&iacute;as pele&aacute;ndonos con la instalaci&oacute;n de una versi&oacute;n de nuestro software en uno de nuestros sistemas. El sistema consta de unas diez estaciones de trabajo solaris y unos veinte PCs con Windows. En todos ellos corren aplicaciones nuestras, en su mayor&iacute;a java. Estas aplicaciones tienen algunas partes comunes, pero son distintas en cada una de las estaciones y de los PCs (cada uno est&aacute; especializado en diversas funciones, algunas comunes, otras no y comparten mucha informaci&oacute;n entre ellos). En las estaciones hay bases de datos Oracle, con muchas tablas comunes, pero otras distintas en cada estaci&oacute;n. Y en todo esto reside el problema de la instalaci&oacute;n.</p>
<p>La gente est&aacute; dividida en dos posibles tipos de instalaci&oacute;n.</p>
<p>Junto con algunos, yo soy partidario de implementar las distintas funcionalidades del sistema en jar distintos e instalar en cada estacion/PC s&oacute;lo aquellos jar que son necesarios, de forma que ninguna estaci&oacute;n/PC lleve m&aacute;s jar o ficheros de configuraci&oacute;n que no va a usar. Esta es la soluci&oacute;n que considero elegante, pero es m&aacute;s compleja. Requiere generar instaladores/zips disintos para cada estaci&oacute;n/PC, as&iacute; como ser mucho m&aacute;s cuidadoso en esta generaci&oacute;n de instaladores/zips, muchos jar, muchos grupos de ficheros de configuraci&oacute;n, partes comunes y partes espec&iacute;ficas.</p>
<p>Otros piensan que es mejor hacer un &uacute;nico mega-jar, o unos pocos jar grandes, un &uacute;nico mega-grupo de ficheros de configuraci&oacute;n e instalar todo en todos lados. De esta forma, un &uacute;nico instalador o un &uacute;nico zip vale para todas las estaciones/PCs. Luego es el propio software el que mirando el nombre de la estaci&oacute;n/PC en el que corre, sabe qu&eacute; fichero concreto de configuraci&oacute;n leer, de qu&eacute; clase principal hacer el new y actuar como lo que le toca. Esta instalaci&oacute;n es, desde mi punto de vista, m&aacute;s chapuza, pero es innegable que es infinitamente m&aacute;s sencilla.</p>
<p>Y despu&eacute;s de la pelea de estos d&iacute;as atr&aacute;s para la instalaci&oacute;n seg&uacute;n mi punto de vista (disintos zips/instaladores que instalan en cada estaci&oacute;n/PC s&oacute;lo lo necesario), creo que estoy empezando a cambiar de opini&oacute;n. Los instaladores/zips, desde luego, se hacen con procesos autom&aacute;ticos, pero alguien tiene que decirle a ese proceso qu&eacute; debe meter. Seg&uacute;n evoluciona el software y va llevando m&aacute;s funcionalidades y ficheros, hay que tocar la configuraci&oacute;n de la herramienta que genera los instaladores/zips (<a href="http://izpack.org/">izpack</a>, <a href="http://www.chuidiang.com/chuwiki/index.php?title=Hacer_un_zip_para_distribuir">maven assembly</a>,&#8230;) y hay que hacerlo con cuidado. Este proceso es manual y est&aacute; sujeto a errores humanos, por lo que a nuestros instaladores siempre les acaba faltando alguna cosa y necesitan su proceso de &quot;depuraci&oacute;n&quot;.</p>
<p>En fin, no me gustan las chapuzas y tengo que pensar seriamente la forma de mejorar el proceso de generar los zips/instaladores, pero desde luego, es dif&iacute;cil resistirse a la facilidad de instalaci&oacute;n de &quot;todo va en todos sitios, aunque no se use&quot;. Es mucho m&aacute;s f&aacute;cil instalar un solo mega-jar en todos lados que instalar varios jar distintos en cada estaci&oacute;n/PC.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chuidiang.com/2009/04/25/%c2%bfelegancia-o-sencillez/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

