How to define own JNDI name for EJB in an ear - java

I have an ear which has ejb.jar, core.jar.
core.jar use lookup to find the bean at run time. Now the jndi path is mysystem-server-component-ear-0.0.1-SNAPSHOT/MyServiceBean/local which means <earname>/<beanname>/<localinterface>
I want to define JNDI like MyServiceBean/local. Where my MyServiceBean is the ejb bean and it use local interface.
I use EJB 3.1 without ejb-jar.xml and jboss.xml. All the wiring done through annotation.
How can I define my own JNDI name which I can lookup

Did you try #EJB(mappedName = "yourJndiName")?
If your JNDI lookups are not working as expected, then you should always check your JNDI tree from within the administration frontend (should be somewhere in jmx-console/JBoss/service=JNDIView or similar). Sometimes the name of the remote interface, etc. is added to your JNDI name by your application server.

Related

Look up a dynamic JNDI name

My application code receives the JNDI name to look up at runtime. Hence, the JNDI name may not be configured beforehand in web.xml or in the #Resource annotation. How may I lookup an Object in such a scenario? Application is running on Tomcat 7.
You can't use resource injection but have to use programmatic lookup
new InitialContext().lookup(dynamicName)

JavaEE 7: EJB jndi-name without interface

I use GF4 server and in its log I have:
Portable JNDI names for EJB com.test.cms.svr.web.Service2:
[java:global/com.test.cms.svr.web_1.0.0/com.test.cms.svr.web.Service2,
java:global/com.test.cms.svr.web_1.0.0/com.test.cms.svr.web.Service2!com.test.fw.svr.web.bundle.ComponentService]]]
My questions:
Why are there two jndi names - with interface and without interface?
Why can I get bean only using jndi-name with interface even when EJB is only local?
Why are there two jndi names - with interface and without interface?
This is an EJB 3.1 feature called portable JNDI names. Here is nice explanation from this blog:
Client applications need to use global JNDI name to lookup an EJB. All
along the ejb specifications had been silent about portability of such
global jndi names. This allowed each vendor to assign a global jndi
names to EJBs in a vendor specific way. This meant that the client
code that performed a lookup using global JNDI names were inherently
non portable across appserver vendor implementations.
EJB 3.1 solves the above problem by mandating that every container
must assign (at least one) well defined global JNDI names to EJBs. The
general syntax of a (portable) global JNDI name of an EJB is of the
form:
java:global/[<application-name>]/<module-name>/<bean-name>!<fully-qualified-bean-interface-name>
In addition to the above name, if the EJB exposes just a single client
view (that is it implements just one interface or the no interface
view), the container is also mandated to map the bean to
java:global/[<application-name>]/<module-name>/<bean-name>
Where
<application-name> defaults to the bundle name (.ear file name) without the bundle extension. This can be overridden in
application.xml. Also, is applicable only if the
bean is packaged inside a .ear file.
<module-name> defaults to bundle name (.war or .jar) without the bundle extension. Again, this can be overridden in ejb-jar.xml.
<bean-name> defaults to the unqualified class name of the bean. However, if #Stateful or #Stateless or #Singleton uses the name
attribute, then the value specified there will be used as the bean
name.
There is some additional GlassFish-specific information in the GlassFish EJB FAQ.
Why can I get bean only using jndi-name with interface even when EJB is only local?
I guess you mean a lookup from another EJB or module in the same web application inside the same JVM. Otherwise this shouldn't be possible without a #Remote interface. Here are two statements from the GlassFish EJB FAQ:
I have an EJB component with a Local interface. Can I access it from an Application Client or a stand-alone java client ?
If the EJB component is running within the server, no. The EJB Local
view is an optimized invocation path that uses call-by-reference
semantics. It is only available to web components and EJB components
that are part of the same application as the target EJB component.
To access EJB components that are running in the server from an
Application Client or stand-alone java client, you'll need to use
either a Remote 3.x Business interface, a 2.x Home interface, or web
services.
One alternative, if using GlassFish v3, is to use the EJB 3.1
Embeddable API. This allows a Java SE program to directly execute EJB
components within the same JVM, without using a server process.
I have an EJB component with a Local interface. Can I access it from a web component in a different application?
No. The EJB specification only requires access to an EJB component's
local EJB interface from within the same application in the same JVM.
One option is to package the ejb-jar in the same .ear as the .war. A
second option, if using GlassFish v3, is to package the EJB component
directly within the .war.
The GlassFish EJB FAQ also contains alot more detailed information about this topic.
See also:
Looking up an EJB dynamically
Consuming local EJB, in the same Container but different ears

How to correctly reference annotated EJB3 beans from JNDI in WAR-project

We have a multimodule Java EE 5 project running on Weblogic 10.3.x. One module has the EJBs and our batch processor is running from the web-module. Since we don't have CDI in JavaEE5, we have to do a JNDI-lookup on the EJBs. The EJBs are defined with #Stateless on the class and #Remote on the interface.
I have succeeded accessing the EJBs by looking the following string:
ejb/batchService#com.example.service.batch.ejb.BatchServiceRemote
However, I belive this is highly platformdependent, and I suspect I should have put something inside the web.xml and probably into the weblogic.xml at least in the web-module - maybe even in the EJB module...
Could anyone enlighten me how to do this propperly? Or is this the best way available?
JNDI format of local bean is
java:comp/env/BeanClassName
JNDI format for remote bean is
mappedName#com.package.BeanClassName
for
#Stateless(mappedName = "mappedName")
public class BeanClassName {
PS. This format supported by WebLogic 10.3. Behaviour of another application servers may be differentю
Prior to EJB 3.1 / EE 6, there are no standardized lookup strings for EJBs. Since they're not standardized, hard-coding the actual binding name of the EJB does make your project product-specific.
The best solution is to create another level of indirection: declare an <ejb-local-ref> in web.xml (or as #EJB/#EJBs on a servlet or other component class), and then use java:comp/env/xyz to lookup the ref. Then, use platform-specific bindings for the EJB ref.

JBoss 5.0 EAR: Locate #Service ejb local interface from struts 1 action in nested war with jndi lookup

I have a war (using struts 1) nested in an ear with session ejbs. If I lookup normal session beans from the war with lookup("earname/beanname/local") everything works. If I lookup a #Service ejb the same way it fails from the war with a NamingException.
To make sure I was doing the lookup correctly I looked up one #Service bean from another's start() method (instead of injecting with annotations) and the jndi lookup succeeded.
What could be the cause of this behavior? I am currently stuck with JBoss 5.0.
After going through the jmx-console like Nicholas recommended I was able to track down my mistake.
It turns out my two lookups were in fact different. The war was using the service name that I wanted, everything else (which was working) was using the class name of the implementation of the #Local interface.
To further the confusion I used #Service(objectName="blah") instead of #Service(name="blah").
I am now able to successfully lookup my #Service ejbs from my war.

Is it possible to use #EJB annotation to inject EJBs through different servers?

I have 2 session beans, OrderBean and InventoryBean which are deployed at different weblogic servers.
The OrderBean needs to access the InventoryBean to check if the supply is sufficient.
Currently, I use JNDI look up to locate the InventoryBean and it works fine.
Now I'm wondering if it is possible to use #EJB to inject InventoryBean by providing the JNDI name and the URL in xml or somewhere else.
Finally I found a way to do this.
i. Configure the foreign JNDI on the weblogic server and link the remote EJB to a local JNDI name.
For example:
Local JNDI:
InventoryBean#com.pkg.InventoryBean (MAPPEDNAME#FULLNAME)
link to
Remote JNDI:
ServiceBean#com.pkg.InventoryBean
ii. Configure ejb-ref in ejb-jar.xml
ejb-ref-name -> ejb/InventoryBean
remote -> com.pkg.InventoryService
mapped-name -> InventoryBean
iii. Add the #EJB annotation in OrderBean
#EJB(name = "ejb/InventoryBean")
private InventoryService inventoryService;
I think it is not possible through EJB annotations, but you can configure foreign JNDI on your WebLogic server and refer to your remote EJB as a local JNDI name. Though, I never tried that, but I think it should work.
It is very AS-specific.
JBoss 7+ makes it possible if you:
Define outbound-socket-binding, security-realm and remote-outbound-connection in the standalone file (all referring to the remote JBoss instance).
Add a jboss-ejb-client.xml to the META-INF folder of your packaged application, with a remoting-ejb-receiver for every connection needed by the application.
Inject the remote EJB with#EJB(lookup = "<jndi_name>")
Let me know if further details are needed.
Give a look at:
JBoss configuration for remote connections
An article about Glassfish-Glassfish remote connections

Categories