0

I'm trying to integrate StarMX framework (https://github.com/rogeriogentil/starmx) into a legacy web application. This framework uses JMX techonology and is initialized using the Singleton pattern: StarMXFramework.createInstance(). The web application uses Java EE 6 technologies such as EJB and CDI (also DeltaSpike). However, the way the framework is being initialized (code below) doesn't add its instance to the CDI context.

import org.starmx.StarMXException;
import org.starmx.StarMXFramework;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Singleton;
import javax.ejb.Startup;

@Startup
@Singleton
public class StarMXSingleton {

    private StarMXFramework starMX;

    @PostConstruct
    public void postConstruct() {
        try {
            starMX = StarMXFramework.createInstance();
        } catch (StarMXException e) {
            (...)
        }
    }

    @PreDestroy
    public void preDestroy() {
        if (starMX != null) {
            try {
                starMX.shutdown();
            } catch (StarMXException e) {
                (...)
            }
        }
    }
}

I know that is possible to extend CDI, but is it possible to add an instance of singleton framework to CDI context?

rogerio_gentil
  • 359
  • 1
  • 4
  • 17
  • 1
    Like this? https://stackoverflow.com/questions/16534728/please-explain-the-produces-annotation-in-cdi – Kukeltje Aug 12 '19 at 17:36

1 Answers1

3

There are two ways, first and easy one is a producer. Here is a link to what CDI producers are and how they work. In short, CDI will use this producer to create the instance of a bean whose types are mandated by the return type of the producer method. The producer method has to be placed inside a CDI bean so that is it picked up by CDI. Note that the scope of the producer affects how often it will be invoked, just as it would be with standard bean. Here is how it could look like:

@ApplicationScoped
public class SomeCdiBeanInYourApplication {

  @Produces //denotes producer method
  @ApplicationScoped // scope of produced bean, use CDI scope (the singleton you have is EJB annotation)
  public StarMXFramework produceMxFramework() {
    return StarMXFramework.createInstance();
  }
  
}

Second means is then CDI extension, namely a lifecycle observer for AfterBeanDiscovery event where you can addBean(). Here is a link to CDI 2.0 spec, feel free to browse older versions based on what version you are on. I won't write code for that as it is rather complex and long, the producer should do the trick for you.

See also

Community
  • 1
  • 1
Siliarus
  • 6,393
  • 1
  • 14
  • 30
  • Thanks @Siliarus for your excellent explanation, but I think that I didn't clarified the question very well. The StarMX is a framework that stays running after you start it. Unlike most common implementations, I won't use anything like `@Inject StarMXFramework starmx;` to obtain the produced object. I need to get (or put) another class in the CDI context. Now, I don't know if it's better to edit this question or create other to explain it better. – rogerio_gentil Aug 13 '19 at 20:38
  • 1
    Probably make another one. But you cannot really "put class into context" in CDI, that is done via bean creation at which point the contextual instance is stored in the context for as long as the context lives. I guess the question is, why do you need to have that object in the context in the first place? – Siliarus Aug 14 '19 at 08:06
  • StarMX enables defining actions based on events or timers via an XML file. So, when a JMX notification is sent (fired), the StarMX can capture it, invoking a class and processing a method that class. However, StarMX doesn't capture JMX notification in a project that uses CDI (with DeltaSpike). – rogerio_gentil Aug 20 '19 at 18:43