Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>From a <a href="http://www.java.net/forum/topic/glassfish/glassfish/redeploy-tree-0" rel="nofollow">discussion</a> on the Glassfish forums:</p> <blockquote> <p>The injected reference is updated only when a new instance that it is injected into is created by the EJB container. So if you look it up all the time, you get an instance with the updated reference, but if your code holds on to the original instance, or if it is pooled, the injected reference remains stale.</p> </blockquote> <p>So the root problem is that the reference to the EJB is <em>stale</em>. I have found two solutions to this problem:</p> <ol> <li>Look up the EJB on each request (do not use CDI)</li> <li>Wrap EJBs in a proxy that looks up the EJB if the reference is stale</li> </ol> <p>With the second solution, CDI can still be used. You'll need a <em>producer</em>, and an <code>InvocationHandler</code>. The code below is a simplified version of the code I use in my project, and it might not compile properly, but it will show the idea and concepts used in making this work. YMMV.</p> <p>First, in the code that uses the EJB, you use <code>@Inject</code>, as follows:</p> <pre><code>public class Foo { @Inject MyEjb obj; } </code></pre> <p>Second, you'll need a producer that simply returns a wrapped version of the EJB:</p> <pre><code>public class MyEjbProducer { @EJB(name = "MyEjb") private MyEjb obj; @Produces public MyEjb getEjb(final InjectionPoint ip) { InvocationHandler handler = new MyInvocationHandler(obj, MyEjb.class); return (MyEjb)Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler); } } </code></pre> <p>Third, the invocation handler needs to test for <code>NoSuchEjbException</code> and look up the bean again:</p> <pre><code>public class MyInvocationHandler implements InvocationHandler { private MyEjb obj; private Class lookupClass; public MyInvocationHandler(MyEjb obj, Class lookupClass) { this.obj = obj; this.lookupClass = lookupClass; } public Object invoke (...) { try { return method.invoke(impl, args); } catch (final InvocationTargetException e) { if (e.getTargetException() instanceof NoSuchEJBException) { // 1. look up EJB again // 2. try calling invoke again } } } } </code></pre> <p>This code is by no means complete. Some of the code, such as looking up the EJB and invoking the method again has been omitted.</p> <p>Doing it this way will work. Another method would be to do something similar, but adding a separate method to the EJBs for checking for staleness, instead of using the method that the user attempts to invoke.</p> <p>What do you think? Is there a better solution?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload