aspose file tools*
The moose likes EJB and other Java EE Technologies and the fly likes EJB3 - dependency injection fails? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » EJB and other Java EE Technologies
Bookmark "EJB3 - dependency injection fails?" Watch "EJB3 - dependency injection fails?" New topic
Author

EJB3 - dependency injection fails?

Dan Lingard
Greenhorn

Joined: Aug 12, 2009
Posts: 12
Hi all,

I'm trying to migrate an application from EJB 2 to EJB 3, and I've encountered a problem with dependency injection.

I've got a really simple bean, pretty much defined as on this tutorial: http://www.webagesolutions.com/knowledgebase/waskb/waskb032/index.html

I can deploy this to my server (WebSphere Application Server 7), run the test servlet, and everything appears to work fine.

However, when I try to use this simple bean in an existing servlet within my application, the dependency injection fails (no error message, but the object is null), and I'm stumped as to why. Is it because it exists within a different EAR to my main project?

Also, how do I use the bean if I can't use DI? I haven't defined anything in terms of deployment descriptors or JNDI files, but I don't believe that I need to. However, I don't know what the JNDI name is of my bean, so looking it up is proving a little tricky! Does anyone know how I define the JNDI name, and if this is done via the annotation?

Any help or guidance would be gratefully received!

Dan
Jaikiran Pai
Marshal

Joined: Jul 20, 2005
Posts: 10102
    
165

Does the version of WebSphere you use, support injection of beans in servlets? And that too a servlet residing in a different ear? You might have to lookup WebSphere's documentation.

If dependency injection doesn't work, then you can do a JNDI lookup. Although i am not sure, but i think WebSphere would have some admin tool which shows the jndi names of the beans that have been deployed. Once you find out that name, you can use it in your code to do the lookup.

[My Blog] [JavaRanch Journal]
Dan Lingard
Greenhorn

Joined: Aug 12, 2009
Posts: 12
Hi Jaikiranm,

Earlier versions of WebSphere did not support EJB 3, but the version I'm currently using does (or at least it says it does!).

This question is why I went back to a stand alone simple "hello world" type of bean - this deploys and works fine on my WebSphere server, using DI. My test servlet looks like this:



... and works fine. However, when I try to use my "proper" servlet from my main application, it fails.



The code is the same, which is why I'm confused - it must be some thing to do with my deployment?

Dan
Jaikiran Pai
Marshal

Joined: Jul 20, 2005
Posts: 10102
    
165

What is the xsd declaration in the web.xml of your application which is running into trouble? The "version" attribute should be 2.5
Dan Lingard
Greenhorn

Joined: Aug 12, 2009
Posts: 12
Jaikiran Pai wrote:What is the xsd declaration in the web.xml of your application which is running into trouble? The "version" attribute should be 2.5

You may be on to something here!

It looks like this:



In the project that works, it looks like this:



The stuff in the web-app element looks very different. I've no idea what this means, unfortunately, but I presume this is the root of my problem? Would just changing the web-app line to be in line with my working web.xml be sufficient?

Many thanks for your help - I've been banging my head against a wall the last couple of days trying to work out why this isn't working!

Dan
Jaikiran Pai
Marshal

Joined: Jul 20, 2005
Posts: 10102
    
165

Dan Lingard wrote:

The stuff in the web-app element looks very different. I've no idea what this means, unfortunately, but I presume this is the root of my problem? Would just changing the web-app line to be in line with my working web.xml be sufficient?

Yes, changing the web.xml to use the 2.5 version of the xsd should be enough. That would then instruct the server that you are deploying a 2.5 version of a web application. Prior versions did not have support for injection into servlets, so containers ignore the annotations in your servlet.
Dan Lingard
Greenhorn

Joined: Aug 12, 2009
Posts: 12
Jaikiran Pai wrote:
Dan Lingard wrote:

The stuff in the web-app element looks very different. I've no idea what this means, unfortunately, but I presume this is the root of my problem? Would just changing the web-app line to be in line with my working web.xml be sufficient?

Yes, changing the web.xml to use the 2.5 version of the xsd should be enough. That would then instruct the server that you are deploying a 2.5 version of a web application. Prior versions did not have support for injection into servlets, so containers ignore the annotations in your servlet.
Many thanks Jaikiran - I'll give that a try!
Dan Lingard
Greenhorn

Joined: Aug 12, 2009
Posts: 12
How odd - changing this hasn't fixed it, with helloRemote still being null.

I used some built in tools to migrate the project from 2.3 to 2.5 and then manually updated the web.xml to fix the issues that arose. It may be that all projects need to be at this level before everything works properly? I'll give that a try and let you know what happened.
Dan Lingard
Greenhorn

Joined: Aug 12, 2009
Posts: 12
Thought I'd post an update, as I think I've solved this!

The issue appears to be because the EJB I'm trying to inject is in a different EAR to the servlet I'm trying to inject it into. As a result, the look up fails. However, if I give it the full JNDI name like so:


It all appears to work. That said, it doesn't seem to be working now, but I'm sure I had it working earlier!

In my case (using IBM's WAS 7.0), the default JNDI name appears to be of the format:

ejb/<EAR Name>/<JAR name within the EAR that contains the EJB>/<Class name of the bean>#<fully qualified name of the interface>

As I said, I'm sure I had the dependency injection working using the method specified above even if it's gone AWOL for the moment. However, the look up using the initial context object certainly works, like so:


Curiously, attempting to combine the obj2 = ... and the cast to the remote interface fails with an exception. Quite why it should work as two separate lines, but fail if I try to combine it like this:


is a mystery, but not one I'm going to look into just now!

Hope this helps any other EJB3 newbies out there - there's loads of documentation, which just meant I got lost looking for specifics!
jane givingup
Greenhorn

Joined: Mar 17, 2011
Posts: 2
You can do the following to make cross-app EJB3 calls in WebSphere v7:

1. Specify the JNDI name for the EJB by creating an ibm-ejb-jar-bnd.xml under the META-INF folder in the ejb project. Note the simple-binding-name, which will create a remote jndi name of 'ejb/EJB2' and a local jndi name of 'ejblocal:ejb/EJB2'. The 'name' should be the unqualified class name of the EJB. This can also be done without using an ibm-ejb-jar-bnd.xml, by going into admin console and typing 'ejb/EJB2 into the EJB's 'EJB JNDI names/Target Resource JNDI Name/JNDI Name For All Interfaces' section:

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar-bnd
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd" version="1.0">
<session name="EJB2" simple-binding-name="ejb/EJB2"/>

</ejb-jar-bnd>

2. In the servlet create a reference to the ejb specifying the remote interface. The 'name' specified as the reference name can be whatever you want:

import org.rb.ejb2.EJB2Remote;
.....

@EJB (name="EJB2Ref") EJB2Remote ejb2;

3. Deploy both apps.

4. In the admin console, go to the servlet client's 'EJB references' and type in the simple-binding-name of the EJB, e.g. 'ejb/EJB2', in order to map the EJB2Ref reference to the JNDI name of the EJB .

This is all that should be required to make cross-app EJB calls.

Note that step 4 actually populates the ibm-web-bnd.xml in the servlet like so:

<?xml version="1.0" encoding="UTF-8" ?>
- <web-bnd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://websphere.ibm.com/xml/ns/javaee" xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_0.xsd" version="1.0">
<virtual-host name="default_host" />
<ejb-ref name="EJB2Ref" binding-name="ejb/EJB2" />
</web-bnd>

and populates the web.xml like so:

<?xml version="1.0" encoding="UTF-8" ?>
- <web-app id="WebApp_ID" version="2.5" metadata-complete="false" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>EJB2ServletClient</display-name>
- <servlet>
.....
</servlet>
- <servlet-mapping>
.....
</servlet-mapping>
- <welcome-file-list>
.....
</welcome-file-list>
- <ejb-ref>
<ejb-ref-name>EJB2Ref</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<remote>org.rb.ejb2.EJB2Remote</remote>
</ejb-ref>
</web-app>
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: EJB3 - dependency injection fails?