Spam en el foro SMF. Anti-Spam

logo SMF Desde hace ya mogollón de años, tengo un foro de java con SMF (Simple Machines Forum). Y desde hace ya mogollón de años vengo sufriendo el spam. Montones de «bots» registrados al día y algunos consiguen llegar a meter mensajes de spam en el foro.

Fui poniendo lo que permite SMF como anti-spam. Un captcha y preguntas que el usuario que quiere registrarse debe contestar. Las preguntas deben ser sencillas para que un usuario normal no tenga problemas, pero que un bot no pueda constestar fácilmente. Mis preguntas eran estilo de qué color es el caballo blanco de Santiago o cuanto es 2+3.

Pues nada, sigue habiendo problemas, así que me he puesto a buscar alternativas. Y encontré esta lectura que me ha llamado la atención «Qué puedo hacer contra el spam»

Resulta que los bots en general pueden con los captchas y según dice ese artículo, un captcha da más problemas a un usuario legítimo al registrarse que a un bot. Desde luego, el captcha más complejo de SMF a mi me cuesta o no puedo leerlo y no ha conseguido parar a los bots.

Resulta también que los bots saben hacer cuentas en las preguntas estilo cuánto es 2+3 y resulta que también prueban a poner todas las palabras de la pregunta como respuesta, con lo que lo de qué color es el caballo blanco de Santiago tampoco es una buena opción.

En este hilo leo posibles buenas preguntas para hacer. Algo que nadie necesita saber puesto que la respuesta se busca en la pregunta y que teóricamente dificulta el asunto a los bots. Preguntas estilo «Pon los tres últimos números que hay en la cadena dg7564gh»

Así que he cambiado las preguntas a preguntas de este estilo. A ver qué pasa.

Truquillo para reiniciar un war en tomcat

Una vez desplegado nuestro.war, a veces tocamos alguna cosa a mano dentro de los ficheros de nuestra aplicación webapps/nuestro/, quizás un fichero .properties, quizás cambiar un jar por una versión más moderna, y queremos reiniciar la aplicación.

Las opciones más conocidas y estándar son:

  • Entrar en el manager de tomcat y desde ahí pararla y volver a arrancarla
  • La opción bestia, parar tomcat y volverlo a arrancar

Sin embargo, hay otra menos conocida y muy útil si no tenemos el manager instalado (por ejemplo, caso de liferay). Si estamos en linux, basta hacer un touch webapss/nuestro/WEB-INF/web.xml Esto hará que se reinicie la aplicación.

He leído «Getting things done», de David Allen

Gettings things done

He leído "Getting things done" de David Allen, el famoso método GTD para organizarse.

La lectura me  ha resultado un tanto extraña. Los primeros capítulos me han parecido estupendos. Nos cuenta en plan teórico cuales son los problemas que tenemos para organizarnos y trabajar con eficacia y nos cuenta, también en plan teórico, cual es la forma que propone para remediarlo. Podemos estar más o menos de acuerdo con lo que cuenta, pero en mi caso sí es cierto que los problemas que menciona son los problemas que me impiden muchas veces hacer las cosas. En otros casos no, soy vago por naturaleza y si el trabajo no me resulta entretenido, tiendo a no hacerlo y eso no lo menciona 😉

La segunda parte me ha parecido más aburrida. Entra ya en el detalle práctico de cómo aplicar su método, pero para mi gusto se extiende demasiado, contando/reafirmando una y otra vez los conceptos que explicó en los primeros capítulos sin aportar realmente nada nuevo, al menos, a nivel conceptual. Por ejemplo, dice que para aplicar su método, debemos aplicarlo a todas las facetas de nuestra vida (trabajo, casa, aficiones, recados, etc) y por ello, para empezar a aplicar su método …. ¡¡ debemos emplear entre una y dos semanas a organizarlo !!. Claro, lo primero es hacer una lista de todo lo que nos preocupa, aunque sea mínimamente, así que empieza por meter en esa lista desde los proyectos de trabajo …. hasta el cuadro que tenemos colgado en el pasillo de casa y que no nos gusta. Y luego hay que coger todas esas cosas, una por una, para ver qué hacemos con ella. Efectivamente, no me extraña que necesitemos una o dos semanas.

Bueno, ahí va mi resumen del libro. No voy a centrarme en las consabidas listas de acciones, acciones siguientes, contextos y lo que encontramos en cualquier resumen por ahí. Iré más que nada a lo que me ha llamado la atención, el "fondo" del asunto.

El problema principal es que habitualmente tenemos los problemas en la cabeza y son muy variados, desde cosas de trabajo realmente estresantes hasta pequeños detalles de la vida cotidiana como "debería revisar el coche".  Tener todo esto en la cabeza hace que no nos acordemos de todo en el momento adecuado y que cuando estamos haciendo algo estemos preocupados pensando en otras cosas pendientes, por lo que no somos todo lo eficientes que deberíamos.

La solución, apuntar todo esto, absolutamente todo lo que tengamos en la cabeza (problemas, cosas que tenemos que hacer, ideas, etc) en una lista. En realidad el autor habla de una bandeja de entrada en la que podamos poner físicamente cosas, notas, papeles, etc. Debemos tener además esa lista más o menos siempre a mano de forma que cuando se nos ocurra algo, podamos apuntarlo inmediatamente. Debemos apuntar absolutamente todo, de forma que confiemos en que esa lista tiene todo y así nuestra mente pueda "descansar" y no pensarlo.

El segundo gran problema es que estas listas suelen ser listas de problemas o cosas que no están totalmente claras, así que nuestro trabajo consiste en revisar esa lista periódicamente y decidir, una por una, que vamos a hacer con cada una de esas cosas. El objetivo es vaciar esa lista de cosas e ir creando otra lista con acciones concretas a hacer. El proceso y las reglas son las siguientes

  • Coger los item de la lista uno por uno, en orden y sacarlo de la lista, no se puede volver a dejar ahí.
  • Decidir si ese item es simplemente información que nos interesa o puede interesar. Tenemos entonces que tener un archivo donde podamos guardar información.
  • Decidir si ese item requiere que hagamos algo. Hay que decidir cosas concretas y exactas para hacer. Por ejemplo, "debería revisar el coche" debe convertirse en "llamar al taller patatín para pedir hora/precio". Si extraer la lista de cosas a hacer requiere mucho tiempo o pensarlo en profundidad, la siguiente tarea a hacer es "sacar lista de acciones a hacer con esto".
  • Si lo que hay que hacer se hace en menos de dos minutos, hacerlo directamnte. Si no, ponerlo en una lista de cosas concretas a hacer. Lo de dos minutos es el tiempo estimado que te puede llevar archivar algo que tienes que hacer para procesarlo luego. Si tardamos más en archivarlo y recuperarlo luego, mejor hacerlo ahora.

Y ya está, cuando hagamos la revisión de la lista de cosas que nos preocupan, debe quedar vacía y en su lugar tendremos una lista de cosas concretas para hacer. La lista de cosas que nos preocupan volverá a ir teniendo más cosas según nos vayan llegando o se nos ocurran. Las apuntamos hasta la siguiente revisión que haremos con periodicidad.

Finalmente, hay un tercer punto muy importante y es el que da lugar a lo de siguiente acción, algún día/tal vez, contexto, etc. El punto importante es que para usar realmente este sistema debemos hacerlo fiable y cómodo. Ello implica que debemos organizarlo de forma que tengamos seguridad de que está todo y que vamos a encontrarlo cuando lo necesitamos. Y de ahí sale todo lo demás.

  • Debemos tener un calendario con las citas o cosas que hay que hacer en fechas fijas. Aquí insiste mucho el autor en que sólo debe apuntarse aquello que sólo se pueda hacer ese día (una cita con el dentista, una reunión ya fijada, etc). Nunca debemos poner el día que una tarea tiene que estar acabada o la lista de tareas que queremos hacer ese día.
  • Las acciones debe estar claramente partidas en acciones que podemos hacer en cualquier momento y acciones que no podemos hacer porque estamos a la espera de algo. Esto nos permite, cuando tenemos tiempo para trabajar, revisar una lista más reducida de cosas que realmente podemos hacer en ese momento.
  • Las acciones tienen que estar clasificadas por un contexto en que podemos llevarlas a cabo. Acciones que se hacen con teléfono, que se hacen teniendo internet, que se hacen teniendo ordenador, que se hacen en casa, que se hacen cuando estamos de compras o de recados, etc. De esta forma, cuando tenemos un rato para trabajar, podemos mirar la lista concreta de cosas que podemos hacer con los medios disponibles.

Todo el sistema (cosas que nos preocupan, acciones, contextos, contenido de las listas, acciones en espera, etc) debemos revisarlos periódicamente para reorganizarlo y asegurarnos que todo el sistema está completo y actualizado. Debemos hacerlo con la frecuencia necesaria como para que confiemos en su estado.

Y aunque hay más cosas en el libro, creo que esto es lo realmente importante: Apuntar todo, decidir acciones concretas y tenerlas perfectamente organizadas para en cada momento y circunstancia, saber qué podemos hacer y asegurarnos que no se nos olvida nada.

Liferay: Migrando de HSQLDB a MySQL

 Liferay viene con una base de datos HSQLDB por defecto. La intención es que con cero instalación tengamos nuestro portal funcionando con sus datos de ejemplo. Sin embargo, el log de liferay al arrancar nos avisa que estamos usando la base de datos HSQLDB, no adecuada para un entorno de producción y nos ruega encarecidamente configurar Liferay con una base de datos en serio, como MySQL, Oracle, etc.

Por supuesto, con las prisas de todo proyecto, ni puñetero caso. Y tras unos meses de desarrollo y con algo más de tiempo, llega el momento de hacer la migración. Este es el mejor tutorial que he encontrado para hacerlo y en el que me he basado. Pero como todo informático experimentado sabe, las cosas nunca van bien a la primera. Aquí mis pasos, problemas y soluciones, no tan detallados como en el tutorial.

Primero de todo, por supuesto, paramos nuestro portal liferay. Del directorio …/liferay-6.0.6/data/hsql cogemos los dos ficheros lportal.properties y lportal.script que son los que tienen nuestros datos en HSQLDB. Hacemos copia de seguridad, por supuesto, los borramos de ahí (junto al directorio hsql) porque ya no los usaremos.

El fichero hsql.script hay que cambiarlo con un editor de textos con lo que indica el enlace anterior

  • Cambiar un par de líneas en las que aparece PUBLIC por LPORTAL. Esta última palabra será el nombre de la base de datos en MySQL donde vamos a hacer la migración. Las líneas donde aparece PUBLIC son las de CREATE SCHEMA y SET SCHEMA.
  • Cambiar todas las fechas 1970-01-01 por 1970-01-02, porque MySQL no admite la primera por lo visto.

Con la herramienta MySQL migration Toolkit hacemos la migración de HSQLDB a MySQL. Primero, antes de arrancar la herramienta, debemos poner el hsqldb.jar en el directorio C:\Program Files\MySQL\MySQL Tools for 5.0\java\lib para que la herramienta tenga disponible el driver de la base de datos HSQLDB.

Una vez arrancada la herramienta, los parámetros de conexión a la base de datos son

Source – HSQLDB
Driver Class: org.hsqldb.jdbcDriver
Connection String: jdbc:hsqldb:file:LIFERAY_INSTALLATION\data\hsql\lportal (Sin extension)
Username: sa
Password: <empty>

Target – MySQL
Host: localhost
Port: 3306
Username: root
Password: <empty>

Por supuesto, el path de la conexión HSQLDB será donde tengamos copiado nuestro fichero lportal.script. Es necesario que el lportal.properties esté en el mismo directorio.

Seguimos con los pasos de la herramienta y nos da hasta cuatro opciones de las que podemos elegir las que queramos

  • Crear las tablas directamente en la base de datos MySQL
  • Crear un script con la creación de tablas para MySQL
  • Insertar los datos en la base de datos MySQL
  • Crear un script con los insert para MySQL

Bueno, el tutorial dice que basta con hacerlo directamente sobre MySQL y así debería ser, pero a mí me han surgido problemas.

La herramienta protesta porque algunas tablas de HSQLDB tiene columnas de tipo texto con longitudes muy, muy grandes y aconseja campos tipo BLOB. Esto hace que la herramienta directamente no cree esas tablas.

Si generamos el script de creación de tablas y lo ejecutamos, ya no tenemos esos problemas con esos campos, pero protesta porque en una tabla concreta se usa un index con uno de esas columnas de texto gigantes y MySQL no lo permite.

En cuanto a los insert, la opción directa no funciona porque faltan tablas. Así que generamos el script y nos quedamos con él, es lo único de los cuatro pasos que nos sirve.

¿Y cómo he creado las tablas entonces?. Pues he dejado que sea Liferay el que lo haga por mí. Borré el directorio liferay-6.0.6/data/hsql, con lo que si arrancamos liferay empezaría desde cero. Pero antes de arrancarlo lo configuro para que use MySQL

  • Pongo el jar con el driver de MySQL en un sitio que lo encuentre Liferay, en concreto lo puse en ../liferay-6.0.6/tomcat-xxxx/ROOT/WEB-INF/Lib/mysql-connector.jar.
  • Me aseguro que el fichero ../liferay-6.0.6/tomcat-xxxx/bin/setenv.bat o setenv.sh (el que usemos) tiene en sus JAVA_OPTS un -Dexternal-properties=portal-ext.properties. Esto hará que se lea el fichero portal-ext.properties
  • Ese fichero está en …/liferay-6.0.6/tomcat-xxxx/webapps/ROOT/WEB-INF/classes/portal-ext.properties. Lo editamos y ponemos la configuración para MySQL

jdbc.default.driverClassName=com.mysql.jdbc.Driver
jdbc.default.url=jdbc:mysql://localhost/lportal?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
jdbc.default.username=un usuario
jdbc.default.password=una password

Por supuesto, en la url pondremos lportal o el nombre que nos guste, pero debe ser el mismo que el que hayamos puesto cuando hicimos la migración de HSQLDB. Sólo queda arrancar liferay y esperar que cree todas las tablas. Matamos liferay, hacemos un backup de las tablas recién creadas sin datos, sólo la estructura y ya tenemos un script que crea las tablas. El comando para ello puede ser algo como

mysqldump -u usuario -p –no-data –databases lportal > crea_tablas_liferay.sql

Ahora ya podemos borrar en MySQL la base de datos completa, volver a crearla y ejecutar los scripts de creación de tablas e inserción de datos. Desde la consola de MySQL

drop database lportal;
create database lportal;
use lportal;
source /path/crea_tablas_liferay.sql
source /path/Inserts.sql

donde path es donde tengamos los scripts e Inserts.sql el el script de inserciones obtenido con MySQL migration Tool. Me tropecé también con un pequeño detalle de MySQL mayúsculas/minúsculas, así que tenlo en cuenta antes de crear las tablas e insertar los datos si estás en linux.

Y listo, arrancando ahora Liferay debemos tenerlo igual que antes, pero trabajando sobre MySQL en vez de sobre HSQLDB.

Otro enlace que me fue útil es este, aunque es para otra herramienta de Atlassian.

Mezclando tecnologías : JSF y jQuery

Hace un tiempo estuve leyendo el tutorial de la antes SUN sobre JSF y estos días estoy leyendo sobre jQuery. Por aquello de jugar un poco con ambas cosas me dije: voy a hacer un proyectito. Una lista de tareas web con base de datos y JSF, pero que se puedan ordenar arrastrándolas con el ratón usando sortable de jQuery. Por supuesto, cada vez que se arrastra una fila de la lista y se coloca en otra posición, debería almacenarse su nueva posición en base de datos.

Pues nada, me pongo a ello. Con JSF me hago toda la parte de base de datos, lista de tarear y botones para editar, borrar y crear.

Ahora me pongo con la parte de jQuery. Lo de hacer la tabla "sortable" y arrastrar las filas de un lado para otro sin ningún problema. Toca hacer la persistencia…. y ahí es donde han empezado mis problemas.

Con jQuery puedo enterarme cuándo se arrastra una fila y hacer una pequeña llamada jQuery.ajax() para indicarle al servidor el nuevo orden y que lo guarde en base de datos. La primera "pega"es que no hay forma fácil de llamar desde jQuery a un managed bean de JSF.La solución pasa por hacerse un JSP normalito o Servlet para recoger esas llamadas jQuery.ajax(). Ese JSP sí puede intentar conseguir el ManagedBean de JSF y hacer la llamada correspondiente.

La segunda pega de momento es más insalvable de una forma sencilla. Con jQuery y sortable() puedo obtener el orden de los elementos por su id del tag html. Es decir, si uso un <table> y quiero ordenar los <tr>, cada <tr> debe tener un id <tr id="algo">….</tr>. En la llamada a jQuery.ajax() se pasaría como parámetro esa lista de id de los <tr> en el orden en que están en pantalla. Y este id debería ser el id de la Tarea en esa fila, de esta forma cuando esa lista de id llegue al servidor, este sabrá el orden de las tareas.

Pero JSF, con su tag DataTable usa columnas y no pone ningún id a los <tr>. Y no hay forma de ponérselo de ninguna forma fácil. Tampoco con javascript/jQuery se puede poner a posteriori, porque jQuery no puede acceder al ManagedBean que ha generado la fila y por tanto a su id. Posiblemente se puede poner una columna oculta con los id de tarea y así jQuery podría poner el id al <tr> según el valor de la columna oculta… pero se me hace un poco "artificioso".

Y ahí me he atascado. JSF no pone id a los <tr> ni forma fácil de hacerlo. JQuery no puede acceder a los ManagedBean para poner ese id a posteriori.

Resumiendo, me hace la impresión de que cada tecnología sirve para lo que sirve y no siempre es fácil usar varias de ellas a la vez.

Jugando con jQuery

Ahora que me ha empezado a tocar a hacer aplicaciones web, hemos empezado a usar jQuery. En los proyectos había hecho algo, pero siempre por encima y sin saber muy bien qué estaba haciendo. Lo típico de buscar en la documentación o en google, encontrar el trozo de código que hace lo que tú quieres, copy-paste y arreglarlo hasta que funcione.

Pero ahora me he puesto a jugar con jQuery un poco más en serio y la verdad es que me ha gustado lo que he visto.

Aunque parece raro al principio, sobre todo porque no tengo ni idea de javascript, te acostumbras rápido a usarlo. Es muy sencillo y funciona bien, además de ser bastante potente.

Tenemos por un lado su funcionalidad "básica", que permite fácilmente buscar elementos dentro de la página web, cambiar cosas, etc, etc. Y me ha gustado especialmente la sencillez con que se pueden hacer llamadas tipo AJAX y lo fácil que se puede leer la respuesta si viene en formato JSON. De hecho, jQuery te transforma automáticamente esa respuesta JSON en un objeto javascript con los atributos y valores correspondientes al JSON. No sé yo el XML, cada vez me da más "yuyu", incluso desde java, nunca es fácil de leer y siempre tienes que liar el código con clases Document, y Node, y buscando Childs …. 

Para la parte de Drag and Drop, por supuesto tenemos lo básico para hacer lo que queramos, pero lo más "molón" es sortable(), que te da directamente una lista que se puede ordenar arrastrando los items con el ratón sin más necesidad que una línea de código javascript. Se puede incluso hacer varias listas y permitir que los elementos se puedan pasar de una a otra … y sólo requiere una línea de javascript por cada lista.

Tenemos también en jQuery una serie de "Widgets" opcionales, como diálogos, pestañas, acordeones, fechas, etc, etc que también son sencillos de usar. La "pega" es que para que salga algo decente requieren unos CSS más o menos complejos. Por lo que casi no queda más remedio que bajarse alguno de algún sitio ….. pero me ha llamado mucho la atención themeroller. Estos de jQuery lo tienen todo pensado y entrando en la página de themeroller podemos definir con el navegador nuestro propio CSS, viendo cómo queda sobre la marcha según vamos tocando, y luego bajarnos el tema completo junto con las librerías de jQuery (la básica y la de los Widgets).

En fin, me ha gustado mucho todo lo que he visto hasta ahora. Sé que solo he ido haciendo unas pruebas básicas para ir aprendiendo y que en una aplicación real puede haber más "enrevesamiento" del previsto.

Certificados digitales y web services

Algo con lo que también ando liado últimamente. Ofrecemos Web Services sobre https y requerimos que el cliente que intente usarlos presente un certificado digital para poder acceder a ellos, pero no usando WS-Security, sino sobre el mismo protocolo https.

El montaje y la serie de artículos a lo que todo este trabajo ha dado lugar es el siguiente.

Por un lado, montar un Apache http server y un Apache Tomcat. El segundo es el que contiene el war con nuestros web services. El primero, el apache http server, únicamente redirige las entradas de los clientes hacia el tomcat, y también es el que tiene su certificado y acepta o rechaza los certificados de los clientes.

Una vez hecho este montaje, viene la parte de hacer el código de cliente del web service. Para ello uso la librería Apache CXF.y este es el código para conseguir que un cliente CXF pueda presentar su propio certificado de cliente al servidor y a su vez acepte o rechace el certificado del servidor. Y bueno, este ya es problema particular mío, pero también tuve que conseguir que el cliente CXF saliera a través de un proxy corporativo.

Y aparte de todo esto, un pequeño conjunto de artículos más básicos que han ido saliendo sobre web services.

En fin, cogidas por los pelos, pero he aprendido un montón de cosas.

jUDDI y la madre …

Estamos instalando un jUDDI para ofrecer este servicio en nuestro proyecto y desde luego, la experiencia no está siendo demasiado buena. Funciona bien una vez instalado, pero la instalación es un pequeño infierno.

De primeras, de los descargables que nos ofrece, el war para tomcat no funciona, le faltan un montón de librerías. El siguiente, jUDDI con portal, tampoco va. Al final el que funciona es el "bundle" con portal, que es un tomcat completo listo para arrancar. Pero claro, yo tengo ya mi propio tomcat ….

Y luego viene el asunto de configurar los usuarios que tienen acceso, no desde el portal de jUDDI sino a los web services que ofrece, y la documentación parece muy clarita. La propiedad juddi.auth=org.apache.juddi.auth.JUDDIAuthentication hay que cambiarla por juddi.auth=org.apache.juddi.auth.XMLDocAuthentication, aparte de añadir otra propiedad con el fichero XML con los usuarios. Pues bien, esa clase org.apache.juddi.auth.XMLDocAuthentication NO existe. La clase correcta es org.apache.juddi.v3.auth.XMLDocAuthenticator, con un v3 por el medio y acabada en ator en vez de ation. La encuentras si montas todo en eclipse y buscas la clase XMLDOCAu… y dejas que te autocomplete.

Por cierto, ando liado en inglés con la gente de los otros países y se poco inglés, afortunadamente sólo es por correo. Y he aprendido que al empezar el correo, "Dear," o "Pedro," se usa con gente con la que se quiere mantener las formas, mientras que "Hi," o "Hello," es para gente con la que tienes confianza. Me chocaba eso de recibir "Dear" en todos los correos. Y nosotros usamos dos puntos detrás (Querido Federico: ), parece que en inglés se lleva poner coma.

Y lo mejor de todo es que ninguno de los de los correos es inglés, hay de todo, menos nativos en inglés.

 

 

Sigo jugando con los web Service

 El proyecto en el que ando metido es un proyecto de lo más extraño. Son seis paises europeos, cada uno tiene que hacer un portal web y todos estos portales web deben compartir datos entre ellos. Debe ser distribuido, por lo que ninguno de los servidores es más importante que los demás ni tiene centralizada la información. Así que la forma que se ha pensado es que cada portal web vaya a su bola con su propia base de datos y sus propios usuarios, pero que todos ellos ofrezcan unos web services de forma que puedan consultarse datos entre ellos.

¿Y qué es lo extraño?. Pues nada especial, sólo lo de siempre. El portal es relativamente sencillo, no es nada que un "friky" que sepa no pueda hacer en su casa en uno o dos meses de trabajo … pero la coordinación de todo esto es un infierno. Seis cliente de seis países distintos cada uno con su propia empresa contratada. Cualquier decisión por pequeña que sea que afecte a la interfaz de intercambio requiere una lista interminable de correos o incluso esperar a ser decidida en alguna de las reuniones internacionales que se hacen de vez en cuando. Al final ya veo por qué muchos proyectos no son rentables, se paga excesiva gestión, excesivos gestores y demasiada reunión cara. Al final la historia del remero y los supervisores va a ser cierta.

Y así estamos, desarrollando nuestra parte del portal, pero medio bloqueados/jugando con la parte de los web services en espera de interfaz definitiva, protocolos de seguridad definitivos, etc.

Así que en eso es en lo que estoy ahora, jugando con los web services y distintos temas de seguridad: WS-Security, http basic authentication, SAML, etc. Y a resultas de eso y como me gusta escribir todos los "hola mundos" de prueba que hago, salen una serie de tutoriales de web services en la chuwiki.

Por cierto, jugando con metro y con CXF, al final me quedo con CXF. ¿Por qué?. Metro me ha dado un par de problemas extraños en un par de ocasiones. Uno por incompatibilidad de librerías que tiran de librerías que tiran de librerías y el otro no lo tengo muy claro por qué me ha dado el error, pero el mismo código/wsdl funciona sin problemas con CXF. Aparte, me gusta mucho más la documentación de CXF que la de metro.

Y la culpa es del remero.