lunes, febrero 11, 2013

Como construir el url jdbc para una BD DB2-AS/400

La base de datos relacional AS/400 tiene sus peculiaridades, a diferencia de otras BD que se instalan sobre un sistema operativo en el servidor o ambiente, DB2-AS/400 viene integrada con este. El sistema es conocido como OS400, iSeries, i5 o simplemente AS/400. Al estar integrada la BD almacena la informacion directamente en el sistema de archivos, una tabla es un archivo fisico, una vista es un archivo logico, un esquema es una libreria, etc.

Estos detalles hacen que los url de conexion cuando usamos JDBC tengan su sintaxis especifica, por ejemplo si queremos que el datasource se conecte a un esquema por default la sintaxis es la siguiente:

jdbc:as400:<host>:naming=sql;libraries=<lib1>,<lib2>,...

Al especificar naming=sql se indica que se usaran "." para separar los nombres de los objetos, si se utiliza naming=system entonces se debera utilizar "/" para separar los nombres de objetos.

El url anterior tomara la primera libreria como el esquema por default, ignorando los demas para la busqueda de objectos (tablas, vistas, etc), si lo que se desea es usar varias librerias a la vez se tiene que usar un url como el siguiente:

jdbc:as400:<host>:naming=sql;libraries=,<lib1>,<lib2>,...

Es importante la coma al inicio de libraries, esto indica que no hay una libreria por default y cargara todas las librerias en la conexion.

Otra forma es utilizar un wildcard de la siguiente manera:

jdbc:as400:<host>:naming=sql;libraries=*LIBL,<lib1>,<lib2>,... 

A diferencia del anterior, este ultimo tomara como default schema la segunda en la lista en este caso lib1, pero a la vez cargara las demas librerias en la conexion.

Espero que sea de utilidad :)


jueves, enero 24, 2013

Removiendo dependencias Maven no necesarias, de proyecto Spring generado con ROO

En mi actual proyecto tenemos una aplicacion que fue generada con Spring Roo, despues removimos Rooya que no planeamos usarlo como framework. El proyecto es en si un REST API por lo cual no necesitamos tener vistas, utiliza Spring MVC para asociar los controladores con los REST services usando las caracteristicas out of the box de Spring MVC.

Sin embargo al momento de crear el proyecto en Roo viene toda la serie de dependencias que se usarian en una aplicacion estandar web con UI, en mi caso la aplicacion ocupaba 48.6 MB de espacio en disco. Decidi dar una limpieza a las dependencias maven, para conseguir finalmente un espacio en disco de 34 MB osea 14.6 MB de diferencia.

Estoy usando Spring 3.1.1, Spring Roo 1.2.2

Una herramienta util para localizar las dependencias es el comando:  

mvn dependency:tree

Este comando inspecciona el proyecto y construye un arbol de dependencias de los jars configurados el el pom.xml, al ejecutarlo se ve algo como lo siguiente:

[INFO] +- junit:junit:jar:4.10:test
[INFO] |  \- org.hamcrest:hamcrest-core:jar:1.1:test
[INFO] +- log4j:log4j:jar:1.2.16:compile
[INFO] +- org.slf4j:slf4j-api:jar:1.6.4:compile
[INFO] +- org.slf4j:jcl-over-slf4j:jar:1.6.4:compile
[INFO] +- org.slf4j:slf4j-log4j12:jar:1.6.4:compile
[INFO] +- org.aspectj:aspectjrt:jar:1.7.0.RC1:compile
[INFO] +- org.aspectj:aspectjweaver:jar:1.7.0.RC1:compile
[INFO] +- javax.servlet:servlet-api:jar:2.5:provided
...
[INFO] +- org.apache.tiles:tiles-jsp:jar:2.2.2:compile
[INFO] |  +- org.apache.tiles:tiles-servlet:jar:2.2.2:compile
[INFO] |  |  \- org.apache.tiles:tiles-core:jar:2.2.2:compile
[INFO] |  \- org.apache.tiles:tiles-template:jar:2.2.2:compile
[INFO] |     \- org.apache.tiles:tiles-api:jar:2.2.2:compile
[INFO] \- org.codehaus.jackson:jackson-mapper-asl:jar:1.9.11:compile
[INFO]    \- org.codehaus.jackson:jackson-core-asl:jar:1.9.11:compile

Las dependencias que encontre que en mi caso no son requeridas para crear un REST API y que removi de mi pom son las siguientes:

POM.xml

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj.version}</version>
        </dependency>

        <dependency>
            <groupId>net.sf.flexjson</groupId>
            <artifactId>flexjson</artifactId>
            <version>2.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.roo</groupId>
            <artifactId>org.springframework.roo.annotations</artifactId>
            <version>${roo.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.webflow</groupId>
            <artifactId>spring-js-resources</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>jstl-impl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>el-api</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>1.6</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>

    <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-jsp</artifactId>
            <version>2.2.2</version>
        </dependency>

Ademas removi el siguiente plugin:

    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
    ...

Tambien hay que editar el archivo webmvc-config.xml y quitar la configuracion del view resolver que apunta a tiles:

webmvc-config.xml

<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="tilesViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
  </bean>
    <bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" id="tilesConfigurer">
    <property name="definitions">
      <list>
        <value>/WEB-INF/layouts/layouts.xml</value>
<!--        Scan views directory for Tiles configurations -->
        <value>/WEB-INF/views/**/views.xml</value>
      </list>
    </property>
  </bean>

 Ademas ya no es necesario usar aspectj para el manejo de transacciones, asi que podemos remover mode="aspectj" en el archivo: applicationContext.xml de la siguiente linea de codigo:

applicationContext.xml

<t:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>

Quedando de la siguiente manera:

 <tx:annotation-driven transaction-manager="transactionManager"/>

Espero que esto sea de utilidad a otras personas con un caso similar.




miércoles, enero 16, 2013

Spring MVC / Jackson : como ignorar bean metadata y otras propiedades

Estaba tratando de usar jackson en mi proyecto actual con Spring MVC 3, tengo un metodo en el controlador parecido al siguiente:

@Controller
@RequestMapping("/usuario")
public class UsuarioController {

    @Autowired
    private GenericResponse genericResponse;

    @RequestMapping(value = "/{nombre}", method = GET)
    public @ResponseBody GenericResponse regresaDatos(@PathVariable String nombre) {
        try {
            genericResponse.setData(servicio.getDatos(nombre));
        }
       
        catch(Exception e) {
            genericResponse.setMessage("Error al obtener datos");
        }
       
        return genericResponse;
    }

La clase GenericResponse

public class GenericResponse {
    private String message;
    private IWrapper data;
   ...
    setters y getters aqui
    ...
}

Cuando utilizas Jackson con spring mvc y la anotacion @ResponseBody en el retorno de un metodo, jackson convertira el retorno del metodo a JSON

El problema es que el objeto genericResponse es un proxy bean con scope request:

    <bean id="genericResponse" class="com.mycompany.common.GenericResponse" scope="request">
        <aop:scoped-proxy />
    </bean>

Esto implica que Spring agrega al proxy infinidad de propiedades y metadatos que Jackson intenta convertir a JSON tambien, como eso no es lo que quiero me puse a investigar como evitar que Jackson convierta las propiedades no deseadas.

La solucion es agregar las siguientes anotaciones en la clase GenericResponse:

@JsonIgnoreProperties({"proxyTargetClass", "exposeProxy", "frozen", "preFiltered"})
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE)
public class ErrorResponse {
    private String message;
    private IWrapper data;

    @JsonProperty
    public String getMessage() {
        return message;
    }
   
    public void setMessage(String message) {
        this.message = message;
    }


    @JsonProperty    
    public IWrapper getData() {
        return data;
    }
   
    public void setData(IWrapper data) {
        this.data = data;
    }
}

Con esto Jackson convierte el objeto a JSON de la manera esperada.

viernes, noviembre 23, 2012

Stubbing void methods con mockito

Usando este interesante framework para crear mocks the objetos en Java (muy util si usas TDD) me di cuenta que los metodos para hacer mock de metodos no funcionan con los metodos void. He aqui la forma de hacerlo:

doNothing().when(<objeto>).<metodo>(<argumentos>);

Asi por ejemplo si tenemos un objecto llamado usuario1 y queremos hacer mock de la siguiente llamada al metodo void cambiaPassword(String password):

usuario1.cambiaPassword(nuevoPassword);

Lo hariamos de la siguiente manera:

doNothing().when(usuario1).cambiaPassword(nuevoPassword);

viernes, octubre 26, 2012

Generar hash encriptados en Mac OS X y otros UNIX

Tan solo hay que usar el siguiente comando:
echo -n <palabra> | openssl dgst -<algoritmo>

Algunos algoritmos soportados son los siguientes:

-md5            
-md4         
-md2          
-sha1          
-sha          
-sha224       
-sha256       
-sha384     
-sha512         

Por ejemplo:

$ echo -n pollo | openssl dgst -sha256
359ee8d482d3cac0fdffb2b83df30b9aabb2f265896ec61f93bbc94d77115a67

lunes, junio 18, 2012

Diagrama del SimpleFormController de Spring MVC

Como sabemos el Framework Spring es un tanto complejo, mas aun el modulo MVC. Aqui les comparto la liga a un blog donde su autor ha realizado un Flowchart del ciclo de vida del SimpleFormController, es bastante util para saber como funciona MVC.



domingo, marzo 04, 2012

Como editar Groovy Server Pages (GSP) con Dreamweaver CS5

Actualmente Dreamweaver CS5 no reconoce los archivos con extensión GSP (Groovy Server Pages) los cuales se utilizan mucho cuando desarrollas aplicaciones con Grails (son los equivalentes a los JSP de las aplicaciones Java tradicionales), esto provoca que no se reconozcan los tags GSP y pues el diseño en algunas ocasiones se vuelve imposible.

Estuve leyendo 2 artículos en los que resuelven esto, dichos artículos están en inglés así que se me ocurrió realizar una traducción aunque con algunas modificaciones basadas en lo que a mi me funcionó.

Los links a los artículos: article1, article2.

Aquí lo que hice:

1. Agregar la extensión .gsp para que sea reconocida por el editor del Dreamweaver, para ello hay que editar los siguientes archivos:

<Directorio de Instalacion de Dreamweaver>\configuration\Extensions.txt
<Directorio de Datos de la aplicación>\en_US\configuration\Extensions.txt

En mi caso:
C:\Archivos de programa\Adobe\Adobe Dreamweaver CS5\configuration\Extensions.txt
C:\Documents and Settings\Ramiro\Datos de programa\Adobe\Dreamweaver CS5\en_US\Configuration\Extensions.txt

a) Agregar en la primera línea justo antes del texto :All Documents el texto GSP, es decir la primera linea debe de quedar de la siguiente manera:

...,GSP:All Documents

Donde obviamente los puntos suspensivos ... indican que simplemente agregué la palabra ,GSP a lo que ya había en la línea antes de la palabra :All Documents

b) Agregar al final de ese mismo archivo la linea:
GSP:Groovy Server Pages

Al guardar este archivo ya quedó configurado el Dreamweaver para reconocer la extensión como un documento de formato válido para editar, sin embargo todavía no reconocerá los tags GSP que es el objectivo principal.

2. Ahora hay que configurar el Dreamweaver para que le de significado a los GSP

Hay que editar un archivo xml que se encuentran en la siguiente ruta:

<Directorio de Instalacion de Dreamweaver>\configuration\DocumentTypes\MMDocumentTypes.xml

En mi caso:
C:\Archivos de programa\Adobe\Adobe Dreamweaver CS5\configuration\DocumentTypes\MMDocumentTypes.xml

Agregamos el siguiente nodo xml al final dentro del contenido del nodo <documenttypes>

    <documenttype id="GSP" servermodel="JSP" internaltype="Dynamic" winfileextension="gsp" macfileextension="gsp" file="Default.gsp" writebyteordermark="false" mimetype="text/html">
        <TITLE>GSP</TITLE>
        <description>Groovy Server Pages (GSP) document</description>
        <dtdcontext>html</dtdcontext>
    </documenttype>

 Con esto Dreamweaver entenderá de que se tratan estos archivos.

3. Crear un template para nuevos archivos GSP

Para que al crear un nuevo archivo aparezca un template por defecto, simplemente hay que crear un archivo llamado en la siguiente ruta:

<Directorio de Instalacion de Dreamweaver>\configuration\DocumentTypes\NewDocuments\Default.gsp

En mi caso:
C:\Archivos de programa\Adobe\Adobe Dreamweaver CS5\configuration\DocumentTypes\NewDocuments\Default.gsp

Como un gsp es en si un html dinámico podemos usar el mismo template que tienen los archivo html (o puedes crearlo a tu gusto), entonces puedes simplemente copiar el archivo Default.html que está en el mismo directorio poniéndole el nombre Default.gsp.

4. Importar el tag library de GSP

Este es el punto más importante, pues es el que hace que el Dreamweaver no tome erroneamente los tags GSP, para esto hay que descargar el tag library para Dreamweaver desde el siguiente link: GSPTagLibrary el cual es un zip.

a) Dentro del zip hay una carpeta llamada gsp, hay que copiarla al directorio:

<Directorio de Instalacion de Dreamweaver>\configuration\TagLibraries


En mi caso:

C:\Archivos de programa\Adobe\Adobe Dreamweaver CS5\configuration\TagLibraries


b) Editar el archivo xml <Directorio de Instalacion de Dreamweaver>\configuration\TagLibraries\TagLibraries.vtm

Hay que agregar el contenido del archivo gspTagLibrary.vtm que se encuentra dentro del zip, este archivo contiene un nodo xml llamado taglibrary el cual pondremos como último nodo dentro del tag <taglibraries> del archivo TagLibraries.vtm que estamos editando.

Una vez agregado hay que sustituir la siguiente línea:

 <taglibrary name="GSP" doctypes="HTML,JSP,GSP" id="DWTagLibrary_GSP" prefix="&lt;g:">

por la línea:

 <taglibrary name="GSP tags" doctypes="GSP" id="DWTagLibrary_GSP" prefix="&lt;g:">

Después localiza en el mismo archivo TagLibraries.vtm que estás editando un nodo <taglibrary> que tenga el siguiente atributo: id="DWTagLibrary_html", en este nodo hay que agregar el texto GSP en el atributo doctypes

5. Habilitar la función de colorear sintaxis para los tags GSP

En los archivos

<Directorio de Instalacion de Dreamweaver>\configuration\CodeColoring\CodeColoring.xml
<Directorio de Datos de la aplicación>\en_US\configuration\CodeColoring\CodeColoring.xml

 En mi caso son:

C:\Archivos de programa\Adobe\Adobe Dreamweaver CS5\configuration\CodeColoring\CodeColoring.xml
C:\Documents and Settings\Ramiro\Datos de programa\Adobe\Dreamweaver CS5\en_US\Configuration\CodeColoring\CodeColoring.xml

a) Hay que reemplazar el texto ,JSP, por ,JSP,GSP, incluyendo las comas
b) Reemplazar la línea: 
<sampleText doctypes="JSP,GSP">
por la línea:
<sampleText doctypes="JSP,GSP">

Y listo, ya puedes trabajar con tus GSP normalmente en Dreamweaver