EJBs acessando componentes Spring

Oi pessoal,

Estamos mudando nossa plataforma de desenvolvimento de Spring + framework caseiro para JEE (ainda não sabemos se será o 5 ou 6). As aplicações existentes não serão migradas, mas vários componentes (implementados com Spring), que são utilizados por várias aplicações, terão que ser acessados nesta nova plataforma. Estamos pensando em como seria este acesso e algumas alternativas seriam:

  1. Duplicar o código dos componentes, deixando quieto o que está em Spring e implementando tudo novamente em EJB. No curtíssimo prazo isso seria o mais rápido, mas é fácil descartar esta alternativa já que código duplicado somente em ultimo caso.

  2. Importar todo o código (através de JARs) dos componentes para dentro da aplicação e acessar localmente. Isso até que seria simples, mas junto com os JARs dos componentes eu teria que trazer toda a tralha de dependências junto, incluindo Spring e o framework caseiro.

  3. Expor os componentes como web-services SOAP. Essa abordagem teria a grande vantagem de deixar o serviço independente de plataforma, mas, por mais que seja fácil expor um pojo como web-service, daria muito trabalho mapear as entidades trocadas em um xml schema, mesmo usando JAXB ou algo similar. As entidades são bem complexas e se contentar com o mapeamento default do JAXB não ficaria legal.

  4. Expor os componentes como web-services rest. Teria a vantagem de economizar muito em mapeamento, mas transformar a api dos componentes para seguir uma linha restful exigiria uma reimplementação muito grande.

  5. Implementar um componente EJB de fachada, que importaria cada componentes (pelo JAR) localmente e exporia o serviço de maneira transparente. Esse EJB de fachada seria então acessado remotamente pelas aplicações da nova plataforma. Seria um saco implementar um componente só para esse intercâmbio mas como seria só uma fachada, não teria muito código. O Spring tem inclusive uma forma, pelo SpringBeanAutowiringInterceptor, de injetar beans Spring em EJBs

  6. Expor os beans Spring por RMI, usando o RmiProxyFactoryBean, e importá-lo nos EJBs com @Resource. Esta acho que seria a melhor alternativa, mas nunca fiz e nem vi nada parecido.

Alguém já precisou fazer algo parecido e teria alguma dica?

valeu!
Fabrício Lemos

Suas opções foram muito bem pensadas, creio que você fez uma boa pesquisa.

Penso que o ideal mesmo é, já que você quer usar JEE, é quando puder reescrever tudo usando EJB e fazer o que já ficou com Spring acessar esses EJBs como remotos. É muito simples e já fiz isso.

Mas por enquando que você tem tudo no Spring e quer que os EJBs acessem seus beans do spring você pode usar um interceptor no EJB que faz a injeção dos beans do Spring: @Interceptors(SpringBeanAutowiringInterceptor.class).

Porém creio que isso só funcione se você tem o contexto do spring como local. Nunca usei, apenas lí sobre isso nos docs do Spring. Uma solução caso você tenha os EJBs e contexto do Spring em local separado é você usar via webservice como você citou, porém haverá um overhead de fazer o malshal e unmarshal.

Abraços

[quote=fabricio.lemos]Oi pessoal,

Estamos mudando nossa plataforma de desenvolvimento de Spring + framework caseiro para JEE (ainda não sabemos se será o 5 ou 6).
[/quote]

Isto não significa nada. Spring tb funciona em JEE. Suponho que vc esteja pensando em EJB ( que é diferente de jee)

Componentes Spring são POJO não vejo onde está o problema. Mesmo que vc tenha usado @Autowired e coisas do tipo, isso é facilmente removido e substituido por xml, deixando o POJO intacto.

sempre má ideia.

não se remover as anotações primeiro.

Fora que não estaria substituindo spring por jee e sim tendo dois sistemas. Não é boa ideia. webservices não é para isto.

Usar EJB para acesso remoto é asneira. Masi facil simplesmente expor os POJO spring como webservices usando o proprio spring.

Se vc injetar coisas usando o spring , vc não está se livrando do spring e migrando para o EJB.

RMI é pessima ideia. mas facil expor o contexto spring com um recurso no JNDI ( não precisa de RMI) e usálo como um service locator ou usar os método create() do ejb para fazer uma auto-injeção

Tentar usar EJB é péssima ideia. Vc já tem uma estrutura em spring, vc não precisa de ejb. Spring roda tranquilo em JEE, sem EJB.

A forma mais limpa é tirar a dependencia do spring dos seus POJO e usá-los puros no EJB.

[quote=garcia-jj]
Porém creio que isso só funcione se você tem o contexto do spring como local. Nunca usei, apenas lí sobre isso nos docs do Spring. Uma solução caso você tenha os EJBs e contexto do Spring em local separado é você usar via webservice como você citou, porém haverá um overhead de fazer o malshal e unmarshal.
Abraços[/quote]

É, os exemplos que vi foran com contexto local mesmo, o que não é meu caso. De qualquer forma vou investigar mais um pouco. Sobre o overhead do marshal e unmarshal, além do possível gargalo que isso pode ocasionar, eu ainda teria que fazer o mapeamento entidade-xml, que mesmo com JAXB, ou solução parecida, pode dar muito trabalho para se chegar a um schema legal. Minhas entidades são bem complexas.

A nossa estrutura com Spring está bem precária e totalmente legada. Fizemos uma avaliação e decidimos usar EJB e JBoss Seam nas aplicações novas. Esta decisão até pode ser revista, mas não quero transformar a thread em uma discussão EJB vs Spring e sim como integrar meu legado com a nova plataforma.

O legado não depende somente do Spring. Tem o framework caseiro e legado e importar esse componente para dentro do projeto significaria trazer muito lixo. Muitos JARs que estão no classpath não sei nem pq estão sendo usados e mudar a versão de qualquer coisa (do hibernate, por exemplo) sempre é um suplício. Por isso não acho muito legal a alternativa 2

Esse seu framework caseiro faz o que? Envolve regras de negócio ou é apenas um controller web?

Se for a segunda opção não será problema usar full-ejb, pois você pode usar o controller acessando EJB remoto ou local do seu módulo EJB.

Ele envolve tudo, desde a persistência até a camada de apresentação.

Ele envolve tudo, desde a persistência até a camada de apresentação.[/quote]

então vc não precisa migrar. Vc precisa fazer o sistema do zero usando tecnologias diferentes. Mas amarrar-se ao JBoss Seams é pura asneira.
Vc vai sair da frigideira para cair no fogo.

Comece por limpar o que tem, aumente a qualidade. Vai ver que não precisa migrar nem para ejb nem para seams.
Por exemplo, comece por limpar esse monte de dependências. Use o maven se for necessário.

[quote]então vc não precisa migrar. Vc precisa fazer o sistema do zero usando tecnologias diferentes. Mas amarrar-se ao JBoss Seams é pura asneira.
Vc vai sair da frigideira para cair no fogo. [/quote]

Eu não vou migrar nada. O que está feito no framework caseiro vai continuar nele. Somente as coisas novas é que vão ser feitas em uma nova plataforma. E como o framework está muito ruim, amarrado e muito difícil de evoluir é melhor, para as coisas novas, abandaná-lo de vez. Não vejo motivo para continuar fazendo sistemas novos em um framework legado.

Se vocês estão decididos a usar o Seam em novos componentes mas sem perder o conhecimento no legado com Spring, isso pode ser feito sem problemas.

É possível injetar Spring Beans em Seam Components e vice-versa, você não perde nada: http://docs.jboss.org/seam/2.2.0.GA/reference/en-US/html/spring.html

Mas para isso eu teria que importar toda a tralha antiga para dentro dos projetos novos (opção 2) e estava querendo evitar fazer isso.

Como não encontrei nenhum furo, pelo menos não conceitualmente, meu primeiro teste vai ser o acesso por RMI.

O seu maior furo, é “acesso por RMI”.
Dependendo da quantidade de chamadas remotas será um gargalo. É “tão complicado” assim importar os jars e as configurações que “já” estão funcionando? Não estou conseguindo achar o problema em fazer isso.

Achismo? Vc tem algum trauma com o Seam? Conta pra gente?

Não é “Seams”. É “Seam”. :wink:

[quote=andre_salvati][quote=sergiotaborda]
Mas amarrar-se ao JBoss Seams é pura asneira.
Vc vai sair da frigideira para cair no fogo.
[/quote]

Achismo? Vc tem algum trauma com o Seam? Conta pra gente?

Não é “Seams”. É “Seam”. ;)[/quote]

Acho que o que ele quis dizer é que não se sai de um framework pra acabar amarrado em outro. (E eu concordo, é sempre péssimo ficar amarrado a algum deles. Por esses e outros motivos o pessoal desenvolveu a JPA, por exemplo.)

Dito isso, não tenho nada contra o JBoss Seam, acho um framework realmente fantástico, mas que deixa você amarrado a ele (eu coloquei em um tópico aqui no GUJ, não lembro o nome, os prós e contras do Seam).

[]´s

[quote=asaudate]
Dito isso, não tenho nada contra o JBoss Seam, acho um framework realmente fantástico, mas que deixa você amarrado a ele …[/quote]

Sem dúvida. Mas vc ficaria amarrado de qualquer forma com outros frameworks.

Cabe a vc escolher o mais conveniente, o que resolve seus problemas.

[quote=Alessandro Lazarotti]O seu maior furo, é “acesso por RMI”.
Dependendo da quantidade de chamadas remotas será um gargalo. É “tão complicado” assim importar os jars e as configurações que “já” estão funcionando? Não estou conseguindo achar o problema em fazer isso.
[/quote]

Quero evitar importar para não começar a bagunçar o classpath. Algum tempo atrás, por exemplo, tentei atualizar a versão do hibernate do legado, passando da versão 3.x para a versão 3.x+1, deu maior problema e algumas coisas deixaram de funcionar, se a memória não me falha foi algo relacionado ao cache. Não foi tão complicado ajeitar para um componente, mas como todos compartilhavam do mesmo classpath em tempo de execução, seria um esforço muito grande e acabei tendo que voltar atrás, principalmente pq o legado não possui qualquer tipo de teste automatizado. Daí pensei isolar todos esses componentes em serviços, ao invés de importar para dentro da minha aplicação.

Também não sei as consequências de se ter dois containners (spring e ejb) rodando na mesma aplicação.

Mas de qualquer forma vou fazer protótipos com sua sugestão e averiguar as escolhas depois de ter implementado algo.

Em tempo, JEE6 acabou sendo nossa principal aposta (ainda temos que fazer alguns spikes). Tivemos muitas dores de cabeça pra colocar o Seam rodando no Glassfish e depois vimos que não valia a pena. Conseguimos uma janela de tempo maior e resolvemos investigar o JEE 6.