Migração jboss 4 para jboss 6 AS (EJB 2 para EJB 3)

20 respostas
java
R

Estou fazendo uma migração do JBoss 4 para o JBoss 6 aproveitando migrando EJB 2 para EJB 3.

Vou discriminar os passos feitos.

Estrutura

MinhaAplicacao.ear
  minhaapp.war
  META-INF
     applications.xml
     persistence.xml

1º Incluir o arquivo postgres-ds.xml na pastajboss-6.1.0.Final/server/default/deploy .(OK)
2º Bibliotecas repetidas que haviam no projeto foram retiradas pois estão no JBoss.(OK)
3º Eliminar os descriptors arquivos ejb-jar.xml e jboss.xml.(OK)
4° Remover as refencias dos ejb’s do application.xml (OK)

<module>
	<ejb>minhaClasseEjb.jar</ejb>
</module>

5º Incluir nas classes que as referencias foram removidas do application.xml (OK)

@Stateless
public class MinhaClasseSEJB implements MinhaInterfaceLocal{  }

6° Incluir a anotação na interface (OK)

@Local
public interface MinhaInterfaceLocal {}

7° Ajustar minha chamada do lookup (OK)

Senhores estou a quase duas semanas com esse erro, já usei diversos artifícios mas nem um com sucesso se alguém já passou por esse problema, me ajude .

O sistema usa Struts 1.2, EJB 3 e Hibernate com JPA.

Erro

2016-06-29 14:58:32,211 WARN [org.apache.struts.action.RequestProcessor] (http-0.0.0.0-8080-2) Unhandled Exception thrown: class java.lang.ClassCastException
2016-06-29 14:58:32,215 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/gsan].[action]] (http-0.0.0.0-8080-2) Servlet.service() for servlet action threw exception: java.lang.ClassCastException: gcom.cadastro.sistemaparametro.SistemaParametro cannot be cast to gcom.cadastro.sistemaparametro.SistemaParametro
at com.sun.proxy.$Proxy152.pesquisarParametrosDoSistema(Unknown Source)
at gcom.gui.CarregarParametrosAction.execute(CarregarParametrosAction.java:42) [:]
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484) [:1.1]
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274) [:1.1]
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482) [:1.1]
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:507) [:1.1]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:734) [:1.0.0.Final]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [:1.0.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:324) [:6.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.1.0.Final]
at gcom.util.web.RequestControlFilter.doFilter(RequestControlFilter.java:132) [:]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:274) [:6.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.1.0.Final]
at gcom.gui.util.FiltroSegurancaAcesso.doFilter(FiltroSegurancaAcesso.java:341) [:]
at gcom.gui.util.FiltroSegurancaAcesso.doFilter(FiltroSegurancaAcesso.java:318) [:]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:274) [:6.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.1.0.Final]
at gcom.gui.util.FiltroLimparSessao.doFilter(FiltroLimparSessao.java:96) [:]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:274) [:6.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.1.0.Final]
at gcom.gui.util.FiltroAtualizarQuadroAvisos.doFilter(FiltroAtualizarQuadroAvisos.java:69) [:]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:274) [:6.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.1.0.Final]
at gcom.gui.util.FiltroSessaoExpirada.doFilter(FiltroSessaoExpirada.java:158) [:]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:274) [:6.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.1.0.Final]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [:6.1.0.Final]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [:6.1.0.Final]
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:181) [:6.1.0.Final]
at org.jboss.modcluster.catalina.CatalinaContext$RequestListenerValve.event(CatalinaContext.java:285) [:1.1.0.Final]
at org.jboss.modcluster.catalina.CatalinaContext$RequestListenerValve.invoke(CatalinaContext.java:261) [:1.1.0.Final]
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:88) [:6.1.0.Final]
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:100) [:6.1.0.Final]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:159) [:6.1.0.Final]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [:6.1.0.Final]
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158) [:6.1.0.Final]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [:6.1.0.Final]
at org.jboss.web.tomcat.service.request.ActiveRequestResponseCacheValve.invoke(ActiveRequestResponseCacheValve.java:53) [:6.1.0.Final]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362) [:6.1.0.Final]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [:6.1.0.Final]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:654) [:6.1.0.Final]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:951) [:6.1.0.Final]
at java.lang.Thread.run(Thread.java:662) [:1.6.0_45]

20 Respostas

A

Ola @reinaldojr,

no projeto web, nos seus controllers(actions do struts) você esta injetando a interface com @EJB ? este módulo web compõe o .ear ou esta separado e apenas deployado no application server ? você tem um serviceLocator ?

esse ajuste nas chamadas lookup pode falar a respeito como fez?

abraços.

R

Bom dia amigo, agora que olhei sua pergunta pensei que haviam esquecido do meu tópico, na verdade do lado do meu actions não reconhece o @EJB, precisei usar manualmente .

public class ServiceLocator {

	private static ServiceLocator instancia = null;

	private static Context contexto = null;

	private static Map mapaHomes = null;

	private static ConnectionFactory connectionFactoryJms = null;

	private static String empresa = null;

	static {

		try {
			
			 Properties jndiProps = new Properties();
			 jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
			 jndiProps.put(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");
		     jndiProps.put("jboss.naming.client.ejb.context", true);
		     contexto = new InitialContext(jndiProps);
		     mapaHomes = Collections.synchronizedMap(new HashMap());
             instancia = new ServiceLocator();
		     connectionFactoryJms = (ConnectionFactory) contexto.lookup("java:JmsXA");
		    
			
		} catch (Exception e) {
			e.printStackTrace();
			throw new SistemaException(e);
		}

	}


    public Object getLocalHome(String jndiHomeName)
    			throws ServiceLocatorException {

    		try {
    			
    			//EJB 3.0
    			return contexto.lookup("gcom/"+jndiHomeName+"/local");
    			/*EJB 2.0
    			return (EJBLocalHome) contexto.lookup(jndiHomeName);*/
    			
    		} catch (NamingException e) {

    			throw new ServiceLocatorException(e, e.getMessage());
    		}

    	}

O modulo web compões o .ear, consigo conectar normal faço as consultas tudo blz levanta o servidor conecta todos meus ejbs na hora de retornar o objeto tenho o erro de classcastexception como estivessem em carregadores diferentes.

A

@reinaldojr, seu que a minha pergunta pode parecer boba, mas vc viu ai publicado os endereços JNDI no startup do server e aparece este recurso contexto.lookup("gcom/"+jndiHomeName+"/local"); ?

Verifica se o endereço esta mesmo correto brother.

Bom, é erro de cast, você lembra que antes quando era EJB2 vc fazia um cast para EJBLocalHome ? acredito que precise fazer igual pois você retorna um object.

R

Sim amigão não so vi a publicação no JNDIView como também testei via um recurso da IDE do eclipse passando o caminho a respeito do que você falou tem toda razão essa alteração eu fiz vou postar antes e depois para você ver como ficou.

Esse e meu método reescrito repare que ele retorna um objeto Local antes retornova o LocalHome.

public ControladorUtilLocal getControladorUtil() {
		ServiceLocator locator = null;

		try {
			locator = ServiceLocator.getInstancia();
			return (ControladorUtilLocal) locator.getLocalHome("ControladorUtilSEJB");
		} catch (ServiceLocatorException e) {
			throw new SistemaException(e);
		}
	}


Antes 

		private ControladorUtilLocal getControladorUtil() {

	ControladorUtilLocalHome localHome = null;
	ControladorUtilLocal local = null;

	ServiceLocator locator = null;

	try {
		locator = ServiceLocator.getInstancia();

		localHome = (ControladorUtilLocalHome) locator.getLocalHome(ConstantesJNDI.CONTROLADOR_UTIL_SEJB);
		local = localHome.create();

		return local;
	} catch (CreateException e) {
		throw new SistemaException(e);
	} catch (ServiceLocatorException e) {
		throw new SistemaException(e);
	}

}

Repare a modificação apesar de ter o nome localhome no servicelocator mas foi reescrito para migração.

Antes da Migração olha o que meu metodo retornava

public EJBLocalHome getLocalHome(String jndiHomeName)
			throws ServiceLocatorException {

		try {

			return (EJBLocalHome) contexto.lookup(jndiHomeName);
		} catch (NamingException e) {

			throw new ServiceLocatorException(e, e.getMessage());
		}

	}

Se você olha minha resposta anterior viu que isso mudou agora retorna um object e trato no metodo acima.

A

Ahamm, entendi, e parece tudo certo, deixa pensar um pouco… :slight_smile:

A

você tem um ejb-jar.xml ?

R

na verdade ainda tenho alguns como eram muitas classes eu usei um Jdom para ler arquivos XML pegar a classe que eu quero incluir os @Stateless onde necessario @EJB e nas interfaces @Local, alguns exclui e outros ainda estão mas como na hora que subiu o JBoss não mostrou nem um erro acabei deixando.

A

eu acredito que eles precisam estar mapeados, eu não lembro se o jboss as6 implementa JavaEE6 mas acho que você pode tentar injetar com @resource, ex:

@Resource(lookup = "java:global/seuBean")

da uma olhada nisso por favor:
JNDI Lookup on Jboss-as-6-0

R

Vou fazer alguns testes como no exemplo, a tarde lhe dou um retorno.

R

Ops voltando agora ao projeto de migração a respeito do post vou postar algumas ressalvas

R

Vou postar a classe desde o inicio para melhor entendimento do erro. Na linha onde consta SistemaParametro sistemaParametro = fachada.pesquisarParametrosDoSistema(); ,
faço uma pesquisa dessa forma vou postar os métodos de depois o log.

public class CarregarParametrosAction extends GcomAction {
	
//	@EJB(lookup="gcom/ControladorUtilSEJB/local")
//	private ControladorUtilLocal controladorUtilLocal;

	public ActionForward execute(ActionMapping actionMapping,
			ActionForm actionForm, HttpServletRequest httpServletRequest,
			HttpServletResponse httpServletResponse) throws ControladorException {

		ActionForward retorno = actionMapping.findForward("telaLogin");

		Fachada fachada = Fachada.getInstancia();

		// instacia a variavel de aplicacao tituloPagina com o valor cadastrado
		// em sistema parametro.
		if ( !Util.verificarNaoVazio((String)servlet.getServletContext().getAttribute("tituloPagina"))) {

			// Recupera o objeto que contém os parâmetros do sistema
			SistemaParametro sistemaParametro = fachada.pesquisarParametrosDoSistema();

			
			servlet.getServletContext().setAttribute("tituloPagina",sistemaParametro.getTituloPagina());
			servlet.getServletContext().setAttribute("logoMarca",sistemaParametro.getImagemLogomarca());
			servlet.getServletContext().setAttribute("nomeEmpresa",sistemaParametro.getNomeAbreviadoEmpresa());

			if( Util.verificarNaoVazio(sistemaParametro.getUrlhelp())){
				servlet.getServletContext().setAttribute("urlHelp",sistemaParametro.getUrlhelp());
			}
			if( Util.verificarNaoVazio(sistemaParametro.getIndicadorSenhaForte().toString())){
				servlet.getServletContext().setAttribute("indicadorSenhaForte",sistemaParametro.getIndicadorSenhaForte().toString());
			}
		}

		if ( !Util.verificarNaoVazio((String)servlet.getServletContext().getAttribute("rodapePagina"))) {

			// Recupera o objeto que contém as datas de Implementacao e
			// alteracao do Banco			
			DbVersaoBase dbVersaoBase = fachada.pesquisarDbVersaoBase();

			if ( dbVersaoBase != null ) {

				String versaoDataBase = Util.formatarData(dbVersaoBase.getVersaoDataBase());

				servlet.getServletContext().setAttribute("versaoDataBase",versaoDataBase);
			}
			
			try {
				
				if (ServiceLocator.getResource("java:/BatchDS") != null) {
					
					servlet.getServletContext().setAttribute("versaoTipo", "Batch");
				}
				else{
					
					servlet.getServletContext().setAttribute("versaoTipo", "Online");
				}
			} 
			catch (ServiceLocatorException e) {
				
				e.printStackTrace();
			}
		}

		
		Internacionalizador.setLocale(
				(Locale)httpServletRequest.getSession(false).getAttribute(Globals.LOCALE_KEY));
		
		Internacionalizador.setProperties(
				(PropertyMessageResources)servlet.getServletContext().getAttribute(Globals.MESSAGES_KEY));

		return retorno;

	}
}

A classe acima chama a Classe Fachada.java o metodo pesquisarParametrosDoSistema(), e o dentro do método a chamada do metodo getControladorUtil().

public class Fachada {

	public SistemaParametro pesquisarParametrosDoSistema() {
		try {

			SistemaParametro sistemaParametro = getControladorUtil().pesquisarParametrosDoSistema();
			return sistemaParametro;
			
		} catch (ControladorException ex) {
			throw new FachadaException(ex.getMessage(), ex, ex.getParametroMensagem());
		}

	}

public ControladorUtilLocal getControladorUtil() {
	ServiceLocator locator = null;

	try {
		locator = ServiceLocator.getInstancia();
		return (ControladorUtilLocal) locator.getLocalHome("ControladorUtilSEJB");
	} catch (ServiceLocatorException e) {
		throw new SistemaException(e);
	}
}

}

Chamand a classe

@Stateless
public class ControladorUtilSEJB implements ControladorUtilLocal{
	// public class ControladorUtilSEJB implements SessionBean {
	private static final long serialVersionUID = 1L;
    
	@EJB(beanName = "RepositorioUtilHBM", name = "repositorioUtilHBM")
	IRepositorioUtil repositorioUtil;

	SessionContext sessionContext;

	public SistemaParametro pesquisarParametrosDoSistema()
			throws ControladorException {
		try { 
			return repositorioUtil.pesquisarParametrosDoSistema();
		} catch (ErroRepositorioException ex) {
			sessionContext.setRollbackOnly();
			throw new ControladorException("erro.sistema", ex);
		}

	}

}

Repare a parte do log agora, o mesmo conecta no banco faz a consulta tanto que mostra no log e retorna, na hora de carregar o mesmo objeto da o erro.

server.log (27.7 KB)

A

Ainda acho que é erro no endereço da JNDI, não ficou claro para mim mas você esta fazendo o lookup como java: certo? faze ele pegar de java:global não conheceço toda arquitetura do seu software mas eu acredito que se suas interfaces locais estivessem anotadas com @Remote daria certo, pode testar para nós ?

R

Minha Interface

@Local
public interface ControladorUtilLocal {

	public SistemaParametro pesquisarParametrosDoSistema() throws ControladorException;

}

Minha Classe

@Stateless
public class ControladorUtilSEJB implements ControladorUtilLocal{

@EJB(beanName = "RepositorioUtilHBM", name = "repositorioUtilHBM")
IRepositorioUtil repositorioUtil;

public SistemaParametro pesquisarParametrosDoSistema()
		throws ControladorException {
	try { 
		return repositorioUtil.pesquisarParametrosDoSistema();
	} catch (ErroRepositorioException ex) {
		sessionContext.setRollbackOnly();
		throw new ControladorException("erro.sistema", ex);
	}

}

}

Minha Interface

@Local
public interface IRepositorioUtil {

	public SistemaParametro pesquisarParametrosDoSistema() throws ErroRepositorioException;
}

Meu Repositorio da Classe

@Stateless
public class RepositorioUtilHBM implements IRepositorioUtil{
	
	@EJB
	private HibernateUtil hibernateUtil;
	
	public SistemaParametro pesquisarParametrosDoSistema() throws ErroRepositorioException {
		
		Session sessao = hibernateUtil.getSessionUtil();

		try {
			
			SistemaParametro sis = new SistemaParametro();
			sis = (SistemaParametro) sessao.createCriteria(SistemaParametro.class).uniqueResult();
			return sis;
		} catch (HibernateException e) {
			throw new ErroRepositorioException(e, "Erro no Hibernate");
		} 

	}

}

E a minha ultima classe de conexão, esta tudo conectando normalmente .

Tive que fazer algumas alterações nas classes antes de ser usadas @Local extends javax.ejb.EJBLocalObject as interfaces e as classes de SessionBeans e tambem tive que injetar o @EJB, essas alterações fora referentes a migração tenho milhares de classes que vão ser mudadas então qualquer mudança tem que ser minima. Não uso interface remota so local devido o sistema antes não usar e se tiver que implementar uma interface remota gastaria muito tempo para colocar em varias classes.

Essas classes postadas são partes da classe fragmentos que estou usando tb não vale a pena postar toda a classe devido ser muito grande.

A

Isto me parece correto, mas a outros pontos na arquitetura, faz mais um teste por favor, remova a dependência do web-project e testa, veja se esta o jar ejb no ear(application.xml)? pois seu problema é que ele esta declarado em mais de um lugar.

R

Salve meu amigo realmente você tinha toda razão anotei minhas interfaces como @Remote tirei os @Locais e tudo funcionou bem então pontos cruciais alteração do @Local para @Remote nas interfaces e meu contexto.lookup(“gcom/”+jndiHomeName+"/local") agora pego o remote contexto.lookup(“gcom/”+jndiHomeName+"/remote"), consegui levantar dessa forma obrigado ainda não terminei a migração mas isso foi um grande avanço tem outros problemas mas o principal foi resolvido e ja consigo entrar no modulo.

R

Sobre a dependencia no application.xml ja havia removido .

A

Que legal @reinaldojr , mas não precisava ser remote :slight_smile: eu só queria que fosse um teste mesmo pois eu já desconfiava que funcionaria, mas tenha em mente que assim você expõe essas interfaces sem necessidade, o ponto é que podemos fazer funcionar da outra forma, ainda cabe um teste como disse acima :slight_smile: tem que funcionar local também, eu penso que o erro esta que este EJB esta declarado em mais de um lugar sem necessiade, mas foi boa evolução :slight_smile:

A

tem que remover do war e deixar no .ear :slight_smile:

R

pois e meu amigo ai mora o problema, o projetos deve ter mas de 100 war são vários módulos então imagina o trabalho, o que você diz tem toda razão eu sei desse problema detectei no inicio da migração, na hora que cirei o persistence.xml coloquei para detectar automático as classes, porem sempre ao fazer o HbmBinder das classes dava um erro de duplicação, solução tive que declarar uma classe a uma no persistence.xml e tirar do automático<exclude-unlisted-classes>true</exclude-unlisted-classes>. Dessa forma consegui da o Binder de todas as classes sem erro. Agora como uso também o ant para criar empacotar todas essas classes jogar no ear todos o war. Não sei como faria isso mas sei que isso pode ser o ponto chave. Mas não sei como fazer.

A

Ola @reinaldojr, pocha o cenário é complexo mesmo, requer muita análise e bastante estudo em cima dos móulos, projetos, etc… bom, não é uma migração fácil, requer muita atenção, procure registrar tudo, anotar pois as vezes esquecemos de algo, vai com calma, te desejo sorte na migração brother, a única coisa que tenho certeza é que tudo é possível fazer, as vezes apenas não custa tão barato quanto eles pensam, pois tudo tera que ser muito bem testado, mas sabe, analisando este seu cenário eu me pergunto: porque uma migração deste porte para colocar em um Jboss 6 AS né? seria ser mais lindo e maravilhoso colocar em um container que já implemente o JavaEE7, mas vai de cada empresa, acham que o suporte pago por essas licensas é útil sendo que é o código e arquitetura e um bom cenário de testes é o que vai realmente fazer toda a diferença, sendo que a comunidade avança muito mais rápido, mas são empresas e somos pagos para apenas executar, de qualquer forma o resto é pura filosofia, sucesso ai :wink:

Criado 29 de junho de 2016
Ultima resposta 25 de ago. de 2016
Respostas 20
Participantes 2