Dec 17

Por qué me está gustando IntelliJ IDEA

 Hace ya un porrón de años tuve que elegir un IDE para trabajar con Java. Miré Eclipse y Netbeans, de aquella no existía IntelliJ y me acabé decantando por eclipse. Y desde entonces, más de 10 años ya, trabajando con eclipse.

Sin embargo, algunos compañeros míos usan IntelliJ y están muy contentos con él. También encontré unas estadísticas en las que IntelliJ se estaba usando cada vez más mientras que Eclipse parece que cada vez menos, aunque actualmente andan muy a la par.

Así que me decidí a probar IntelliJ …. y de momento me está convenciendo.

Me está costando acostumbrarme a los atajos de teclado o encontrar los comandos del IDE que quiero hacer, pero sólo es por la costumbre y poco a poco me voy haciendo a los nuevos atajos. Aparte de esto ¿por qué me está gustando?

Lo primero es el auto-compilar. Eclipse auto-compila siempre. IntelliJ por defecto no lo  hace, pero es una opción que se puede poner. El autocompilado de eclipse a veces hace el trabajo lento o pesado. En eclipse me veía frecuentemente esperando por barras del progreso de cosas que el eclipse estaba haciendo por debajo. En IntelliJ de momento no me está pasando.

Soy fan del editor vi. IntelliJ lo lleva por defecto, pero se puede activar/desactivar. Siempre tengo el gvim instalado en windows para determinadas tareas, ahora parece que no me va a hacer falta.

IntelliJ lleva la ventana de comandos del sistema empotrada por defecto. Habitualmente me gusta ejecutar los comandos de gradle, maven, git y subversion desde línea de comandos, porque me da la impresión de tener más control de lo que estoy haciendo. Lo de tener la ventana de comandos integrada en el IDE me está ayudando mucho. Sí, eclipse tiene un plugin opcional para poner.

Otra ventaja que resulta más o menos interesante es que el autocompletar de IntelliJ es más inteligente. Incluso autocompleta el nombre de la variable que estamos declarando, ofreciéndonos sugerencias. Por ejemplo, si tengo una clase MiClase y despues de poner el tipo MiClase le digo a IntelliJ que me diga el posible nombre de variable, me pone miClase.

Pero todo esto no dejan de ser detalles (bueno, quizás lo de las esperas de eclipse no sea tan tonto). Una de las cosas que me ha convencido totalmente de IntelliJ es que IntelliJ entiende por separado los classpath de test y de main. Tanto en gradle como en maven, hay directorios src/main/java y src/test/java y hay dependencias de compilado y dependencias de test. Tanto gradle como maven no incluyen para nada las dependencias de test en compilado o runtime, salvo que se estén haciendo test. Pues bien, eclipse no hace esta distinción en absoluto. En tu código de src/main/java puedes usasr clase que sean de test o de dependencias de test. En eclipse va, pero al compilar luego fuera de eclipse con gradle o maven, da error. IntelliJ sin embargo sí tiene en cuenta esta separación. Tiene su "classpath" de "proyecto_main" y "proyecto_test".

En fin, llevo ya un par de semanas con IntelliJ y me está gustando más que eclipse. Es posible que tenga que volver a eclipse cuando quera utilizar alguna cosa que no venga en la edición gratuita de IntelliJ.

May 30

Autocompletar en los IDE

autocompletar en javascriptPara trabajar siempre me gustan más los lenguajes estáticamente tipados que los dinámicamente tipados y entre otras ventajas, una de ellas es la de autocompletar de los IDE. Pero siempre que digo esto, alguien me comenta que si el IDE está correctamente configurado, los dinámicamente tipados también tienen autocompletar.

Bien, esto es cierto, pero sólo parcialmente. Imagina el siguiente trozo de código en un lenguaje estáticamente tipado, como java

public void metodo ( UnaClase parametro) {
   parametro.???
}

Cuando empezamos a teclear en la zona de ???, el IDE sabe que parámetro es de tipo UnaClase, porque se ve claramente, así que es perfectamente capaz de darnos los métodos y atributos públicos de parámetro para que elijamos uno.

Sin embargo, en un lenguaje dinámicamente tipado, si tenemos el código equivalente

function unaFuncion (parametro) {
   parametro.???
}

aquí el IDE no tiene ni idea de qué tipo es parámetro y de hecho, no puede saberlo, porque parámetro puede ser de cualquier tipo cuando el código se esté ejecutando, se puede llamar a unaFuncion() pasándole un entero, una cadena de texto, un objeto propio que hayamos creado o cualquier otro tipo que se nos ocurra. Así que el IDE aquí es totalmente incapaz de ofrecernos opciones, salvo que el lenguaje tenga algo común en todos sus tipos.

¿Cómo se apaña entonces para autocompletar?. Bien, un caso como el que acabamos de mostrar es imposible, pero los IDEs tienen sus trucos para ofrecernos opciones de autocompletar cuando es posible. Por ejemplo, en el caso anterior, si tenemos

function unaFuncion (parametro) {
   parametro.funcion1();
   parametro.funcion2();
   var a = parametro.atributo1;
   parametro.???
}

aquí el IDE ve qué cosas usamos de parámetro, así que cuando lleguemos a los ??? nos ofrecerá las funciones y atributos que ya hemos usado (funcion1, funcion2, atributo1), sean o no correctos y de hecho, pueden no ser correctos porque nos hemos equivocado al teclear o simplemente porque en tiempo de ejecución alguien nos pasa como parámetro algo que no tenga esas funciones ni atributos.

Otro truco usado por los IDE es el siguiente

function unaFuncion () {
   var b = new UnaClase()
   b.???
}

en este caso, se ve claramente qué contiene la variable b, aunque no tenga tipo definido, ya que estamos haciendo un new de una clase concreta y metiéndola en la variable. Si el IDE es capaz de encontrar en nuestro código la definición de UnaClase, será capaz de ofrecernos sus métodos/funciones y atributos … es justo el caso de la imagen.

Así que sí, los IDE pueden autocompletar en lenguajes dinámicamente tipados, pero con ciertas limitaciones.

Feb 01

Acciones adicionales al salvar un fichero con Eclipse

 

Un compañero me mostró una característica interesante de eclipse. Es posible configurarlo para que cada vez que demos "salvar" a uno de nuestros ficheros java, realice en él algunas acciones que le indiquemos: arreglar los imports, darle formato al código, poner las llaves en todos los bloques if, while, for aunque no sean necesarios, eliminar variables locales o privadas que no se usan, etc, etc.

A todo esto se accede desde "window" -> "preferences" -> "java" -> "editor" -> "save actions" (en eclipse versión 3.4.1). Ahí nos muestra una ventana con un montón de acciones que se pueden hacer, junto con un ejemplo de texto java para que veamos cómo afecta.

Hace poco, comenté que he instalado Sonar y viendo algunas de las métricas que tiene en cuenta, veo que muchas pueden cumplirse sin dificultad símplemente configurando eclipse con estas opciones. Por ejemplo, Sonar considera incorrecto (warning) no poner llaves en un if, else o bucle que sólo tenga una línea. Poniendo esta opcion, no solo nuestros nuevos ficheros cumplirán esta métrica, sino que los viejos, según los vayams tocando para lo que sea, se iran arreglando solos.

Un pequeño detalle, ojo con lo de eliminar automáticamente los atributos privados y variable locales no usadas. Yo lo he puesto y según voy escribiendo código, tengo la costumbre de salvar con cierta frecuencia. Si escribo una variable local que voy a usar más adelante, pero todavía no la he usado y le doy a salvar, me la borra, por lo que tengo que volver a escribirla o darle al Ctrl-Z.

Más detalles en Accion adicionales al salvar un fichero con eclipse.

Jan 31

Debugger remoto en java con Eclipse

Bueno, es un tema muy sabido, yo también sabía que existía hace tiempo y mucha gente lo usa para depurar la parte del servidor en sus aplicaciones web. Yo, como desarrollo aplicaciones de escritorio, nunca me había preocupado por el tema.

Sin embargo, sí me ha salido la necesidad. Nuestras aplicaciones de escritorio como tales son realmente sólo interface de usuario, mucho java Swing sobre PCs con Windows. Pero esa, aunque es la parte más labiorosa y la que más líneas de código lleva y la que es más difícil de hacer bien, es lo que la mayoría de la gente considera la parte "tonta" de la aplicación. La parte "de verdad" de la aplicación es una ejecutable java que hace de servidor, que corre en una estación de trabajo Sun que ni siquiera tiene monitor ni teclado. El código de ese ejecutable se desarrolla y prueba por supuesto, en PCs con pantalla y teclado y eclipse. El software se instala y arranca en esas estaciones sun a base de "telnet" desde los PCs. Y por ello es muy difícil de depurar en el "entorno de producción".

Normalmente no es necesaria esa depuración. El ejecutable java que hace de servidor suele salir lo bastante bien del PC como para tener cierta garantía de que funciona bien. Y si hay algún problema, no suele haber problemas en arrancar el servidor con eclipse en el PC y depurarlo ahí de una forma normal. Pero no siempre es posible y, de hecho, tenemos un problema últimamente que requiere depuración en el entorno real, así que me he metido con lo de la depuración remota con eclipse.

El tema es bastante sencillo. Por un lado, basta con arrancar el programa que queremos probar con las siguientes opciones:

-Xdebug -Xrunjdwp:transport=dt_socket,address=1044,server=y,suspend=n

donde básicamente le estamos indicando con -Xdebug que debe admitir una conexión remota para debug y con -Xrunjdwp:transport los parámetros para esa conexión, así como que no debe esperar la conexión del debugger (suspend=n).

Luego, en eclipse, con el proyecto y los fuentes del programa a depurar montados, basta abrir la configuración de debugger (Run -> Debug Configuration) y crear una configuración de Remote Java Application para ese proyecto indicando los parámetros de conexión y el ordenador en que corre el ejecutable.

Por supuesto, aunque es una tontería, en la Chuwiki he puesto los detalles de la depuración remota con eclipse. Y hasta he puesto fotos, yo, que soy vago para capturar pantallas.

Sep 07

Jugando con el móvil y J2ME

Este verano me han regalado un móvil. No es que me hagan especial ilusión, de hecho el que tenía  lo usaba como hucha y me explico: es de tarjeta prepago, cada seis meses le echo dinero para que no caduque, pero habitualmente dejo el móvil apagado y en casa, por lo que el saldo se va incrementando, como una hucha.

Sin embargo, el móvil que me han regalado sí tiene una cosa que me ha hecho ilusión: Java.

Así que me he decidido a hacer un primer "Hola Mundo" para el móvil y así enterarme de qué va todo esto de J2ME.

Primero a la página de sun, a bajarme el J2ME. Ya empezamos con cosas raras (para el que no tiene ni idea, como yo). Lo que hay que bajar es el "Sun java wireless Toolkit 2.5.2 for CLDC". Bueno, yo esperaba algo así como un JDK o un JRE y no un nombrecito tan extraño. Urgando un poco en google vi que era eso lo que había que bajarse para hacer programitas para el móvil.

La instalación es sencilla. Primero te pide el directorio de tu SDK de J2SE (tienes que tenerlo instalado previamente) para añadirle la parte de J2ME. Luego te pregunta por un directorio donde instalar el Wireless Toolkit. Ahí mete un pequeño entorno de desarrollo y un par (cuatro) emuladores de móviles estándar, para poder hacer pruebas antes de meter el código en el móvil.

Luego, como soy muy bruto, pensé en hacer el programa a pelo, es decir, con el gvim y compilando en línea de comandos. Es la mejor forma de enterarse qué estás haciendo. Sin embargo, mirando tutoriales, no encontré nada que me convenciera, además, soy un "caga-prisas" incapaz de pasarme dos días buscando y leyendo manuales antes de ponerme a codificar. Así que me decidí por Eclipse y su plugin para J2ME, el EclipseME, que por lo que he visto en google, debe ser el más aceptado.

Una vez instalado el plugin, se le da a nuevo proyecto J2ME y te crea un proyecto para J2ME con todos las dependencias ya puestas y un ficherito jda por defecto. Ese ficherito jda por lo visto en algo parecido al fichero de manifiesto de java estándar, pero para móviles y es obligatorio tenerlo. Ahí se indica el nombre de la aplicación, el icono que tiene que tener y la clase principal de la aplicación (la del main(), pero que aquí no tiene main(), sino que hereda de MIDlet, al igual que los applets no tienen main y heredan de Applet).

Luego, mirando por google y copiando trozillos de código de un lado y otro, hice el "Hola Mundo". Un programita que saca en la pantalla del móvil el texto "Hola Mundo". Ahora queda arrancarlo en eclipse a ver si funciona.

Hay que configurar el plugin EclipseME indicándole dónde están los emuladores de móviles. Para ello se le indica el directorio del Wireless Toolkit de Sun, donde están esos cuatro emuladores que comenté antes, y el plugin los busca y encuentra. Una vez hecho esto y elegido qué emulador quieres (el de móvil estándar con pantalla en color en mi caso), ya se puede ejecutar el programa.

Sale una ventana con el dibujo de un móvil en la pantalla. Allí se ejecuta el programa que hemos hecho y vemos en la pantalla del móvil el "Hola Mundo". Con el ratón podemos pulsar las teclas del móvil.

Ahora sólo me queda lo más importante, generar el .jar y meterlo en el móvil de verdad, a ver si funciona. La pega es que de momento no tengo ni bluetooth, ni cable de datos, así que hasta que vaya de compras no veré el resultado final.

Dec 04

XPlanner y Eclipse

Dos herramientas que se vuelven a integrar para trabajar conjuntamente: XPlanner y Eclipse

XPlanner, como ya mencioné alguna vez, es una pequeña aplicación desarrollada en JSP, por lo que necesitamos tener instalado Tomcat o algo parecido. Se accede a ella desde navegador y nos permite tener un listado de tareas a hacer por proyectos. Esta muy pensada para metodologías ágiles, como Scrum o Programación extrema. Para cada proyecto permite definir una serie de "historias de usuario" y para cada historia de usuario una serie de tareas para hacer. Las historias de usuario podemos agruparlas en iteraciones a realizar en un plazo determinado, al estilo de un Sprint de Scrum o iteración de programación extrema. Luego, día a día, podemos ir marcando cuánto hemos hecho para obtener gráficos al estilo Scrum.

Por otro lado, eclipse europa, según qué opción nos descarguemos, viene con un plugin llamado Mylyn que nos permite también gestionar nuestras tareas. Nos da en eclipse una perspectiva de "planning" en la que podemos crear nuestras carpetas de tareas pendientes y dentro de cada carpeta poner las tareas que queramos. Podemos activar las tareas cuando trabajamos en ellas y desactivarlas, de forma que Mylyn nos lleva una especie de cronómetro con el que podremos saber cuánto tiempo dedicamos a cada tarea. Desgraciadamente, es demasiado listo y si no estamos trabajando, no cuenta el tiempo. Otra característica interesante de Mylyn es que lleva un "filtro" de fuentes y ficheros que vamos tocando, de forma que al activar una tarea, sólo se ven aquellos fuentes con los que solemos trabajar en esa tarea. Interesante en proyectos grandes con miles de fuentes.

Y ahora lo más curioso de todo, Mylyn permite importar tareas de ciertas herramientas web como bugzilla y ahora, también de XPlanner. En Mylyn creamos un nuevo repositorio de tareas y seleccionamos XPlanner. Damos los datos necesarios, como la URL en la que está XPlanner, el nombre de usuario, el password y listo. Las tareas que tenemos de XPlanner se vienen a eclipse como lista de tareas a hacer. Desde el mismo eclipse podemos más o menos actualizar XPlanner.

Ya lo tengo instalado, con alguna tarea en XPlanner. Ahora solo queda lo más duro… ¡trabajar!

Nov 30

Springide

Llevo casi toda la semana entretenido, cambiando un poco los módulos ya hechos de una aplicación de escritorio para poder instanciarlos usando Springframework e instanciándolos con Springframework.

El primer módulo lo abordé con la ilusión de probar algo nuevo. Sin embargo, a la hora de escribir el fichero xml de configuración de Springframework empecé a intuir que ese fichero puede ser un verdadero infierno. Tenía abiertos dos editores, en uno la clase java principal del módulo/bean y en el otro el fichero XML. Iba mirando el nombre exacto de los métodos set() para poner el property con el mismo nombre en el fichero XML. Me reordaba a los viejos tiempos en que programaba en C++ con el vi, sin ningún tipo de IDE. Tenías que ir abriendo los ficheros .h para ver cómo se llamaba exáctamente el método y su parámetros para poder hacer la llamada en tu fichero .cpp

Indagando por google, descubrí que efectivamente, ese es uno de las pequeñas pegas de Springframework: XML grandes y pesados de construir.

Pero me dije, como todo está inventado, seguro que hay un plugin de eclipse para Springframework. Efectivamente, en Springide tienen un estupendo plugin de Springframework para eclipse. Se puede instalar desde eclipse, con "help" -> "software updates" -> "find and install" y poniendo la dirección http://springide.org/updatesite_dev/

La instalación me dio un pequeño problema. No se deja instalar completo, posiblemente porque la versión de eclipse que tengo es la más última y el plugin debe andar un poco por detrás. No obstante, la parte básica del plugin sí se instaló.

Una vez instalado Springide, la construcción del fichero XML es muy agradable. Eclipse ya ofrece ayuda contextual para los ficheros XML, de forma que en cualquier sitio del fichero, pulsando Ctrl-espacio, podemos ver los posibles tags o atributos XML que se pueden añadir siguiendo el DTD que se indique en la cabecera. Con Springide, la ayuda contextual incluye además las clases accesibles para el proyecto o las referencias a los beans ya declarados en el fichero XML.

Me explico, si empezamos a escribir

<bean id="nombre" class="MiC

y justo depués de la C de MiC pulsamos Ctrl-espacio, aparecerá el típico menú con todas las clases accesibles que empiecen por MiC. Seleccionamos una en el menú y se añade automáticamente, incluyendo el paquete.

De la misma forma, si escribimos

<property name="

y pulsamos Ctrl-espacio, aparece un menú con todos las propiedades de la clase en la que estemos poniendo este tag property. Elegimos una y seguimos escribiendo

<property name="propiedadElegida" ref="

y ahora, pulsando Ctrl-espacio sale un menú con todos los beans que ya tenemos declarados, para elegir uno.

Me queda comprobar si se pone en rojo si escribimos una clase, propiedad o bean que no exista.

May 08

Aprendiendo Orientación a Objetos observando (y III)

Otro ejemplo de Orientación a Objetos y patrones en la API de java es la forma de construir las ventanas, la interface gráfica de usuario.

Todos los componentes visuales -JButton, JCheckBox, JList, etc- heredan de Component y todos tienen el método paint(Graphics). Este método, en cada componente, dibuja el componente sobre el Graphics que se le pasa.

Pasarle el Graphics es nuevamente una buena idea y una aplicación del patrón Estrategia. Un JButton sabe qué tiene que dibujar -líneas, sombras, icono, etc-, pero es Graphics el que realmente hace el dibujo. Esto da mucha versatilidad, puesto que si al JButton le pasamos un Graphics que pinte en pantalla, el botón se dibujará en pantalla. Si le pasamos un Graphics que dibuje en impresora, el botón se dibujará en una impresora y si le pasamos un Graphics que dibuje en un BufferedImage -una imagen en memoria-, el JButton se dibujará en una imagen. El mismo botón con exactamente el mismo código puede dibujarse en cualquier lado.

Es más, si le pasamos un Graphics2D -que como hereda de Graphics se puede pasar- al que hayamos aplicado alguna transformación con setTransform(), podemos obtener fácilmente botones "deformados": girados, a escala, cizallados, etc.

Sin embargo todo esto va más allá. Hay componentes java como los JPanel que está destinados a "contener" otros componentes java. De esta forma, podemos tener un panel que tenga dentro dos botones, una lista y un checkbox. Estos componentes se llaman Container. Pues bien, los Container también heredan de Component y también tienen un método paint(). ¿Qué hace este método paint() del Container?. Sencillo, simplemente dibuja lo que es el panel y luego, con un bucle, llama al método paint() de cada uno de los componentes que tiene dentro.

Esto es una aplicación del patrón compuesto -Composite-. Tenemos un componente compuesto -el Container- que implementa la misma interface que un componente simple, por lo que se puede tratar perfectamene como cualquier otro componente. Pero en realidad está "compuesto" de otros componentes simples y en el método del componente simple -paint() en este caso-, simplemente va llamando a todos los paint() de los componentes simples.

Este mecanismo permite fácilmente crearse unas piezas simples de un puzzle, crearse nuevas piezas componiendo piezas simples que a su vez podríamos usar para componer piezas más complejas.

Esta idea puede servir de base para una librería gráfica. Una clase Lienzo recibe ObjetosGraficos que tengan un método dibujate(Graphics). Así, por ejemplo, podemos tener un ObjetoGrafico Rectangulo, Circulo, etc. Podemos componer ObjetosGraficos, haciendo un ObjetoGrafico Tablero que esté compuesto de varios Rectangulo, o un coche a base de un par de Circulo-Rueda y alguna cosa más.

La idea importante que pretendo transmitir con estos tres artículos es símplemente que fijándose en como se hacen las cosas en la API de java, podemos aprender mucho sobre cómo hacer nuestros programas orientados a objetos, cómo se deberian organizar las clases para obtener cosas flexibles, modulares, ampliables y sobre todo muy reutilizables.

Si nos ponemos a mirar la API, encontraremos miles de ejemplos de casi todos los patrones de diseño y sería de tontos no dedicar un mínimo de atención a estos ejemplos.

Mar 23

Test Continuo

Igual que tenemos integración continua, que básicamente consiste en compilar con frecuencia todo el proyecto desde cero y que hay herramientas que lo hacen automáticmente todos los días, como Cruise Control, también -acabo de descubrir- existe el concepto de test continuo.

Si tenemos unas mínimas buenas costumbres de programación, haremos test unitarios para nuestras clases. Herramientas como Cruise Control y maven se encargan de pasar esos test cada vez que compilamos y nos dicen si hemos o no metido la pata. Pero … ¿por qué no ir más allá?

Acabo de descubrir un plug-in para eclipse -que todavía no he probado, pero lo haré pronto- llamado Continuous Testing Plugin. Tiene pinta de que tú lo instalas en Eclipse, le dices cuales son las clases de test y él, según vas tocando código, va pasando los test de la que eclipse recompila automáticamente. Esto hace que si estropeas un test tocando código, te enteres inmediatamente.

Este mismo Lunes lo pruebo en el trabajo, aunque me da un poco de miedo que ralentice mucho eclipse.

Mar 16

Omondo y PMD

Omondo es un plugin de eclipse para poder dibujar UML. PMD es un plugin de eclipse para ver las métricas de nuestro código.

Ambos tienen muy buena pinta y parecen plugins en serio y bastante pontentes. Los he probado ambos y he tenido que desinstalar ambos.

Como ya comenté en otras ocasiones, trabajo en proyectos muy grandes, de cerca de cinco o seis mil clases. Por supuesto, están repartidas en varios subproyectos de eclipse, interdependientes entre sí. Habitualmente tengo eclipse abierto con entre diez y quince proyectos, de varios centeneres de clase cada uno de ellos.

Omondo hace que eclipse tarde en arrancarse lo indecible. Según abres eclipse, se debe poner a revisar todas las clases para sus diagramas. Para cada proyecto te saca un aviso que debes cerrar. Resulta que al final, una vez abierto, eclipse se queda pillado unos minutos revisando diagramas y además debes estar pendiente para ir cerrando esos avisos. Si te vas a tomar un café mientras abre, se queda parado en el aviso y no continúa.

En cuanto a PMD le pasa algo parecido pero de otra manera. Mientras no lo usas, va todo bien como siempre. Pero si le pones que se ponga a medir las métricas de los ficheros, hace que eclipse se vuelva lento e inmanejable.

Así que para UML tendré que buscar otra herramienta y PMD lo paso actualmente con maven, de forma que en cada compilado me genera el informe de métricas.