0

What I want to achieve is to take advantage of EJB feautures and use some kind of automatic pooling.

I thought a SLSB may be suitable, when retaining a local stateless variable (don't know if it is an appropriate definition) - at least from the client/caller POV.

@Stateless
public class CommunicationService implements Serializable
{
    private Process process;

    @PostConstruct
    //@PostActivate maybe?
    public void startProcess()
    {
        try
        {
            process = new ProcessBuilder("running a temporary daemon").start();
        }
        catch(IOException e)
        {
            throw new RuntimeException(e.getMessage(), e);
        } 
    }


    @PreDestroy
    //@PrePassivate maybe?
    public void endProcess()
    {
        if(process.isAlive())
        {
            process.destroy();

            boolean terminated = false;
            try
            {
                terminated = process.waitFor(5, TimeUnit.SECONDS);
            }
            catch(InterruptedException e)
            {
                // ignore
            }

            if(!terminated)
            {
                process.destroyForcibly();
            }
        }
    }

    public int send(String message)
    {
        // do something with the process - may take a long time
        // this is just an example

        PrintStream printStream = new PrintStream(process.getOutputStream());
        printStream.println(message);

        try
        {
            return process.getInputStream().read();
        }
        catch(IOException e)
        {
            return -1;
        }
    }
}

Note that I want a pool of processes, so @Singletons are not suitable.

  1. Is this the correct use of @Stateless EJB instance variable?
  2. Is a @MessageDriven more appropriate?
  3. Is there a more EE way to achive it?

Thanks

Michele Mariotti
  • 7,372
  • 5
  • 41
  • 73
  • 1) well no because you're giving a stateless EJB state. Wrong tool for the job. 2) well no because MDBs are related to queuing, not pooling. 3) I wouldn't know what to answer to that because I don't really understand why you need a pool to begin with. What problem would you be solving using it that involves processes? – Gimby Jan 31 '17 at 09:26
  • **1)** I don't care which client access which process, I'm not sure it could be considered a *state*. **2)** You're right. I was thinking a sort of an async queue, but definitely it's not suitable. **3)** integration with legacy sw. In my specific case I'm rewriting a piece of *jodconverter*, so i need some OpenOffice instances up and running. – Michele Mariotti Jan 31 '17 at 09:46
  • Sounds more like you then indeed do need a singleton EJB which manages a "pool" of process then. Can be a simple as a list. – Gimby Jan 31 '17 at 09:53
  • The point is that I don't want to manage the pool myself. That's more about curiosity to better understanding EJBs than a real practical problem :) – Michele Mariotti Jan 31 '17 at 09:57

2 Answers2

2

Contrary to popular belief, it's quite OK to maintain state in SLSBs. It just cannot be client state. §4.7 of the EJB 3.2 Spec says:

The term “stateless” signifies that an instance has no state for a specific client. However, the instance variables of the instance can contain the state across client-invoked method calls. Examples of such state include an open database connection and an object reference to an enterprise bean object.

Therefore, this might be a workable strategy with some caveats:

  • The spec says that "stateless session bean instances are typically pooled". You would need to check that your chosen JavaEE server implementation does actually pool them, because (at least for a while there) some of them would just create a new instance every time;

  • Controlling the number of beans in the pool may be tricky. An implementation may continue to create bean instances even when the pool is full, it just never returns them to the pool;

  • If any type of RuntimeException is thrown from a business method then the bean instance will be discarded without calling the @PreDestroy callback (see §9.3.1 of EJB 3.2 Spec). This will result in process leaks in your system;

Therefore you will need to be intimate with the way in which your server manages SLSB pools.

Steve C
  • 18,876
  • 5
  • 34
  • 37
  • Currently, I'm using Wildfly 10. I'll check how it manages SLSB. The `RuntimeException`/`@PreDestroy` info is great! Thank you very much for this amazing answer! – Michele Mariotti Feb 01 '17 at 11:45
-1

For me, you need to implement a Factory method pattern ;

Read this for me information EJB Factory Class

Community
  • 1
  • 1
bilelovitch
  • 1,975
  • 1
  • 16
  • 24
  • I don't want to implement an EJB container and I don't understand how it can be useful: how is it related with automatic pool handling or SLSB instance variables? – Michele Mariotti Jan 31 '17 at 12:10
  • Regardless of technology, for implementing a pool handling the Factory pattern ise useful. – bilelovitch Jan 31 '17 at 12:51