Empece este blog para guardar los descubrimientos en programacion que hago cuando tengo un error y por mas que busco en san Google, no encuentro nada hasta despues de horas de andar buscando y horas de prueba y error. Si a alguien algun dia le sirve, que bueno. En general es para mi porque se me olvidan muchos de estos descubrimientos.

Friday, May 31, 2013

Error Rosetta Stone v3

Se que esto no es de programacion, pero necesitare acordarme de esto y los marcadores siempre se me pierden.

El Rosetta Stone V3 esta dando un error cuando no se actualizo correctamente.
El link de la solucion esta aqui.

Instrucciones en español:
  • Encuentra el siguiente archivo (Para Windows 7 esta en C:\programData\Rosetta Stone\tracking.db3 (Carpetas ocultas) y renombralo a  tracking.db3.bak
    1. Reinicia la maquina.
    2. Inicia el Rosetta Stone (tu progreso se habra perdido. Lo siento)
    3. Cierra el Rosetta.
    4. Renombra el tracking.db3.bak otra vez a tracking.db3 (A mi me habia salido un nuevo tracking.db3. Borre este y renombre el viejo)
    5. Vuelve abrir el Rosetta y disfruta poder usarlo nuevamente. 
    :)

    Errores comunes en Clientes de Webservices generados con Axis

    Generar un cliente para consumir un servicio, debería de ser tan fácil como generarlo.. consumirlo... me funciona y ya.
    Pero a todos los que nos ha tocado, consumir servicios, nos hemos dado cuenta que no siempre es así. Se nos pueden generar muchos problemas, que muchas veces son muy sencillos de solucionar, y en los que nos ha tocado googlear por largas horas y a prueba y error logramos resolver. Aquí van algunos de esos problemas y como resolverlos:

    1. The message must be an instance of: {http://www.w3.org/2003/05/soap-envelope}Envelope

      Este error lo que nos indica es que la versión de soap que se está usando es distinta, o sea que debemos cambiarlo a la 1.2
      Solución:
      Luego que crean los métodos en su provider, y en el método que consumen deben de agregar lo siguiente en el serviceStub que se les generó:
      Cuando se realiza el Envelope, en el parámetro que se le pasa al getFactory:
             env = toEnvelope(getFactory(_operationClient.getOptions().getSoapVersionURI())
      sustituir el_operationClient.getOptions().getSoapVersionURI() por http://www.w3.org/2003/05/soap-envelope
      Con esto ya se actualiza la versión.

    2. The MessageContext does not have an associated SOAPFault.

      Este error lo que nos indica es que el contexto no tiene un fault asociado, es decir que el servicio está devolviendo un error y el cliente que se nos generó espera que el error venga en un fault; sin embargo el servicio no devuelve un fault.
      Solución:
      En el serviceStub que genero nuestro cliente hay una opción que setea si se devuelve o no un fault, esta se encuentra antes de crear el messageContext, antes del envelope:
             _operationClient.getOptions().setExceptionToBeThrownOnSOAPFault(true);
      Esta debe setearse en false para que ni genere fault, o si nuestro error es al revés, debemos setearla en true.


    3. Nuestro Servicio no tiene Seguridad

      Normalmente los servicios que consumimos tendrán un usuario y password; sin embargo si nos entregan uno sin seguridad.
      Solución:
      No utilizar el rampart que normalmente usamos y comentar esta linea:
               sc.engageModule("rampart");

      Además dentro del serviceStub que se nos generó debemos agregar después de realizar el envelope, del método toEnvelope, estas líneas:
          String url = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
          OMNamespace xsi = getFactory(_operationClient.getOptions().getSoapVersionURI()).createOMNamespace(url, "wsse"); 
          SOAPHeaderBlock soapHeaderBlock =env.getHeader().addHeaderBlock("Security",xsi);                                                  
          soapHeaderBlock.setMustUnderstand("1"); 
          Iterator it = env.getHeader().examineAllHeaderBlocks(); while(it.hasNext()) { SOAPHeaderBlock headerBlock= (SOAPHeaderBlock)it.next();
                        headerBlock.setRole("http://www.w3.org/2003/05/soapenvelope/role/next");

      Estas lo que hacen es agregar un header de seguridad que necesita el servicio para que funcione correctamente.

    Thursday, May 9, 2013

    Haciendo un Case en un Count SQL

    Odio hacer un query que me costo hacer y luego no acordarme como hacerlo.
    Por alguna razon el haber pasado de SQL Server a Oracle me volvio perezosa con los queries. 
    Odio que Oracle no tenga Top! Amaba mi top!

    La vez pasada necesitaba hacer un query con unos counts especiales y google fue de muy poca ayuda. Eso me sorprendio considerando la cantidad de ejemplos de queries en la red. 
    Este query sirve para cuando quieres hacer where distintos para cada count en una misma tabla. 
    Los ejemplos que me daban eran Unions o joins pero yo queria algo simple y limpio.
    He aqui el query que mi compañero me ayudo a sacar:

    Supongamos que tengo un tabla en donde se almacenan diferentes estados. Digamos el estado de un producto donde estado = B es en bodega, T= en tienda, P=pendiente de ingresar a bodega. etc. Yo quiero saber el total de productos por cada estado. 
            select 
                   idproducto, descripcionProducto,
                   count(1) as totalProductos,
                   count(case
                           when (estado != 'B') then
                            1
                         end) as bodega,
                   count(case
                           when (estado != 'T') then
                            1
                         end) as enTienda,
                   count(case
                           when (estado = 'P') then
                            1
                         end) as pendiente
              from productos
             group by Idproducto


    Sencillo, rapido y bonito. 
    Vi ejemplos de If en los parenthesis del count pero no les entendi mucho. Este case es lo mismo y mas comprensible. 
    Bueno, al menos no se me va olvidar para la proxima! 

    Monday, August 27, 2012

    Generando Web Service Cliente con Axis 2 en Soap 1.2

    Pues la vida al fin habia sido color de rosa en la generacion de web service client en axis2 utilizando el metodo de generacion de cliente desde linea de comando encontrado aqui.

    Resulta que los webservices que nos entregan ahora son el Soap 1.2 y estos generaron ciertos problemas.
    No soy experta en generacion de web service clients, menos en Soap 1.2, pero he aqui nuestros problemas encontrados y las soluciones a ellos.
    Honestamente creo y recomiendo que lo ideal es que generes los clientes utilizando el jax-ws. No tengo conocimientos extensos en este tampoco, pero si se que es mas facil la generacion y consumo de estos. Nosotros desafortunadamente por integracion al proyecto no podemos dejar el Axis y si te encuentras en nuestro mismo barco, espero aqui encuentres ayuda.

    La generacion del Cliente se realizo como siempre con la linea de comando y sin necesidad de cambiar nada en el codigo generado.

    Primer Error:

    org.apache.axis2.AxisFault: BEA-382032: The message must be an instance of: {http://www.w3.org/2003/05/soap-envelope}Envelope
    {http://schemas.xmlsoap.org/soap/envelope/}VersionMismatch
    <faultcode>soapenv:VersionMismatch</faultcode>

    Solucion:
    Como el error decia que el problema es que la version que se esta recibiendo el http://schemas.xmlsoap.org/soap/envelope/ y la que esta esperando es http://www.w3.org/2003/05/soap-envelope, se tuvo que poner esta en duro en el stub generado.

    La url que debes cambiar no se encuentra tal cual, aparece como _operationClient.getOptions().getSoapVersionURI() en el metodo toEnvelope. Donde encuestres este metodo de toEnvelop cambia el _operationClient.getOptions().getSoapVersionURI() por  "http://www.w3.org/2003/05/soap-envelope".

    Segundo Error:
    org.apache.axis2.AxisFault: Must Understand check failed for header http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd : Security
    {http://www.w3.org/2003/05/soap-envelope}MustUnderstand
    Solucion:
    Para este investigamos en varias paginas. Un compañero encontro la solucion en la siguiente pagina:
    http://msdn.microsoft.com/en-us/library/ms977327.aspx

    Para corregir el error en los headers por seguridad se hizo lo siguiente en codigo:
    Después de realizar el Envelop (luego del método toEnvelop), deben colocar el siguiente código:

    OMNamespace xsi = getFactory(_operationClient.getOptions().getSoapVersionURI()).
    createOMNamespace(url, "wsse");

    SOAPHeaderBlock soapHeaderBlock =env.getHeader().addHeaderBlock("Security",xsi);                                                  
    soapHeaderBlock.setMustUnderstand("1");

    Iterator it = env.getHeader().examineAllHeaderBlocks(); while(it.hasNext()) { SOAPHeaderBlock headerBlock= (SOAPHeaderBlock)it.next();


    Con estos cambios, todo lo de mas funciono como siempre.

    Saludos.  

    Tuesday, February 14, 2012

    Seteando la Variable JAVA_HOME

    Ok, entonces mis amigos, siguiendo con el tema de los webservices:

    La ultima vez comentaba de como crear el webservice client desde linea de comando. En mi compu no dio ningun problema y corrio a la perfeccion generando las clases del cliente. Al intentar generar las clases de la misma manera en la computadora del compañero nos lanzo un error. (No tengo el error exacto a mano, lo siento)

    El error era: La variable JAVA_HOME no esta seteada o asignada. 

    Pues google no ayudo mucho, probablemente porque todos asumen que deberia saber, pero yo no sabia y mis compañeros tampoco (Si, no estar solo te hace sentir mejor :P)

    Aqui la solucion:
    Clic en windows (si el icono de windows) ------> clic en Computer o Equipo (dependiendo del lenguaje de tu SO) -------> clic en properties o propiedades-----> configuracion avanzada de sistema-----tab de Opciones avanzadas----->clic en variable de entorno---->Busca la Java_home y das doble clic y en valor de la variable escribe la direccion (directory path) de donde tienes instalado tu JDK o JRE y voila!!

    Bueno, a mi me lo explicaron y se me olvido y tuve que volver a preguntar, asi que si llegaste aqui buscando como hacer esto, espero te sirva como me servira a mi!
    Saludos!

    Monday, January 30, 2012

    Web Service clients desde command line

    Webservices, webservices, porque me dificultas tanto la vida? Esta bien, son un reto, son algo nuevo para mi y mantienen las cosas interesantes. Aunque me estoy quejando de webservices y realmente son los clients los que han sido dolores de cabeza. En el pasado escribi un post de como generar clientes en ADB y en xmlBeans con el Axis2 Code Generator Eclipse plugin. Al tener otro problema con estos clientes, tuve que irme por la solucion de clientes generados por linea de comando.

    En general es muy sencillo. Estoy segura que hay mas informacion al respecto pero he aqui lo esencial.

    Descargar las librerias de Axis2. Trata siempre de estar actualizando ya que Axis pasa corrigiendo bugs conocidos que probablemente sean los que te estan dando problemas.

    Abres una consola DOS y navegas hasta llegar al directory donde tienes tus librerias Axis2. Navega hasta la carpeta bin. escribe el siguiente comando:
    WSLD2JAVA -uri http://EndpointDelWebService?wsdl

    Hay mas comandos que puedes agregar a esta sentencia para especificar databinding (ADB es el default en esta generacion tambien), ruta en donde poner las clases generadas, etc. Para mas informacion puedes buscar aqui: http://axis.apache.org/axis2/java/core/docs/reference.html

    Navega en la carpeta bin y copia las tareas generadas (clases JAVA). Copia las clases en algun proyecto donde desees el webclient (En este caso no tenemos problemas poniendolo en un Java Project que te permite usar este .jar para cualquier proyecto que requiera usar ese cliente).

    Siempre requeriras crear clases para consumir las clases generadas. En mi caso siempre necesito un ConectionStud manager y un PasswordCallbackHandler. Las clases son un poco bruscas a mi parecer ya que generan casi todo el codigo en una sola clase, pero si necesitas entrar al codigo para hacer cambios, el codigo generado es un poco mas facil de seguir y cambiar que las clases generadas por los Eclipse code generator plugins.

    En una nota aparte, tambien tuvimos problemas con el policy del webservice. Por lo general, el policy va dentro del request cuando envias el user y password. En este caso tuvimos problemas porque el webservice nos retornaba que no encontraba el policy. Se tuvo que crear .xml que llevara el policy con el username de nuestro cliente para poder solucionar este problema. Ejemplo de Policy:


    <?xml version="1.0" encoding="UTF-8"?>
    <wsp:Policy wsu:Id="wss_username_token_service_policy"
    xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsp:ExactlyOne>
    <wsp:All>
    <sp:SupportingTokens
    xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
    <wsp:Policy>
    <sp:UsernameToken
    sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
    <wsp:Policy>
    <sp:WssUsernameToken>TuUserName</sp:WssUsernameToken>
    </wsp:Policy>
    </sp:UsernameToken>
    </wsp:Policy>
    </sp:SupportingTokens>
    <ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
    <ramp:user>TuUserName</ramp:user>
    <ramp:passwordCallbackClass>package.claseDeTuCallBackHandler</ramp:passwordCallbackClass>
    </ramp:RampartConfig>
    </wsp:All>
    </wsp:ExactlyOne>
    </wsp:Policy>


    Como puedes ver en el ejemplo, se utiliza ramparta para el manejo de autenticacion por lo que necesitaras el modulo rampart (yo utilizo el 1.4 aunque no es el ultimo) y agregar las librerias de rampart.

    Para el uso de este, debes configurar apache.axis2.client.options en el ConectionStud Manager.
    Aqui un pequeño ejemplo:


     ClientGeneradoStub result = new  ClientGeneradoStub  ();
     ServiceClient sc = result.getServiceClient();
     Options options = new Options();
     options.setUserName("TuUserName");
     options.setTo(new EndpointReference(endPoint));
     options.setProperty(RampartMessageData.KEY_RAMPART_POLICY,  loadPolicy(repositoryPath + "policy/policy.xml"));
     sc.setOptions(options);
     sc.engageModule("rampart");


      private static Policy loadPolicy(String xmlPath) throws Exception {
    StAXOMBuilder builder = new StAXOMBuilder(xmlPath);
     return PolicyEngine.getPolicy(builder.getDocumentElement());
     }

    Ahora, en el llamado al loadPolicy mandas el directorio en donde se encuentras tu archivo policy.xml (o como tu lo nombraste). Yo agregaba esto al directorio: "policy\\policy.xml" y funcionaba perfectamente. Sin embargo, una vez en produccion, el cliente se volvio a quejar que no encontraba el policy. Crei que el problema era de permisos de carpeta y no lei el policy porque no podia. El problema era de sintaxis. Un amable compañero descubrio que la sintaxis correcta era:   "policy/policy.xml". Mi sintaxis corria perfectamente en windows, pero la sintaxis del compañero corria en windows y linux y voila!

    Bueno, ahi sigo con los exploits en el mundo de webservices. Espero esto te ayude!

    Thursday, January 19, 2012

    Error comun en Eclipse

    ERROR: "resource is out of sync with the filesystem"


    Odio este error, y a cada rato me salia y hasta hoy le dedique tiempito para preguntarle a san google. 


    Solucion:
    Para un error tan molesto, la solución es muy sencilla. Clic derecho-->clic refresh.


    El refresh se podria poner de manera automática de la siguiente manera:
    Clic en Window en el menu superior del Eclipse--->clic preferences--->clic General----->clic Workspace----> dentro de la ventana de workspace hacer clic en Refresh automatically.


    Esto ayudara con estos molestos errores, sin embargo algunos no lo recomiendan por el hecho que en ocasiones un refresh significaría un build del workspace y se prefiere tener control manual de esto. 


    Otro de los errores comunes de Eclipse es el siguiente:
    ERROR: Problem ocurred while trying to save the state of the workbench. Could not write metadata for...


    Por mas que busque, no encontre solución a este error. San google solo me informo que efectivamente es un bug de eclipse. Algunos mencionaban como solución el borrar el .metadata. Según lo que leí, esto lo que hará es borrar tus proyectos del eclipse pero no del disco, y lo único que tendrías es que volver importar los proyectos al eclipse. Esta no es una solución elegante, y no me he animado a probarla aun (talvez cuando tenga todo lo pendiente en el svn me anime). Si alguien cae por estos rumbos y conoce la verdadera solución, por favor comentar y compartir!!!!