What is a global JNDI name and why does it differ between app servers? - ejb

I am studying up on EJB 3 from the book EJB in Action and this book in chapter 5 discusses about environment naming context(ENC). It says this :
If you know how JNDI references worked in EJB 2, you’re familiar with
the environment naming context (ENC). ENC allows portability of the
application without having to depend on global JNDI names. Global JNDI
names for resources differ between application server implementations,
and ENC allows you to use a JNDI location that starts with
java:comp/env/ instead of hard-coding the actual global JNDI name. EJB
3 essentially assumes that all JNDI names used in code are local
references and automatically prepends names with the java:comp/env/
prefix.
I am not getting what is meant by global JNDI name? Why does it have to be different across app servers?
I am tagging the question as both EJB2 and EJB 3 since the quote references both the versions. Please feel free to edit if you think otherwise.

A global JNDI name uses a name in the default JNDI context. For example, on WebSphere Application Server, remote EJBs are bound by default to ejb/<app>/<module>/<bean>#<interface>. If you hardcode this lookup string in your application, then the application won't be portable to other application servers (which might use a different scheme for the default name) or even the same WebSphere Application Server if the target application or module name changes.
The solution in EE is for your application to declare an EJB reference, which will be in the java:comp/env context with a name that you choose. When a deployer installs your application on the server, they can bind the java:comp/env name to a global JNDI name that is appropriate for the environment. This same pattern is actually used by all EE resources (data sources, String/int/boolean configuration values, etc.), and when used properly, it is one of the strengths of the EE platform.
I can't tell what the excerpt above is trying to say without more context. Perhaps it's referring to the EJBContext.lookup method, which is effectively a shortcut of doing a lookup relative to java:comp/env.
As a final aside, I'll note that EJB 3.1 defines a standard location of java:global/<app>/<module>/<bean>!<interface> for EJB bindings. Regardless, it is still a best practice to use EJB references when doing lookups across applications (or even across modules if you're not in full control of the application that will contain the EJB client).

Related

Is a local client passed a direct reference to a EJB LocalBean?

When a local client gets a reference to a LocalBean, does the container provide a direct reference to bean instance? If not, what is provided?
Pointers to specs and authentic sources would be highly appreciated.
The spec does not prescribe that explicitly as I see, but injected references to EJBs are normally interface-based proxies. That's necessary for providing container services, like transaction management and timeout control, picking an instance from the pool in case of SLSB, calling user interceptors if any, etc.
While the spec only tells something rather neutral:
The container is responsible for making the business interfaces and/or
home interfaces of its deployed enterprise beans available to the
client through dependency injection and/or through lookup in the JNDI
namespace.
You can easily check that BTW, for example with debugger.

EJB or CDI in Nu Echo Rivr (VoiceXML Java library)

I’ve tried CDI injection and #EJB injection of Stateless EJBs in a Rivr dialog. They don’t work.
I’ve also tried JNDI lookup of the EJBs through the Global JNDI name but I get following error (note I am using java:global but I get this message):
A JNDI operation on a java:comp/env name cannot be completed because the current thread is not associated with a Java Enterprise Edition application component. This condition can occur when the JNDI client using the java:comp/env name does not occur on the thread of a server application request. Make sure that a Java EE application does not run JNDI operations on java:comp/env names within static code blocks or in threads created by that application. Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on java:comp/env names.
Is there anyway I can inject or locate CDI #Named or EJBs in a Rivr dialog?
thanks
Ignacio
I examined the Spring example in Rivr cookbook and found that the DialogFactories are executed in the ServletThread. This allowed me to perform a standard JNDI lookup using the Global JNDI name successfully and pass the EJBs to the Dialog being created.
Rivr team confirmed this by email and I am now successfully accessing EJBs that way.
I could not perform standard #Inject or #EJB injections but the JNDI "traditional" solution worked for me.

Difference between EJB and Servlet?

We are using ejb 2.1 to expose as a webservice using apache axis2.I have read in codebranch website that both are serverside components where in ejb can be run in more than one server unlike servlets..but I didn't get clear picture of difference.
Let me quote this old (but good) comparison.
Enterprise JavaBeans are components meant to encapsulate business logic. They do not handle presentation and have a precise set of restrictions they must obey. An EJB may not manage threads, access files with the java.io package, have a GUI, accept socket connections, or load native libraries. These restrictions are imposed because EJBs execute inside an EJB container, roughly analogous to the way servlets execute in a servlet container. Where servlets can be used to perform many arbitrary tasks, including the generation of HTML pages, EJBs are used almost entirely as business objects. A session bean represents a client for a session or transaction and an entity bean represents a persistent business object that is usually stored in a database. Unlike servlets, a single session bean may exist per client. A single servlet may serve many clients. A session bean usually mediates client access to entity beans, shielding the client from the details of managing state.
I got exact answer Both are server side entities.EJB is designed by wrapping RMI API's.EJB is a service at Enterprise level.Main advantage that EJB can be a webservice which can deployed anywhere in the world.EJB is servicelayer enity which can even used by servlets.
We can have plain java in the service layer but differance that EJB has is it(EJB) can be alone deployed in any server unlike plain-java service layer.

Web Services Model

I have 1 Site (MySite.com) / 1 Web Service (WebService.MySite.Com) and one Common Library (LibCommon)
The common Library Contains a Model e.g. UserModel = LibCommon.UserModel
The web service has a method 'Void CheckUser(LibCommon.UserModel model)'
However when I add the 'WebService' reference to 'MySite.com' the method changes so that it looks like 'Void CheckUser(WebService.MySite.Com.UserModel model)'
So I think fair enough I can just cast one object to the other as they are identical however .NET Says I cannot do this?
Is there a work around for this?
Cheers,
Note this is for WCF, and not ASMX web services:
You can't directly cast the original data class to the proxied class generated by the WCF service reference wizard. However, you can reuse the original data class in the client:
Add the library reference containing the transfer objects (i.e. LibCommon) as a reference to both the Service (WebService) and the Client (Mysite.com). When adding the service reference on the client, choose the advanced tab and then select Reuse types in referenced assemblies. This will then reuse the common data transfer classes, instead of duplicating the types with proxies.
Note however that by eliminating the proxied data class, you are introducing direct coupling between client and server - you should do this only if you have control over both client and server w.r.t. version control issues etc (e.g. able to deploy new versions of both client and server simultaneously)
As an aside, it is also possible to eliminate the shared service interface as well, by moving the server side Service contract interface into a separate, common assembly and then using a technique such as this or this.

Servlet-spec: <context-param> vs <env-entry> in web.xml?

Why does the Servlet specification define two distinct ways (context parameters and environment entries) to provide a web application with configuration parameters?
What are the respective advantages of these approaches (when should which be preferred)?
Environment entries are available via JNDI which may be useful when you don't have a ServletContext directly at hands, such as in EJBs. The one in the web.xml is actually the last in precedence chain as to overridding environment entires. They are usually definied in server's own configuration. So if one intends to override a server-specified environment entry from the webapp on, then that could be done via web.xml.
Context parameters are really specific to the webapp itself. They are only available when you have a ServletContext directly at hands, usually only inside filters, servlets (and inherently also JSPs via ${initParam.someName} in EL) and listeners. They are supposed to be used to provide configuration parameters for filters, servlets and/or listeners running in the webapplication. It wouldn't make much sense to provide them by JNDI which is an overcomplicated process for the simple purpose.

Resources