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.

Tuesday, December 20, 2011

Eclipse Axis Error

Intentando generar un web service o un web service client utilizando el wizard de Eclipse, nos encontramos con el siguiente error:

Error when deploying Web service to Axis runtime axis-admin failed with {http://xml.apache.org/axis/}HTTP (404)Not found

San Google dijo que el problema es que estas intentando hacer un deploy cuando el server aun no ha levantado. Varias paginas web decian que la solucion sencilla era darle Next, Next, Next hasta que funcionara porque en teoria eventualmente tu server levantaria. Varios Next despues con el mismo error, varias paginas hablaban de un parche que se podia instalar que bruscamente mantenia tu start loopeando hasta que el server estuviera arriba. Esa solucion no me gusto.

Solucion sencillisima!!!:
Click en Window en la parte de arriba del Eclipse-----> clic en preferences----->escribe Axis------->clic en Axis2 Preferences----->pestaña Axis2 Runtime---->clic en Browse------>vete a la locacion de tu axis2 libs----> clic en Axis Emitter---->clic en Apply.

Si no tienes las librerias de Axis2, asegurate de bajarlas primero. Yo se que el wizard de Eclipse crea los web services y web service clients en Axis pero no se porque haciendo esto funciono en mi maquina y en la de mi compañera.

Eclipse bug fixed sin parche!

Thursday, December 15, 2011

Web service client con ADB databinding y xmlbeans databing con Axis2 Code Generator Eclipse

Al final de este articulo se encuentran dos ejemplos de como utilizar las clases generadas por el Axis2 Code Generator plugin para Eclipse. Primero discuto algunos errores que encontre en su uso.

Oh San Google, San Google como fallas!
Esta es una de esas veces donde me quise arrancar los pelos buscando como solucionar dos errores horripilosos de Axis2 cuando se genera Web clients.

Error 1:
org.apache.axis2.Axis Fault: org.apache.axis2.Databinding.ADBException: Unexpected subelement .....

En este primer error, San Google fue mas o menos de ayuda. Digo mas o menos porque lo unico que hizo fue confirmar que hay un bug en la generacion de clases con el Axis2 con Databinding ADB. Lo que sucede en este error (segun lo que lei) es que el ADB esta esperando que el xml request o response (debes encontrar en cual de los dos o si en los dos esta el error) envie un orden especifico "a,b,c" y el webservice esta retornando un orden "a,d,c" por ende, el Unexpected Subelement. No comprendi a cabalidad si el error es porque el orden del schema en el wsdl no corresponde, el bug es del ADB. Creo que lo mas correcto seria corregir el wsdl en el webservice, pero como en este caso nosotros solo consumiamos el webservice y no lo creamos, asi que no pudimos darnos el lujo de corregirlo.

Ya he utilizado el ADB databing antes y no me genero este error. Es el databing por default del Axis2 Code Generator y su codigo es mas sencillo.  (abajo un ejemplo).

Solucion: Asumo yo que se considera bug del ADB porque no deberia quejarse y solo recibir lo que se le envia. Por eso, la recomendacion general de San Google fue utilizar xmlbeans de Databinding.

Generamos nuevamente el codigo del cliente con el Axis2 Code Generator con databinding xmlbeans y todo parecia ir bien hasta que aparecio este error:

Error2:
ClassNotFoundException : Cannot load SchemaTypeSystem. Unable to load class with name schemaorg_apache_xmlbeans.system...
.TypeSystemHolder.
Make sure the generated binary files are on the classpath.



Todo San Google tenia la misma solucion: asegurate de agregar la clase TypeSystemHolder.class al classpath. Muy pocos decian como (porque agregar algo al classpath es lo mas sencillo del mundo, pero no para esto!). No intentes agregar la clase al classpath en ningun lado, no funciona. Una cosa que me enoja de los ejemplos y ayuditas del Axis2 es que todos son para Web dynamic projects! U_U...
Algunos mencionaban soluciones utilizando un WSDL2JAVA code generator (que en esencia es lo mismo que el Axis2 Code Generator) y utilizar un ANT script para copiar la disque clase al classpath. Lo triste es que todos decian: "copialo al build/classes" y los JAVA projects (que son los que generalmente uso para los webclients) no tienen esas carpetas!!! ¬_¬

Solucion sencillisima: click en build path ------> configure build path. En la pestaña de Source--->click en Add Folder----->agrega la carpeta resources que te creo el Axis2 que contiene el TypeSystemHolder.class y un monton de otras cosas mas. Agrega toda la carpeta, no agregues solo la subcarpeta con la clase. NO es necesario ningun xmlbeans.jar; que no te engañe Google!!!


Aqui los ejemplos (Son solo una idea o guia);

ADB Databing. 
Como menciones arriba, es el default y el mas "amigable" de usar.
   
        ExampleServiceStub service=null;   // Declara el servicestub primero 
        ExampleParameter param= new ExampleParameter(); //averigua que tipo de parametro espera el                         metodo que desea consumir. 
param.setA("A");
param.setB("B");
param.setC("C"); //....etc
       ExampleMethod method = new ExampleMethod(); //llena el parametro del metodo
method.setFunctionCall(param);
service = _servicePool.borrowService(_endPoint, _repositoryPath, _userName);
ExampleResponse functionresponse = service.function(method); //invoca la funcion
ExampleResponse response = functionresponse.getResponseMessage();

XmlBeans
Jamas imagine que el codigo de xmlbeans seria tan diferente. No es en si MUY diferente, pero sin una guia, definitivamente seria un reto.

        ExampleStub service = null;
        service = _servicePool.borrowService(_endPoint, _repositoryPath, _userName, _timeOut);    
        ExampleRequestDocument request = ExampleRequestDocument.Factory.newInstance(); //no utilices la palabra new aqui. Se instancia con un Factory.newInstance();
        ExampleParameterQuery param = request.addNewExampleRequest();
param.setA("A");
param.setB("B");
param.setC("C"); //...etc
        request.setParameter(param);
        ExampleResponseDocument response = service.getFunction(request);

Si esto te ayuda, me alegro mucho! A esta mente pollo que todo se le olvida le servira mucho!