Lifecycle of @Applicationscoped at Ear

Asked

Viewed 463 times

1

I have an application with several WEB modules and an EJB inside an EAR as shown below: inserir a descrição da imagem aqui

In the EJB module I created a class annotated with @ApplicationScoped, my goal is for this class to store information that must be passed between WEB projects.
It happens that when adding information in the class in the project Portaltrainingsweb they are not visible in the project Moduloaluno for example.

Follows code of the class that is annotated with @ApplicationScope

@ApplicationScoped
public class ServiceAutenticacao {

private Map<String, Colaborador> mapaTickets = new HashMap<String, Colaborador>();


public ServiceAutenticacao(){
    System.out.println("Objeto service Autenticação criado...........................");
}

public void adicionaColaborador(String ticket, Colaborador colaborador){
    this.mapaTickets.put(ticket, colaborador);
}


public Colaborador getColaborador(String ticket) throws ServiceException{
    if(mapaTickets.containsKey(ticket)){
        return mapaTickets.get(ticket);
    }else{
        throw new ServiceException("Ticket de autenticação inválido: " + ticket);
    }
}
}

It follows how I write information on the object of this class in the project Portaltrainingsweb:

@ManagedBean
@SessionScoped
public class PrincipalController {

@Inject private ServiceAutenticacao serviceAutenticacao;

public void redirecionaModuloAluno(){
    //pendura o colaborador com um ticket no Servico de Autenticação entre projetos
    String ticketInterno = UtilService.generateOid();
    this.serviceAutenticacao.adicionaColaborador(ticketInterno , this.colaboradorAutenticado);

    HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
    String url = req.getRequestURL().toString();
    String urlModuloAluno = url.substring(0, url.length() - req.getRequestURI().length()) + "/ModuloAluno/autenticacao/autenticacao.jsf?ticketinterno="+ticketInterno;

    FacesContext context = FacesContext.getCurrentInstance();

    try {
        context.getExternalContext().redirect(urlModuloAluno);
    } catch (IOException e) {
        e.printStackTrace();
    }

}

And how I try to get this information in the project Moduloaluno:

@ManagedBean
@RequestScoped
public class AutenticacaoController {

@Inject private ServiceAutenticacao serviceAutenticacao;

Colaborador colaborador  = serviceAutenticacao.getColaborador(this.ticketInterno);
            System.out.println("Colaborador: " + colaborador.getNome());
            principalController.setColaboradorAutenticado(colaborador);

I put a System.out in the class constructor ServiceAutenticacao and I realized that she’s being instantiated over and over again. So my question is, the object noted with @ApplicationScope is the same among several projects of the same EAR ? If so, would you tell me why I can’t access the information on the other project(ModuloAluno)

  • 1

    Which application server are you using? Is it possible to test on another? The deploy is being done all together within the EAR, right? Multiple instantiation is not necessarily a problem since some instances will be proxies, so I suggest using a method with annotation @PostConstruct instead of the constructor to place the println. Hashmap startup can also be moved to the @PostConstruct (not q this will solve the problem but it is + correct). I also suggest testing @javax.ejb.Singleton to see if it works differently from @ApplicationScoped

  • I am using Wildfly 9 as a server. deploy is all together within the same EAR. I will try to make some adjustments to test on another application server. I changed the map startup and syso to a method @postconstruct and I noticed that the call now occurs only twice. I also switched to @Singleton using @EJB to fetch the object. I noticed that when I go to get information on the map by the second project it is empty and no longer has the information I filled in.

  • In the startup logs or in the server configuration web interface does it say anything? (i.e., does it inform what is being considered as a single application and what is separate - I don’t know if it has changed much since Jboss AS 7 to Wildfly 9)

  • It’s really weird, I went through everything, the web interface of the server says it’s all packaged inside the same EAR. I copied exactly the code of another application that works and the same error occurs. I can only recreate the projects to make a test.

1 answer

1


I found this bug/Issue in Jboss: https://issues.jboss.org/browse/CDI-129

What it says there is that the operation was not specified completely and the decision that @Applicationscoped is instantiated once only by EAR (rather than once by WAR) is relatively recent, so it may not be working as desired on current servers.

In a quick read, I saw that only in CDI 2.0 we will have this behavior (1 instance by EAR) guaranteed :(

  • Lí the Issue, really then we have to use @javax.ejb.Singleton for the time being the only guarantee that we have to have a single one in all projects of the same EAR. Thank you for the help.

  • Ah, did @Singleton work? Good, it had not been clear in the other comment and I was already thinking about suggesting much more different/complicated things, like using the database, or making a web service just for that (Argh), or trying a beta version of CDI 2.0 (Ugh).

  • Actually it didn’t work, it’s the same case. I think it has something to do with packaging, because the web projects are referencing ejb in the Deployment Assembly configuration as a jar. I don’t know if this can affect anything.

  • For me, it seems right to do so... I probably never noticed problem because I only used @ApplicationScoped and @Singleton for caches or Lazy-loading settings. It is then the idea to pass your Map to the database... :-/

  • 1

    I managed to solve it. I recreated the entire structure of the empty projects in the eclipse. Then I copied all the source files for the projects again and made sure that the settings were correct as described in the link: http://stackoverflow.com/questions/7591056/classes-of-referenced-ejb-project-not-found-in-the-referencing-web-project] and it worked perfectly, I haven’t changed a single line of code. The only explanation I see is some bug in the eclipse during the deploy or something.

  • I marked the answer as correct because given the description of my problem being a question about the scope of @applicationscoped it is illuminating and solves the problem. Although my problem is something of configuration.

  • Interesting. This means that it is actually possible to achieve both behaviors depending on how the project is configured and/or how the deploy is done. If I ever find out which.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.