Com a minha mudança de alocação da Globo.com para a Globosat, continuo trabalhando bastante com integração de aplicações, mas agora com um ferramental e paradigmas diferentes.
Na Globo.com eu trabalhei muito com open source, e estava acostumado a montar as aplicações a partir de componentes “crus”, em vez de usar ferramentas sofisticadas. Open source faz parte da cultura da empresa, e tínhamos uma boa liberdade de escolha de tecnologias e arquiteturas.
Como falei algumas vezes no passado, nós migramos boa parte da arquitetura legada com EJBs para serviços REST usando por baixo o Jersey, Spring e Ibatis. A produtividade no desenvolvimento de serviços REST me agrada muito, e mesmo alguém que não conheça muito de serviços REST consegue desenvolver um serviço sem tanto esforço.
Agora vou trabalhar mais com serviços SOAP, mas usando ferramentas muito produtivas, como o Aqualogic ESB e o Workshop, entre outros. Essas ferramentas facilitam muito o trabalho oferecendo Abstrações Opacas. Como ainda estou muito ligado ao trabalho com Open Source, eu venho tentando no meu tempo vago encontrar ferramentas open source com a mesma proposta.
Neste momento estou tentando encontrar a maneira mais produtiva de se trabalhar com web services SOAP usando open source. No passado eu desenvolvi serviços com o XFire, com o Axis 2 e com o JAX-WS, mas achei interessante reavaliar as opções existentes atualmente.
Nos últimos dias eu fiz testes com o Axis 2, com o Apache CXF e com o JAX-WS.
Eu não gosto muito do Axis 2. Você até consegue desenvolver serviços rapidamente com ele, mas ele gera um código tão sujo que é muito triste colocar qualquer coisa em produção com ele, sabendo que você vai ter que manter depois aquele código. Além disso, para utilizá-lo você precisa levar nada menos que 51 jars para sua aplicação, o que transforma qualquer aplicação em um mastodonte. Um outro problema dessa lista massiva de dependências é que a chance de uma aplicação pré-existente ter conflitos de dependências com o Axis é grande.
Na prática, eu só utilizaria o Axis 2 (e mesmo assim com má vontade) para desenvolver serviços se fosse numa estrutura como o WSO2 Web Services Application Server, que é um servidor de aplicações “dedicado” a serviços Axis.
O Apache CXF oferece um “front-end” com JAX-WS (que é o mais recomendado) e um “front-end” alternativo, que usa o Aegis Databinding. Por enquanto olhei apenas o front-end com JAX-WS, mas não vi nenhuma vantagem em utilizar o CXF em vez da implementação de referência presente no Glassfish. Se pintar disposição eu darei uma olhada no front-end com Aegis Databinding, mas por enquanto não tenho grandes expectativas em relação a ele não.
Para finalizar, fiz muitos experimentos com a implementação de referência do JAX-WS, embutido no Glassfish V2. A forma de trabalho que achei mais produtiva nestes meus testes foi desenvolvendo com JAX-WS no Netbeans (utilizei a versão 6.5).
Tentei desenvolver a partir de classes Java, e a partir do WSDL, e esta última me trouxe melhores resultados.A melhor forma que achei foi começar desenhando os schemas XML com o editor do Netbeans:
Criei um Complex Type para cada classe de domínio, e 1 Complex Type para o Request de cada operação e 1 Complex Type para o Response de cada operação. Tendo feito isso, criei depois 1 Element para o Request de cada operação e 1 Element para o Response de cada operação. Com o schema XML criado dessa forma, criei em seguida o WSDL, com o editor do Netbeans também:
Na criação do WSDL, coloquei nas mensagens de Request/Response das operações os Elementos declarados no schema XML anterior. É importante prestar atenção nisso. Usando Elementos nas mensagens, você está criando serviços no modelo Document/Literal. Se você colocar nas mensagens um Complex Type diretamente, em vez de colocar um Elemento, você estará criando um serviço no modelo RPC/Literal. Eu particularmente prefiro Document/Literal, e o código gerado pelo JAX-WS neste modelo me agrada mais.
A implementação do serviço com JAX-WS ficou parecida com isso aqui:
package org.brunopereira.cadastro; import javax.jws.WebService; import org.brunopereira.schema.cadastroclientes.CadastroClienteRequestType; import org.brunopereira.schema.cadastroclientes.CadastroClienteResponseType; import org.brunopereira.schema.cadastroclientes.Cliente; import org.brunopereira.wsdl.cadastrocliente.CadastroClientePortType; @WebService(serviceName = "CadastroClienteService", portName = "CadastroClientePort", endpointInterface = "org.brunopereira.wsdl.cadastrocliente.CadastroClientePortType", targetNamespace = "http://brunopereira.org/wsdl/CadastroCliente", wsdlLocation = "WEB-INF/wsdl/CadastroCliente/CadastroCliente.wsdl") public class CadastroCliente implements CadastroClientePortType { public CadastroClienteResponseType cadastrarCliente(CadastroClienteRequestType request) { System.out.println("Cadastro de cliente foi invocado!! Será feito o roteamento para o serviço adequado!!"); Cliente cliente = request.getCliente(); CadastroClienteResponseType response = new CadastroClienteResponseType(); response.setCliente(cliente); return response; } }
O código do cliente foi gerado bem facilmente a partir do WSDL também, e ficou bem limpo. O que achei bem fraco foi a parte de teste dos serviços tanto no Netbeans como no Eclipse. No Eclipse você só consegue usar os plugins de teste se você tiver desenvolvido os serviços dentro do Eclipse, o que inviabilizou o meu uso. E o Netbeans tem um suporte que só serve pra HelloWorld, pra aqueles serviços de Calculadora, que você passa uns parâmetros primitivos e recebe um resultado simples. A interface do testador do meu serviço ficou dessa forma:

Dá pra ver que não serve para nada além de um HelloWorld basicão.
Bom, de uma maneira geral, o suporte a Web Services no Netbeans é muito melhor do que no Eclipse, que pra piorar só suporta a criação de serviços com o Axis. Até agora a maneira mais produtiva que encontrei de trabalhar com serviços SOAP foi essa que descrevi. Nos próximos dias olharei o que tem de interessante no projeto Metro e no JBoss ESB. Se encontrar coisas interessantes falarei mais por aqui. Ah, e se alguém tiver dicas para melhorar esta forma de trabalho que descrevi, por favor me avisem, pois estou avaliando muita coisa e não dá tempo de dedicar tanto tempo a cada opção dessas.


Oi,
eu estive trabalhando um tempo com essas tecnologias e quando tive oportunidade de avaliar, CXF me pareceu a melhor opção (entre glassfish e Axis2), porque o que eu precisava fazer era estender o framework. CXF eh muito melhor documentado e o código eh bem mais modular pra quem quiser criar algo novo.
No meu caso, eu estava trabalhando num projeto chamado Servus, que eh um componente do EMFT no Eclipse ( http://wiki.eclipse.org/Servus ). A idéia era a seguinte. Muita gente que trabalha com Java hoje em dia cria modelos EMF para modelar os dados. EMF gera as classes de dados e tem diversos serviços como reflexão, persistência em arquivos XML, em banco de dados, etc.
Agora, imagine que você tem esse modelo e gerou as classes, daih você quer expor algum serviço que receba como parâmetro (ou retorne) algum desses tipos. EMF jah tem um mapping pra XSD, então em teoria bastaria você criar um WSDL e apendar o XSD (ou um pedaço dele). Mas os problemas seriam 1) quando você usasse alguma ferramenta JAX-WS pra gerar Java pro seu WSDL, você geraria novas classes pros seus dados (bem parecidas com as que você jah tem), mas nao poderia reusar as que você jah tem 2) você normalmente teria que usar JAX-B bindings, mesmo que EMF jah faca binding de Java pra XML.
Então a idéia era criar um mapping WSDLEMFJava(JAX-WS) em que o código gerado pros client proxies e server skeletons usasse as mesmas classes geradas pelo EMF pra Java, e pudesse aproveitar a serialização do EMF pra fazer o binding. Por isso, eu teria que adicionar um binding pro CXF pra reaproveitar o que o EMF faz. Alem disso, daria pra usar modelos EMF pra modelar os seus serviços.
Infelizmente eu não tive tempo de terminar a implementação do componente, jah que houveram mudanças na IBM que me fizeram ter que mudar de projeto (eles dão funding pro meu doutorado). Toda a estrutura pra ler WSDL, gerar modelos EMF e gerar código esta implementada. Falta somente finalizar as templates pra gerar o código direito. Como disse, não estou podendo trabalhar diretamente nisso, mas se o projeto interessar realmente a alguem, eu posso ajudar a entender o que foi feito, o que ainda tem que ser feito, etc.
Alias, um outro objetivo do projeto era ajudar na migração de serviços baseados em WSDL1.x pra WSDL2, jah que o modelo EMF suportaria ambos.
[]s
OI Thiago, obrigado por compartilhar essa sua experiência. Você estava usando o CXF como implementação de JAX-WS ou estava usando ele com o Aegis Databinding?
Oi,
eu tava usando como implementação de JAX-WS, mas ao invés de usar JAX-B pro binding, tava fazendo serialização em EMF.
Clarificando um pouco. EMF implementa mappings pra XML. Então um modelo Ecore do EMF pode ser visto como um XSD e EMF (de)serializa objetos Java de/para XML. Então, ao invés de encher as suas classes com anotações JAX-B, a idéia era reaproveitar esses mappings do EMF.
Eu cheguei a implementar um proof-of-concept no CXF, criando um novo DataBinding que chamava as classes do EMF pra serializar e de-serializar. Funcionava direitinho, mas eu nunca tive chance de terminar uma implementação robusta.
Quando eu acompanhei a lista cxf-dev, me pareceu que Aegis não era tido como a melhor opção, era somente mantido pra ter compatibilidade para clientes que usavam o Aegis nas implementações antigas.
[]s
Oi Thiago, obrigado novamente por compartilhar essa sua experiência. Como você falou, também tive a impressão de que a recomendação forte do CXF é o uso do JAXB em vez do Aegis.
Então se é pra usar JAX-WS com JAXB, prefiro simplesmente usar a implementação de referência que não deixa a desejar em nada em relação ao CXF. Por enquanto continuo achando que a forma mais produtiva de trabalhar com SOAP usando open source é escrevendo os schemas e os WSDLs e depois gerando as classes Java com o JAX-WS/JAXB.
Exato! O melhor jeito atual eh “escrevendo os schemas e os WSDLs e depois…”. Eh exatamente isso que a gente tava tentando evitar, que voce tenha que se preocupar com XSDs e WSDLs. A ideia era usar EMF no lugar.
Mas concordo que se voce nao precisa modificar o framework, glassfish deve ser suficiente. Mas CXF tem algumas coisas legais tambem, como o Simple Databinding pra fazer prototipos.
[]s
Muito bom artigo. Recentemente fiz a mesma pesquisa no trabalho e obtive o mesmo resultado: Netbeans + Metro. O Metro contém o JAX-WS RI internamente e o WSIT, para WS-Secutiry e WS-Coordination. Muito completo e produtivo. Fora esta parte de testes, que você pode tentar usar o soapUI, acho muito melhor do que o BEA Workshop.
Lembrando que tanto o Glassfish quanto o JBoss trabalham com o Metro, ou seja, não é preciso levar nenhuma lib para a aplicação se estiver usando um destes app servers.
Abraço e estou no aguardo da seqüencia deste artigo!
Oi Rodrigo, obrigado por compartilhar também esta sua experiência. Eu não tive tempo nas últimas semanas de prosseguir muito nos experimentos, mas pretendo em breve retomar meus testes usando o Glassfish + Metro em conjunto com o Mule e talvez o Service Mix.
O Mule e o Service Mix têm propostas um pouco distintas, e também quero avaliar melhor as características de cada um. Se você tiver observações interessantes sobre os 2, terei todo o interesse em saber.
[]s