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.

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!!!!