0

In my web project, I have these components:

  1. EJB annotated class UserService
  2. EJB annotated class UserDAOImpl
  3. SessionScoped Managed Bean called UserStateBean
  4. ViewScoped ManagedBean called AdminDashboardView

The EJB UserService, is created at the init method (that is annotated with PostConstruct) of the UserStateBean and the UserDAOImpl is created at the init method of UserService, likewise.

Questions:

  1. Are these EJB classes stateless? (Haven't used any annotation above it, except for @EJB) If not, should they be?
  2. At the AdminDashboardView, I need to access the UserService EJB. Which is the proper way of doing that?

What I've already tried for (2):
At the AdminDashboardView, I declared it as a member, like this:

@EJB
private UserService userService;

At the init function I have this: userService = new UserService();.
This worked just fine, and succeeded with what I wanted to do, but, is this the correct way of doing that?

My thoughts on this, is that it could be correct, as the new instance of the UserService EJB I get, is from a pool that the container has (source). Is this correct?

Community
  • 1
  • 1
Chris
  • 3,619
  • 8
  • 44
  • 64

1 Answers1

3

Absolutely not!

You aren't supposed to create EJBs yourself like as that you aren't supposed to create JSF/CDI managed beans yourself. What you've there is a manually created and managed instance completely outside control of EJB container. If the EJB class in turn contained a @PersistenceContext, or another @EJB, then it would stay null, etc. Also that manually created instance has totally no notion of proxying and transaction management. The new works this way exactly like inside a main() method.

Put @Stateless on the EJB class and get rid of manual creation in @PostConstruct. The @EJB basically already injects it (like as that a @Inject basically already injects any @Named). The @EJB supports injecting of @Stateless, @Stateful and @Singleton classes.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you for the reply, but I am still struggling with the initialization of the `UserService` `EJB`. 1) First of all, it should be declared `Stateless` as it only contains a `UserDAO` `EJB` and it has actions on business logic such as find a User etc.., right? 2) The declaration of the `UserService class` is exactly this: `@Stateless public class UserService implements Serializable` and into the `UserStateBean` there's this `@EJB private UserService userService;` but still when I click the `login` button which calls the equivalent function of the `UserStateBean`, the `userService` is null. – Chris Aug 30 '14 at 19:12
  • What container are you deploying to? Apparently it doesn't support EJB natively or has it disabled somehow. By the way, explicitly implementing `Serializable` is unnecessary. EJB does it all by itself via autogenerated proxies as answered on your previous question. – BalusC Aug 30 '14 at 19:18
  • I am deploying to Tomcat 7 (I was requested/constrained to use this Servlet Container). OK, removed the Serializable related code! So I've tried adding EJB support, enabling the framework from IntelliJ, and now I can see via the `Java Enterprise` tab of the IDE, the `UserService` EJB with a green square (probably indication of sth working) but again the `userService` `EJB` is null, and getting this [NPE](http://pastebin.com/WPJVsb51). Are there any more steps to take for the initiallization of the `EJB`? – Chris Aug 30 '14 at 19:42
  • Tomcat is a barebones JSP/Servlet container. Just having EJB API present during compiletime doesn't make it to work magically on Tomcat during runtime. You need to install an EJB implementation like OpenEJB on Tomcat (like as that you needed to install a JSF implementation on Tomcat because it doesn't support it natively; from the *entire* Java EE API, Tomcat only natively supports JSP, Servlets and EL (and JNDI). You'd better replace that thing by a true Java EE container, such as TomEE (Apache minded) or WildFly (Oracle/JBoss minded). EJB'll work out the box without any extra effort. – BalusC Aug 30 '14 at 19:52
  • And, you'd better reconfigure your IDE to take only Tomcat-supported libraries in compiletime classpath ("build path") so that you don't hit this wall again sooner or later with another Java EE provided API which isn't supported by Tomcat, such as JavaMail, CDI, Bean Validation, JPA, JTA, JMS, etc. – BalusC Aug 30 '14 at 19:53
  • Unfortunately, I probably can't change to another Application Server :/ I am now trying to integrate OpenEJB with Tomcat, if no success there, I might ask another question. You mean something like changing the scope of the Dependencies from `Compile` to `Runtime` or `Provided` (if so, in to which one of the two? And also, how could it find the `jars` afterwards - _This should be a really stupid question here, but I am just starting with Java EE/Web and application servers_) – Chris Aug 30 '14 at 20:02
  • Tomcat only provides JSP, Servlet and EL out the box. So only those can be set to "provided". If you instead set the entire Java EE API to "provided", then Maven and your IDE will also assume that you're developing for a true Java EE application server and won't give warnings/errors when you use an API which isn't at all provided by the target container Tomcat. – BalusC Aug 31 '14 at 06:46
  • I saw in your new question that you picked GlassFish. You'd better not do that. Check last paragraph of [this answer](http://stackoverflow.com/a/25339225/157882). – BalusC Aug 31 '14 at 19:05
  • I was going to post here to tell you this, but you beat me to it. Thanks a lot for the pointer, should I try TomEE? What do you recommend? – Chris Aug 31 '14 at 20:29