Confusion-1: I have started with EJB. There are so many types of beans out there! Other than EJB (stateful, stateless, singleton, message-driven), I am coming across more types. Would you please tell me what is a managed bean?
EJBs are the part of Java EE which provide thread-safe high performance transactional operations for your application. Do you need to read-write to a database? Do that with an EJB. Do you need to need to update multiple database and send JMS message all within a transactions so all that work is atomic? Do that with an EJB.
Typically @Stateless beans are most commonly used. They can be deployed as part of a WAR, stand-alone as part of a JAR, or bundled into an EAR. Start your application by putting everything into the WAR and if you have great need then separate them later. @Stateless beans are also great for “micro services” because they are a thread-safe pooled resource so they provide very high performance servicing requests.
@Stateful beans are like a webapp session…each session gets its own instance to store its own stuff. These aren’t used much anymore.
@Singleton beans are most commonly used for configuration and reference data. They can be deployed as part of a WAR, stand-alone as part of a JAR, or bundled into an EAR. They can be configured to automatically instantiate when the application is deployed. They can cache reference data for the lifetime of the application – use your imagination for what kind of read-only reference data your application may need. Combine this with the @Scheduled annotation to automatically refresh the cached data periodically.
@MessageDriven beans are typically used for listing to JMS topics or queues for messages to process. Very valuable, but not needed by all applications.
BTW, this stuff is supported by a server that implements a the full Java EE specification or one that implements the Java EE Web Profile. Payara, WildFly, and TomEE are good. Avoid using Tomcat…it’s just Servlet/JSP container and as such lacks may of the Java EE features.
As the Java EE specification evolves, it’s looking like the having a separate specification defining the EJB components will eventually go away and a lot of the functionality that EJBs provide will move into the CDI specification. Every application (typically) needs thread-safe transaction management so in my opinion they are essential. Question is do you use functionally provided to you by your EE server or roll your own solution?
Confusion-2: I see that EJB's are sometimes referred to as CDI beans. What are these CDI creatures actually?
Context and Dependency Injection (CDI) is a completely different specification from EJBs. CDI is the Java SE and Java EE standard for doing dependency injection for your code. As the Java SE and Java EE standard, its preferable to use over other 3rd party dependency injection frameworks because your code is much more portable for use with either Java SE or Java EE applications because it avoids class path and backward compatibility issues.
From the standpoint of history, EJB components were part of the Java EE specification right from the beginning because of critical need for a component to handle transactional operations. A few years later, CDI was added to the Java EE specification to provide a standard for dependency injection.
Confusion-3: Are all types of beans (EJB, managed, entity, CDI, others I have not seen yet) sup posed to conform to the Java Beans Model by defining SET and GET methods? Is that a mandatory requirement?
No, it’s not a requirement. The Java Beans model is most heavily used by JPA and JSF. JPA is the Java SE and Java EE ORM standard, so it’s @Entity classes typically follow the Java Beans getter/setter because you need to get and set your data. JSF is the Java EE standard web view technology and it relys on the Java Beans model for mapping data coming in from HTTP GET/POST to Java objects.
Confusion-4: From my Java EE client application, I can easily obtain a reference to a stateless session bean with the @EJB annotation. But I am having a hard time trying to distinguish between @EJB, @Inject, and @Resource.
@EJB was the very first dependency injection supported by Java EE. @EJB came before the CDI specification existed for Java EE. Once the CDI specification became part of Java EE, it’s @Inject tag could anything, including instances of EJBs. So there is some overlap between the two. There are some very subtle differences between using @EJB and @Inject and it’s one of those things that if you have a need for the subtle difference then you’ll know about it – you’re using a remote EJB. Using @Inject is preferred and will be correct the majority of the time. Using @Inject is used for injecting instances of classes from you’re application’s code. The @Resource annotation also does dependency injection but thing of using @Resource as a way to get something from your application server – an EntityManger for JPA, a JNDI variable, etc.
Confusion-5: Regarding message driven beans, what is the difference between a MessageDrivenContext and transaction context? When would I prefer one to the other?
I’m not too familiar with messaging so I won’t comment on this one.
Confusion-6: Where does a messaging service provider fit in the n-tier hierarchy? The EIS tier? Aren't queues/topics part of the messaging service provider? Then why is a queue configured separately for use with Glassfish MQ?
GlassFish comes with its own messaging server and yes, you use the GlassFish admin console to setup queues and topics your application needs to use. How you use messaging in your application is outside the scope of a quick discussion, but, in general your code should always connect to a topic or queue provided by the application server and not have any concern for how the queue or topic is actually configured. For example, the queue may be using the messaging server provided by GlassFish or the queue may be connecting to a messaging server at another company you want to do business with. Your application doesn’t care about the details…it just know that the queue I want to connect to is bound to “java/com/env/jms/myqueue” and that’s it. The messaging servers take care of all the nasty details of making sure no message gets lost and all messages eventually get delivered.
Confusion-7: This is giving me a really hard time. JDNI. I know that java:comp/env is a naming space/environment that is private to each EE component, but what is its role actually? Is it us ed when a component attempts to find a reference by using portable global JDNI lookup? Is it used when a component attempts to find a reference by using @EJB?
JNDI namespaces are confusing. Here’s a summary:
Lookups in this namespace are scoped per component. For example, an EJB is a component, so each EJB in a JAR file gets its own unique java:comp namespace. This means both AccountEJB and CartEJB can look up java:comp/LogLevel and get different values. For backward compatibility, this isn’t true for the web module. All components deployed as part of a WAR share the same java:comp namespace. It’s unlikely you’ll use this namespace very often. It’s mostly there for backward compatibility. Prior to Java EE 6, java:comp was really the only standard namespace.
Lookups in this namespace are scoped per module. All components in the module share the java:module namespace. An EJB-JAR file is a module, as is a WAR file. For backward compatibility, the java:comp and java:module namespaces are treated identically in web modules and refer to the same namespace. You should favor the use of java:module over java:comp when possible.
Lookups in this namespace are scoped per application. All components in all modules in the application share the java:app namespace. An EAR is an example of an application. All WARs and EJBs deployed from the EAR would share
Lookups in this namespace are global and shared by all components in all modules in all applications.
In general, Java EE applications are supposed to be configured like this. Suppose you need a database DataSource so you can read/write from a database. Your application code can use a JNDI lookup like this to get it: ctx.lookup(“java:module/env/jdbc/myoracledb”). Now when you go to your application server’s admin console and you create a database connection pool, your application server (this is application server specific) may put the DataSource in JNDI at “java:global/jdbc/OracleProdDB”. At this point your code is different than the application server, but that’s OK. At this point you would look at what application server-specific configuration files you can include in you WAR that specify a configuration to map java:module/env/jdbc/myoracledb to java:global/jdbc/OracleProdDB so your application code can actually find the resource.
Because this can get so confusing, it’s typically better to stick with the annotations which inject the resources and figure it out for you.