Adam Bien's Weblog

Wednesday Feb 09, 2011

Dependency Injection Performance in Java EE 6: Dependent (easy) vs ApplicationScoped ("optimized")

Is the simplest possible Java EE 6 Dependency Injection fast enough?

In Java EE 6 you can inject POJOs with @Inject. In this case the lifecycle of the POJO will be dependent on the lifecycle of the injection point. See also Simplest Possible POJO Injection Example With Java EE 6. Injection of POJOs, however, could affect performance: in worst case each request would create a new instance. To test the difference an ApplicationScoped (in fact a singleton) bean will be injected into a Stateless Session Bean as well as a Dependent Scope (an arbitrary POJO) to measure the difference. The code for the application scope bean:

public class Bean {
    public long get() {
        return System.currentTimeMillis();
    }
}

@Path("application")
@Stateless
public class ApplicationScopeTester {

    @Inject
    ApplicationScopedBean bean;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String get(){
        return String.valueOf(bean.get());
    }
}

@ApplicationScoped
public class ApplicationScopedBean extends Bean{}


...and dependent scoped:

@Path("dependent")
@Stateless
public class DependentScopeTester {

    @Inject
    DependentScopedBean bean;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String get(){
        return String.valueOf(bean.get());
    }
}

public class DependentScopedBean extends Bean {}


The test was performed with JMeter with the following settings:
500000 Samples, 5 Threads, no think time, with attached VisualVM.

The results are interesting. The performance of the ApplicationScoped bean is only 3.5% better. In most measurements the performance was identical and around 3300 - 3500 transactions / second. Each request was handled by a Stateless Session Bean without any configuration, so each method invocation initiated a new transaction.
The reason for this result is the Stateless Session Bean and its pooling behavior. In Java EE 6 a Stateless Session Bean as a boundary / facade is not only the simplest, but also a reasonable choice.

There was no difference in GC behavior, or CPU usage: CPU Usage 50%, GC Activity 7%, RAM usage 70 MB

ScopeAverageMinMaxTransactions/Sec
Dependent10953248.96
ApplicationScoped10203366.41

The tests were performed with JDK 1.6 Glassfishv3.1 RC2 without any modifications. The entire projects with JMeter load script was pushed into: http://kenai.com/projects/javaee-patterns/, project DependentVsApplicationScopePerformance.
[Thanks Mark Struberg for the idea for this post!]


Special Event: Java 8 with Java EE 7: "More Power with Less Code", 13th October, 2014

A book about rethinking Java EE Patterns

Comments:

2 EJBs, 3 ManagedBeans & 2 RESTful services in less than 50 lines.

Amazing.

JEE 6 - plain as in "POJO"...

Cheers,
Jan

Interesting result, btw ;-)

Posted by jan groth on February 09, 2011 at 03:00 PM CET #

2 EJBs, 3 ManagedBeans & 2 RESTful services in less than 50 lines.

Amazing.

JEE 6 - plain as in "POJO"...

Cheers,
Jan

Interesting result, btw ;-)

Posted by Jan Groth on February 09, 2011 at 03:01 PM CET #

@Jan,

the best of all - almost no XML. Except a file beans.xml with the content <beans/> :-)

thanks for your comment!,

adam

Posted by adam-bien.com on February 10, 2011 at 01:29 AM CET #

Hi Adam. When you inject a @Dependent bean, it must be created. When you deploy a normal-scoped bean, like @ApplicationScoped, a proxy for it has to be created or looked up in a cache or whatever, and on GF as far as I know, the actual instance is created lazily. As such, I am surprised that the @Dependent scope was slower.
What did you test actually?

Posted by jambalaya on February 14, 2011 at 04:09 PM CET #

Hi Adam,

How different is dependency injection between J2EE 6 and Spring ? Can you please shed some light ?

Thanks
Javin

Posted by Javin Paul on February 14, 2011 at 05:49 PM CET #

Adam, i have a JSF-managed-bean web app AND a CDI-managed-bean web app variant that I'd love to compare the performance of the two on Glassfish 3.1.2.2.

Currently, the JSF-managed-bean web app is running super super fast on a Windows Server 2003 32bit 4GB RAM 'production' server, and there are 'still' some outstanding optimizing that I can do to the xhtml pages (such as eliminate any/all rendered="#{bean.attribute}" and maybe/possibly write some bean-managed-transactions to retrieve data from multiple tables in the database, so I can render all that data on my xhtml pages.

Currently, I am using JPA queries (dynamic SQL SELECT statements and @Entity named queries) by way of SessionFacade @Stateless EJBs (originally, that code was 'generated' by NetBeans 7.0 generate-JSF-pages-from-database-or-entity-classes).

Of course, that JSF web app has PrimeFaces and MyFaces 2.1.9 helping to speed up the performance 'and' usability and 'stability'. I scan my server/error log every now and then for 'exceptions' like null pointer exceptions, and try to 'fix' every exception that shows up in Glassfish server log. Just last night, I scanned that server log and saw 'no' errors except some GSON exception related to Google Calendar API, that I call to push/publish 'schedule' data to Google Calendar.

I spent the last 2 weeks 'trying' to migrate the JSF-managed-bean web app to CDI-managed-bean web app. Now, the CDI-managed-bean web app runs on TomEE1.5+ SNAPSHOT, but will 'not' run on Glassfish 3.1.2.2/WELD. EBKC? Yes, i don't mind taking the blame for my inability to interpret all the jboss/weld CDI documentation out there and my loyalty to and trust in NetBeans/Glassfish for being able to solve any/all java-related-tasks.

Last but not least, I am glad to say that the Glassfish3.1.2.2/JSF-managed-bean web app runs really really fast (pages are rendered in 2-to-3 seconds or less) while TomEE1.5+/CDI-managed-bean web app runs really really slow (on same server, some pages rendering between 5 and 15+ seconds), also while the Glassfish3.1.2.2/CDI-managed-bean web app does 'not' run at all!

conclusion: Glassfish3.1.2.2/JSF-managed-bean web app wins my vote, but I'd like you to prove me wrong! I would love to get my CDI-managed-bean web app running on Glassfish 3.1.2.2 'faster' than JSF-managed-beans. :)

Posted by Howard W. Smith, Jr. on December 01, 2012 at 11:21 PM CET #

Post a Comment:
  • HTML Syntax: NOT allowed
realworldpatterns.com
...the last 150 posts
...the last 10 comments
Links
License