JSF + Stateless EJB performance
I have a JSF 2.0 application running on GlassFish v3. It has EJBs that serve database data via JPA for the main applications sessions. Even on non-IDE app-server, the EJB calls are very slow. Between some pages, the user has to 开发者_如何学Cwait over 10 seconds to get to the next page.
The EJB runs on the same application server, and only Local
interface is used. The EJB is injected via @EJB
annotation.
Any clues?
Thanks in advance, Daniel
EDIT See my answer for solution.
It's hard to tell without profiling the code and/or unit-testing every part in the business logic to see what step exactly takes that much time. My initial suspicion would be the DB performance. Maybe the table contains million of records and is poorly indexed which causes a simple SELECT
to take ages. Maybe the network bandwidth is poor which causes to take more time to transfer the data.
At this point, with the as far given little information, it can be everything. I'd just profile it.
At debug, the app is stuck at the EJB call for several seconds, after that it jumps inside the EJB method and it runs fine.
You need to provide more details:
- Do you use
Local
orRemote
interfaces? Is the client (the webapp) on a remote machine? - How do you access the EJBs? Are they injected? Do you perform a JNDI lookup?
- What did you measure? (either during profiling or using
System.nanoTime()
at various points) - Do the measures really show that most of the time is spent in the invocation itself?
Answering these questions should help to identify where to look and possible causes.
The problem was previously, that both Local
and Remote
interfaces had been implemented, and only the Remote
interface was used, however there is no need for that. Both interfaces had the same methods, which is something to avoid according to the NetBeans warning message I got:
When a session bean has remote as well as local business interface, there should not be any method common to both the interfaces.
More detailedly:
The invocation semantics of a remote business method is very different from that of a local business method. For this reason, when a session bean has remote as well as local business method, there should not be any method common to both the interfaces. Example below is an incorrect use case:
Remote public interface I1 { void foo();}
Local public interface I2 { void foo();}
Stateless public class Foo implements I1, I2 { ... }
So the solution was to remove the Remote
interface, and set the application logic to use the Local
interface.
精彩评论