Loading...
Important Notice - Forums is archived

To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Product icon
TUTORIAL

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.

CDI & ThreadLocal

Dmitri Livotov
1 decade ago May 19, 2010 11:53am

We finally figured out the problem why ThreadLocal pattern does not work when Vaadin application instance is created on JEE6 compatible app server using CDI.

The main problem is that when you're using injections and inject the SessionScoped application instance to a application servlet, actually this becomes not your application instance but the generated proxy class - this is done by the CDI congtainer transparently. This proxy class extends your actual class and delegates all methods invocation to an correct actual, real instance of your class.

But this is the reason, why the following code in the ThreadLocal pattern does not work anymore:

public void transactionStart ( Application application, Object o )
   {
       if ( application == this )
       {
           currentApplication.set ( this );
       }
   }

The "if" statement will not work here because instances will not match due to proxy object over the actual instance.

So, here is the solution to get it working back. It is backwards compatible and will work with non CDI environments.

First, in your application class, make the extra methos, which returns self. Then, in your transaction start/end listeners, tweak the condition a bit:

public class MyApplication extends Application()
{
   public MyApplication()
   {
      super();
      ...
   }

   public Application getSelf()
   {
      return this;
   }
   ...
   ...

   public void transactionStart ( Application application, Object o )
   {
       if ( application instanceof MyApplication && ((MyApplication)application).getSelf() == this )
       {
           currentApplication.set ( this );
       }
   }

   public void transactionEnd ( Application application, Object o )
   {
       if (application instanceof MyApplication && ((MyApplication)application).getSelf() == this )
       {
           currentApplication.remove ();
       }
   }

   ...
   ...
}

So, calling getSelf() in our "if" block will always return the exact instance of an application, not a proxy and ThreadLocal pattern will work fine with CDI.

I think, we need to adjust the information on a wiki (manual) for the explanation of a ThreadLocal pattern as well onthe page which describes how to use Vaadin app with JEE6 - both via CDI or SessionBean. Id make the changes but not familiar with the LifeRay's wiki, so if anyone made such changes or will give me a glue how to edit wiki pages here, Id be thankful.

Best,
Dmitri

Dmitri Livotov
1 decade ago May 19, 2010 12:03pm
Andy O
1 decade ago Dec 08, 2011 10:33am
Bobby Bissett
1 decade ago Dec 28, 2011 10:44pm