domingo, 26 de agosto de 2012

PMD: 'MEJORA DE CÓDIGO JAVA'


En esta oportunidad mostraré el manejo de una muy buena herramienta para la validación y mejora de código JAVA llamada PMD.

PMD es una herramienta que comprueba que nuestra aplicación cumpla una serie de reglas que nos ayudan a obtener un código más elegante, sencillo y mantenible. Estas reglas se agrupan por conjuntos y pueden ser reglas de complejidad, como que la complejidad ciclomática no sea demasiado alta; de diseño, como no usar interfaces como meros contenedores de constantes; de optimización, como procurar usar ArrayList en lugar de Vector; etc.

PMD se puede utilizar desde linea de comandos, o puede integrarse con multitud de IDEs y herramientas, como Eclipse, NetBeans, Maven o JEdit. Y aunque algunos de los casos que comprueba PMD ya se tengan en cuenta en Eclipse, sigue siendo una utilidad muy interesante para añadir a nuestra caja de herramientas.

El ejemplo mostrado detalla el manejo paso a paso de esta herramienta tanto para las IDEsEclipse, JDeveloper.

Para descargar el tutorial dar click:  AQUI

Para descargar las fuentes ECLIPSE del tutorial, dar click: AQUI

Para descargar las fuentes JDEVELOPER del tutorial, dar click: AQUI


Saludos.




FINDBUGs: 'MEJORA DE CÓDIGO JAVA'



En esta oportunidad mostraré el manejo de manera EXTERNA y como PLUGIN de una muy buena herramienta para la validación y mejora de código JAVA llamada FINDBUGS

FINDBUGS es un programa de tipo código abierto creado por William Pugh que busca errores en programas escritos en código Java. Utiliza análisis estático para identificar cientos de tipos de errores potenciales en programas Java. FINDBUGS opera en Java ByteCode, en lugar de por código fuente.

El ejemplo mostrado detalla el manejo paso a paso ya se por PLUGIN y EXTERNA (independientemente de la IDE: Eclipse, JDeveloper, etc):

Para descargar el tutorial dar click:  AQUI

Para descargar las fuentes ECLIPSE del tutorial, dar click: AQUI

Para descargar las fuentes JDEVELOPER del tutorial, dar click: AQUI


Saludos.

martes, 21 de agosto de 2012

MAPPING 'JMS' & 'MDP' CON 'SPRING3'


En esta oportunidad mostraré como realizar un Mapping mediante SPRING, para el manejo de lanzamiento de mensajes 'JMS' y para su respectiva recepción de dichos mensajes 'JMS' mediante 'MDP' (Message Driven Pojos).

El mapping mostrado a continuación hace referencia al manejo de dos colas JMS para ello es requerido crea lo siguiente:
  • 1  JNDI TEMPLATE
  • JNDI FACTORY
  • JDNI DESTINATION RESOLVER
  • JDNI DESTINATION (por cada cola)
  • JMS TEMPLATE
Y para la recepción del mensaje JMS se deberá crear:
  • JMS MDP
  • JMS LISTENER
(Para fines del ejemplo, se ha cambiado LLAVES por CORCHETES):

[?xml version="1.0" encoding="UTF-8" ?]
[beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd
      http://www.springframework.org/schema/jee
      http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
      http://www.springframework.org/schema/util
      http://www.springframework.org/schema/util/spring-util-3.0.xsd" ]
        
    [!-- ************** [JNDI TEMPLATE] ************** --]            
    [bean id="idTemplateJDNI" 
          class="org.springframework.jndi.JndiTemplate" ]
     [property name="environment" ] 
         [props]
             [prop key="java.naming.factory.initial" ]weblogic.jndi.WLInitialContextFactory[/prop]
             [prop key="java.naming.provider.url" ]t3://localhost:7001[/prop]
         [/props]
     [/property]
    [/bean]    
    
    [!-- **************** [JNDI FACTORY] *************** --]     
    [bean id="idConnectionFactoryJDNI" 
          class="org.springframework.jndi.JndiObjectFactoryBean" ]
          [property name="jndiTemplate"        ref="idTemplateJDNI" /]
          [property name="lookupOnStartup" value="false" /]
  [property name="cache"                 value="true" /]
          [property name="jndiName"            value="dummy.javaman.jms.factory" /]
          [property name="proxyInterface"     value="javax.jms.ConnectionFactory" /]
    [/bean]
        
    [!-- ********* [JDNI DESTINATION RESOLVER] ********* --]  
    [bean id="idDestinationResolverJNDI"
          class="org.springframework.jms.support.destination.JndiDestinationResolver" ]
          [property name="jndiTemplate" ref="idTemplateJDNI" /]
          [property name="cache"           value="true" /]
    [/bean]    
    
    [!-- ************* [JDNI DESTINATION] ************** --]      
    [bean id="idDestination_01"
          class="org.springframework.jndi.JndiObjectFactoryBean" ]
          [property name="jndiName" value="jms.jndi.queue" /]
    [/bean]
    
    [bean id="idDestination_02"
          class="org.springframework.jndi.JndiObjectFactoryBean" ]
          [property name="jndiName" value="jms.jndi.auxiliar" /]
    [/bean]
        
    [!-- **************** [JMS TEMPLATE] *************** --]     
    [bean id="idTemplateJMS_01" 
          class="org.springframework.jms.core.JmsTemplate" ]
          [property name="connectionFactory"          ref="idConnectionFactoryJDNI" /]
          [property name="destinationResolver"        ref="idDestinationResolverJNDI" /]
          [property name="defaultDestination"          ref="idDestination_01" /]      [!-- COLA #1 --]
          [property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE" /]
          [property name="sessionTransacted"         value="true" /]
    [/bean]    
   
    [bean id="idTemplateJMS_02" 
          class="org.springframework.jms.core.JmsTemplate" ]
          [property name="connectionFactory"          ref="idConnectionFactoryJDNI" /]
          [property name="destinationResolver"        ref="idDestinationResolverJNDI" /]
          [property name="defaultDestination"          ref="idDestination_02" /]      [!-- COLA #2 --]
          [property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE" /]
          [property name="sessionTransacted"        value="true" /]
    [/bean]
    
 [!-- ****************** [JMS MDP] ****************** --]  
[bean id="idClaseJmsMessageListener_01"
     class="pe.com.javaman.dummy.servicioLlamadasWS.jms.ServicioLlamadasMDP_A" ]  [!-- PARA RECEPCIÓN [ASINCRONA] DE LA COLA --]   
[/bean] 
   
[bean id="idClaseJmsMessageListener_02"
     class="pe.com.javaman.dummy.servicioLlamadasWS.jms.ServicioLlamadasMDP_B" ]  [!-- PARA RECEPCIÓN [ASINCRONA] DE LA COLA --]   
[/bean] 
   
 [!-- **************** [JMS LISTENER] *************** --]      
[bean id="idListenerJMS_01" 
     class="org.springframework.jms.listener.SimpleMessageListenerContainer" ]
     [property name="connectionFactory" ref="idConnectionFactoryJDNI" /]
     [property name="destination"            ref="idDestination_01" /]                 [!-- COLA #1 --]
     [property name="messageListener"   ref="idClaseJmsMessageListener_01" /]
[/bean] 
    
[bean id="idListenerJMS_02" 
     class="org.springframework.jms.listener.SimpleMessageListenerContainer" ]
     [property name="connectionFactory" ref="idConnectionFactoryJDNI" /]
     [property name="destination"            ref="idDestination_02" /]                 [!-- COLA #2 --]
     [property name="messageListener"   ref="idClaseJmsMessageListener_02" /]
[/bean]                                
 [/beans]  

Esto sería todo nos vemos.


MAPPING PROXY 'JAXWS' CON 'SPRING3'


En esta oportunidad mostraré como trabajar con PROXY Client con JAXWS usando SPRING 3.

Todos sabemos que cuando uno crea un PROXY Client con JAXWS y lo encapsula en un .jar, se puede realizar de 2 formas: 

1. En base la URL del servicio desplegado.
2. En base al .WSDL en físico en un ruta especifica.

Al realizar cualquier de estos 2 pasos, se genera una dependencia internamente dentro del .jar, ya sea de la ruta absoluta del .WSDL o bien de la URL de la cual se genero el .jar. 

Este es un gran problema por eso es que, en este caso, SPRING entra a solucionar dicho problema y muchos más. Ya que dentro de sus mappings XML setea y asocia: targetNamespace, service, EndPoint, etc, por c/u de los Servicios Web los cuales consumiremos.

En mapping aplicado es el siguiente:

En mi caso yo segmento toda la logica para el manejo de WS en un XML separado del ApplicationContext, llamado:  applicationProxyWs.xml:


(Para fines del ejemplo, se ha cambiado LLAVES por CORCHETES):

[?xml version="1.0" encoding="UTF-8" ?]
[beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:context="http://www.springframework.org/schema/context" 
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:ws="http://jax-ws.dev.java.net/spring/core" 
       xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
       xmlns:oxm="http://www.springframework.org/schema/oxm" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context-3.0.xsd
                           http://www.springframework.org/schema/task
                           http://www.springframework.org/schema/task/spring-task-3.0.xsd
                           http://www.springframework.org/schema/aop  
                           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
                           http://www.springframework.org/schema/context  
                           http://www.springframework.org/schema/context/spring-context-3.0.xsd
                           http://www.springframework.org/schema/jee
                           http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
                           http://www.springframework.org/schema/util
                           http://www.springframework.org/schema/util/spring-util-3.0.xsd
                           http://jax-ws.dev.java.net/spring/core
                           http://jax-ws.dev.java.net/spring/core.xsd
                           http://jax-ws.dev.java.net/spring/servlet
                           http://jax-ws.dev.java.net/spring/servlet.xsd" ]
                            
      [util:map id="jaxwsCustomProperties" ] 
        [entry key="com.sun.xml.ws.request.timeout" ]  
               [value type="java.lang.Integer" ]1500[/value] 
        [/entry]
        [entry key="com.sun.xml.ws.connect.timeout" ] 
               [value type="java.lang.Integer" ]1500[/value] 
        [/entry]
      [/util:map]
        
    [bean id="ObtenerDatosService"  class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean" ]
            [property name="wsdlDocumentUrl"  value="http://localhost:8088/mockObtenerDatosBinding?wsdl" /]                  
            [property name="namespaceUri"     value="http://pe.com.externalCompany/bean/ObtenerDatosWS" /]                 
            [property name="serviceName"      value="ObtenerDatosService" /]                                               
            [property name="portName"         value="ObtenerDatosPort" /]                                                  
            [property name="serviceInterface" value="externalcompany.com.pe.bean.obtenerdatosws.ObtenerDatosPortType" /]   
       [property name="customProperties" ]
           [ref local="jaxwsCustomProperties" /]                                                                           
       [/property]                                            
      [/bean]      
      [bean id="ObtenerTecnologiaService"class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean" ]
         [property name="wsdlDocumentUrl"  value="http://localhost:8088/mockObtenerTecnologiaBinding?wsdl" /]                        
         [property name="namespaceUri"     value="http://pe.com.externalCompany/bean/ObtenerTecnologiaWS" /]                      
            [property name="serviceName"    value="ObtenerTecnologiaService" /]
 [property name="portName"         value="ObtenerTecnologiaPort" /]   
 [property name="serviceInterface" value="externalcompany.com.pe.bean.obtenertecnologiaws.ObtenerTecnologiaPortType" /] 
[property name="customProperties" ] 
      [ref local="jaxwsCustomProperties" /] 
[/property] 
[/bean] 
[/beans]
La obtención y configuración de los datos de cada property lo sacamos de la misma URL de cada WebService de esta manera:
  • wsdlDocumentUrl           =>  [URL] 
  • namespaceUri                =>  [wsdl:definitions targetNamespace='XXXX'] 
  • serviceName                  =>  [wsdl:service name='XXX'] 
  • portName                       =>  [wsdl:port name='XXX'] 
  • serviceInterface              =>  [public interface XXX] 
  • jaxwsCustomProperties  =>  [PROPERTIES] en milisegundos 
Es todo saludos.   

domingo, 19 de agosto de 2012

MANEJO FRAMEWORK: "EHCACHE".



En esta oportunidad mostraré el manejo de  uno de los Frameworks más utilizados para el Cache de Objetos Java. Su nombre es: EHCACHE.
En general, EHCACHE consta de "regiones de cache" dentro de la aplicación en donde se ubican objetos .JAVA para poder así guardarlos en memoria por un lapsus de tiempo para así reutilizar la información guardada en ella. Estas regiones se configuran en clases .JAVA o en un archivo XML (preferible), para determinar el tiempo de expiación, cantidad máxima de elementos, tiempo, etc.
El compartido muestra una interfaz LOGIN que se conecta a un BD en MYSQL (Script dentro del APP) desplegado sobre un TOMCAT. La configuración de EHCACHE aplicada en el XML (ehCache.xml), es de 30 segundos pero la puedes configurar a tu gusto. En ese lapsus de tiempo la informaron guardada en CACHE se repetirá todas las veces que se consulte hasta pasado el tiempo configurado en dicho fichero XML. 

    maxElementsInMemory = "500" 
    eternal             = "false"
  overflowToDisk      = "false" 
  timeToIdleSeconds   = "30" 
  timeToLiveSeconds   = "30" />
Se comparten 2 versiones del DUMMY. Uno versión J2EE normal y el otro versión J2EE aplicado con MAVEN.
Para descargar el ejemplo completo pulsar:  AQUÍ   

sábado, 18 de agosto de 2012

CREACIÓN DE "WEBSERVICE" BASADO EN "JAXWS" DESDE "ECLIPSE"


En este tutorial se mostrará la creación de WebService apoyándose en el Framework JAXWS a modo TopDown (desde la Interface .wsdl) todo desde la ide “ECLIPSE”, específicamente usando: SpringSourceToolSuite v2.9.2, y como servidor de aplicaciones el: ORACLE WEBLOGIC Asumiremos que la interface .wsdl, ya se tiene creada.

Todo el tutorial en detalle se ha especificado en un documento word.

Para descargar el tutorial paso a paso, dar click: AQUI





APLICACIÓN DE "TIMEOUT" EN "PROXY CLIENT" CON "AXIS 1.4"

En esta oportunidad mostraré algo muy requerido y necesario cuando se consumen WebService, a lo que me refiero es a la aplicación de los famosos TIMEOUT control de cada WebService consumido por medio de lo "Proxy Client" generados.

En esta oportunidad mostraré el manejo de dicho TimeOut por medio del FrameWork AXIS 1.4, un FrameWork no tan power como JaxWS pero que buen y aun muy usado en el mercado mundial.

Aquí muestro el contenido completo de la clase JAVA: TestProxyAxis1 , en donde limplemento el Cliente que consume un supuesto WebService: http://localhost:7001/ObtenerTecnologiaWS/ObtenerTecnologiaService?wsdl, al cual se le envía un numero telefónico y este responde con el tipo de Tecnología (El WS no es parte de este ejemplo planteado). Se debe de suponer que previamente uno ya ha tenido que crear el "Proxy Client" (.jar), para poder consumir el Servicio Web.

EJEMPLO:

import java.net.SocketTimeoutException;
import java.net.URL;
import javax.xml.rpc.ServiceException;
import org.apache.axis.AxisFault;
import externalCompany.com.pe.bean.ObtenerTecnologiaRequest;
import externalCompany.com.pe.bean.ObtenerTecnologiaResponse;
import externalCompany.com.pe.bean.TransaccionBean;
import externalCompany.com.pe.bean.ObtenerTecnologiaWS.ObtenerTecnologiaBindingStub;
import externalCompany.com.pe.bean.ObtenerTecnologiaWS.ObtenerTecnologiaInput;
import externalCompany.com.pe.bean.ObtenerTecnologiaWS.ObtenerTecnologiaOutput;
import externalCompany.com.pe.bean.ObtenerTecnologiaWS.ObtenerTecnologiaServiceLocator;

/**
 * @author cguerra.
 * @clase: TestProxyAxis1.java 
 * @author_company: nombre de la compañía del autor.
 * @fecha_de_creación: dd-mm-yyyy.
 * @fecha_de_ultima_actualización: dd-mm-yyyy.
 * @versión 1.0
 */
 public class TestProxyAxis1{

   /**
    * @param argumentos
    */
    public static void main( String ... argumentos ){

        String URL_ENDPOINT = "http://localhost:7001/ObtenerTecnologiaWS/ObtenerTecnologiaService?wsdl";
       
        ObtenerTecnologiaServiceLocator objLocator = null;
        ObtenerTecnologiaBindingStub      objBinding = null;
       
        ObtenerTecnologiaInput          objInput    = null;
        ObtenerTecnologiaRequest    objRequest  = null;
        ObtenerTecnologiaOutput       objOutput   = null;
        ObtenerTecnologiaResponse objResponse = null;
       
        try{
            objLocator = new ObtenerTecnologiaServiceLocator();
            objBinding = (ObtenerTecnologiaBindingStub)objLocator.getObtenerTecnologiaPort( new URL( URL_ENDPOINT ) );
           
            //TIMEOUT:
            setTimeOutWS( objBinding );
           
            objInput          = new ObtenerTecnologiaInput();            
            objRequest    = new ObtenerTecnologiaRequest();   
            objOutput       = new ObtenerTecnologiaOutput();
            objResponse  = new ObtenerTecnologiaResponse();
                                   
            objInput.setParam_Request( objRequest );
                       
            //INPUT:
            objRequest.setTelefono( "52148652" );
            objInput.setParam_Request( objRequest );           
           
            //WEBSERVICE:
            objOutput      = objBinding.obtenerTecnologia( objInput );           
            objResponse = objOutput.getParam_Response();
           
            //OUTPUT:
            String          tecnologia       = objResponse.getTecnologia();
            TransaccionBean objTransaccionBean = objResponse.getTransaccionBean();
            String          codigo             = objTransaccionBean.getCodigo();
            String          mensaje          = objTransaccionBean.getMensaje();
           
            System.out.println( "- TECNOLOGIA: " + tecnologia );
            System.out.println( "- CODIGO:     " + codigo  );
            System.out.println( "- MENSAJE:    " + mensaje );
        }
        catch( ServiceException e ){
               System.out.println( "ERROR:[ServiceException] " + e );
        }
        catch( AxisFault e ){
               System.out.println( "ERROR:[AxisFault] " + e );
        }
        catch( Exception e ){
               System.out.println( "ERROR:[Exception] " + e );
        }
    }
   
   /**
    * setTimeOutWS   
    * @param  objBinding
    * @throws Exception
    */
    public static void setTimeOutWS( ObtenerTecnologiaBindingStub objBinding ) throws Exception{ 
       
        try{
            javax.xml.rpc.Stub          objStub_RPC  = (javax.xml.rpc.Stub)objBinding;        
            org.apache.axis.client.Stub  objStub_AXIS = (org.apache.axis.client.Stub)objBinding;
           
            int timeOut = (5 * 1000);  //5 segundos
            
            //----- FORMA #1: -----//
            objStub_RPC._setProperty( "axis.connection.timeout", timeOut );
           
            //----- FORMA #2: -----//
            objStub_AXIS.setTimeout( timeOut );
           
            //----- FORMA #3: -----//       
            objBinding._setProperty( org.apache.axis.client.Call.CONNECTION_TIMEOUT_PROPERTY, timeOut ); 
        }
        catch( Exception e ){
               throw new SocketTimeoutException();
        }       
    }
   
}

El método:  setTimeOutWS recibe solo el Binding y es reutilizado para desde cualquier lugar aplicar un TIMEOUT de 3 formas distintas (uno ya escoge cual de ellas usar).

Saludos.