aspose file tools*
The moose likes EJB Certification (SCBCD/OCPJBCD) and the fly likes @Resource(name= Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » EJB Certification (SCBCD/OCPJBCD)
Bookmark "@Resource(name="x",lookup="y")" Watch "@Resource(name="x",lookup="y")" New topic
Author

@Resource(name="x",lookup="y")

Dieter Quickfend
Bartender

Joined: Aug 06, 2010
Posts: 543
    
    4

Just wanted to verify this, because the EJB3.1 spec is not clear on this and it's hard to find answers:



equals

equals


Does not work:




What can also happen:


Do I understand the difference between "name" and "lookup" correctly? I've had a lot of trouble grasping this and it's confused me enormously in a few Enthuware questions...


Oracle Certified Professional: Java SE 6 Programmer && Oracle Certified Expert: (JEE 6 Web Component Developer && JEE 6 EJB Developer)
Jaikiran Pai
Marshal

Joined: Jul 20, 2005
Posts: 10213
    
166

@Resource EE annotation does 2 things:

1) Binds to a (relative) name within the environment naming context (ENC) of the component
2) Looks up from a jndi name

The name attribute that you pass is where it binds to relative to the ENC of the component (which by default is java:comp/env). So if you specify a name = "foo" then it binds the resource to "java:comp/env/foo" so that later at runtime within your component's methods you can do a JNDI lookup with that fully qualified name if you want to.

Now to bind some resource, the @Resource has to (optionally) know from where to fetch the resource from. That's where the lookup attribute plays a role. It tells the container that it has to fetch a resource from the location pointed to by the lookup attribute and bind it to the location pointed to by the (optional) name attribute.

So if you have something like:


Then the container will lookup a resource under "bar/hello" JNDI name and bind it to java:comp/env/foo JNDI name for that component which has this annotation.

[My Blog] [JavaRanch Journal]
Dieter Quickfend
Bartender

Joined: Aug 06, 2010
Posts: 543
    
    4

But the 'name' attribute also does injection of resources bound in the EJB's environment, right? Like if you specify in ejb-jar.xml an env-entry "myString" for some EJB, the following:

@Resource(name="myString")
String myString;

will inject the resource instead of binding it, and for, let's say a datasource, which is specified as "java:comp/env/jdbc/Muppets" in the JNDI context, the 'name' property is not binding it when it injects this value using:

@Resource(name="jdbc/Muppets")
DataSource ds;



I guess the point of confusion for me is the double task of the 'name' property (i think the 'lookup' on its own is clear enough) and its scope (what can it inject and what can't it inject?)
Jaikiran Pai
Marshal

Joined: Jul 20, 2005
Posts: 10213
    
166

Dieter Quickfend wrote:But the 'name' attribute also does injection of resources bound in the EJB's environment, right? Like if you specify in ejb-jar.xml an env-entry "myString" for some EJB, the following:

@Resource(name="myString")
String myString;

will inject the resource

No. The name still will be used for "where to bind". There "where to get the resource value from" changes in this case. In this case instead of looking it up from some other jndi name, the value injected is the one from the deployment descriptor.


and for, let's say a datasource, which is specified as "java:comp/env/jdbc/Muppets" in the JNDI context, the 'name' property is not binding it when it injects this value using:

@Resource(name="jdbc/Muppets")
DataSource ds;


I don't understand what you meant there. But even if it's a datasource (or any other resource), the name still represents where to bind in the ENC.
Dieter Quickfend
Bartender

Joined: Aug 06, 2010
Posts: 543
    
    4

So, if I'm understanding you correctly, specifying "@Resource(name='thisResource') String myString;" behaves exactly the same as "@Resource String myString;" except that the former will also bind the value injected into this component (without knowing where it got it from) as 'thisResource' in the ENC (assuming 'thisResource' doesn't exist)? What happens if 'thisResource' already exists?
Frits Walraven
Creator of Enthuware JWS+ V6
Bartender

Joined: Apr 07, 2010
Posts: 1696
    
  25

Hi Dieter,

I understand you are struggling as the EJB specs are not always clear, let me try to help you a bit
Dieter Quickfend wrote:So, if I'm understanding you correctly, specifying "@Resource(name='thisResource') String myString;" behaves exactly the same as "@Resource String myString;" except that the former will also bind the value injected into this component (without knowing where it got it from) as 'thisResource' in the ENC (assuming 'thisResource' doesn't exist)? What happens if 'thisResource' already exists?

You should look at it like this:
- every @Resource is equal to a JNDI lookup (so your resource already has got a JNDI name)
- the name parameter refers to the JNDI name (env-entry-name in the ejb-jar.xml)

Just a small example to explain the difference between:
  • @Resource(name = "initNumber") Integer init;
  • @Resource Integer anotherInit;

  • In the first one you will have an ejb-jar.xml of:

    With the second one you will have an entry declaring the injection target of the resource

    The EJB will look like:

    What happens if 'thisResource' already exists?

    Two <env-entry>s with the same <env-entry-name> won't deploy.

    I am not sure whether you are using my notes (ScbcdLinks), but you can find a couple of examples in there in chapter 7.

    Regards,
    Frits
    Dieter Quickfend
    Bartender

    Joined: Aug 06, 2010
    Posts: 543
        
        4

    That clears it up for me. So @Resource(name="") is actually a code-level declaration of an env-entry rather than a JNDI lookup of an env-entry. Thanks a bunch Frits!

    And yes, I've been using your notes intensively, after reading the specification, to prepare for the EJB certification (which will be in a few weeks). Thanks a lot, both for this explanation and for your awesome notes! They've been a big help!
    Frits Walraven
    Creator of Enthuware JWS+ V6
    Bartender

    Joined: Apr 07, 2010
    Posts: 1696
        
      25

    That clears it up for me. So @Resource(name="") is actually a code-level declaration of an env-entry rather than a JNDI lookup of an env-entry.

    Well, I wouldn't say that.

    Every @Resource is still a JNDI lookup followed by an injection. In the first case the JNDI lookup is done with the name : "java:com/env/initNumber" and that entry exists because it is declared in the ejb-jar.xml (with value 10)

    The second case is different, the lookup in initiated by the @Resource, the injection is now done from the deployment descriptor.

    There is even a third case possible where you can use both name and lookup.

    The third one you will have an ejb-jar.xml of:

    and the bean:
    The lookup mostly refers to an entry in the global JNDI, but this is just to show you that you can also get it from the components ENC itself.

    And yes, I've been using your notes intensively, after reading the specification, to prepare for the EJB certification (which will be in a few weeks). Thanks a lot, both for this explanation and for your awesome notes! They've been a big help!

    Thanks

    Regards,
    Frits
    Dieter Quickfend
    Bartender

    Joined: Aug 06, 2010
    Posts: 543
        
        4

    So actually @Resource(name="initNumber") DOES do a JNDI lookup for a specific property in the bean's ENC named initNumber, thus the 'name' property corresponds to a bean-level version of the general-ENC-level 'lookup' property

    so:

    - when only @Resource without parameters exists, the deployment descriptor MUST specify the injection-target of the environment entries (or the container may infer it automatically (i.e. SessionContext))
    - @Resource(lookup="") does a global JNDI lookup
    - @Resource(name="someNumber") does a JNDI lookup for a bean-level environment entry called "someNumber"
    - @Resource(name="someNumber") can also declare a bean-level environment entry 'binding' if a proper value exists in the deployment descriptor specifying the annotated property as an injection-target
    - @Resource(name="someNumber" lookup="java:comp/env/thisIsTheOriginalReference") does a JNDI lookup and binds this value as a bean-level env-entry called 'someNumber'


    My confusion is still the double function of the 'name' property I think. I hope I have it right this time.
    Frits Walraven
    Creator of Enthuware JWS+ V6
    Bartender

    Joined: Apr 07, 2010
    Posts: 1696
        
      25

    Hi Dieter,

    I read the specifications again and I now know again how it works (I still find the description in the EJB specs is lacking some important aspects)

    Let's go back to the
    The "name" and "type" are not specified in the @Resource annotation, the container will infer the name and type of the resource, so it will look for an entry with (the default) JNDI-name: "nl.notes.ejb.EchoBean/anotherInit" and type "java.lang.Integer" and if it finds the entry in the ejb-jar.xml:
    it will inject the value 10 into the field.

    So if you go to the next one (which was sort of bugging us)
    The container now does a lookup without the default name, because there is an explicit name specified. It look for an entry with the JNDI-name "initNumber". This means that if there is an entry with the JNDI-name "initNumber" and type "java.lang.Integer" in the deployment descriptor for this SessionBean (EchoBean):
    it will inject the value 11 into the field "init" of the bean.

    And lastly our third case:
    The "name" and "type" are not specified in the @Resource annotation, the container will infer the name and type of the resource, so it will look for an entry with (the default) JNDI-name: "nl.notes.ejb.EchoBean/init" and type "java.lang.Integer" and it won't find the entry in the ejb-jar.xml so no injection is done (at first). However there is another environment entry with name "init2" that specifies an injection target of the instance variable "init", this time the injection of value 12 is done from the deployment descriptor into the field "init".
    (I have not repeated the injections with the "lookup" parameter as those where already clear, right?)

    Does this clear up all your doubts?

    Regards,
    Frits

    N.B. I will update my notes with this explanation soon
    Jaikiran Pai
    Marshal

    Joined: Jul 20, 2005
    Posts: 10213
        
    166

    Frits Walraven wrote:
    (I still find the description in the EJB specs is lacking some important aspects)


    From what I remember the explanation of @Resource is probably done more in the Java EE spec rather than in EJB spec.

    Frits Walraven
    Creator of Enthuware JWS+ V6
    Bartender

    Joined: Apr 07, 2010
    Posts: 1696
        
      25

    Jaikiran Pai wrote:
    From what I remember the explanation of @Resource is probably done more in the Java EE spec rather than in EJB spec.

    Yes, that is true, it is in the JSR-250 "Common Annotations for the Java Platform 1.1" and a bit in JSR-316 "Java Platform, Enterprise Edition 6 Specification 6.0".

    The problem in the EJB spec is that it is not all that clear in that respect, whereas the rest of the EJB spec is quite detailed. A few lines of text or a reference to JSR-250 would have helped.

    Regards,
    Frits
    Dieter Quickfend
    Bartender

    Joined: Aug 06, 2010
    Posts: 543
        
        4

    That's pretty clear, Frits, thanks. The only thing I'm still left wondering is that in the third case, where the container finds no env-entry with the name specified (name="init") but finds another ("init2) with the field declared as an injection target, will the annotation "@Resource(name="init") bind the injected value as a bean-level environment entry called "init", as specified in the name?
    Frits Walraven
    Creator of Enthuware JWS+ V6
    Bartender

    Joined: Apr 07, 2010
    Posts: 1696
        
      25

    No, in that case there will be no entry created in the beans environment and an explicit lookup will fail with a javax.naming.NameNotFoundException.

    Regards,
    Frits
    Dieter Quickfend
    Bartender

    Joined: Aug 06, 2010
    Posts: 543
        
        4

    great, I got it now! Thanks for the help!
    Frits Walraven
    Creator of Enthuware JWS+ V6
    Bartender

    Joined: Apr 07, 2010
    Posts: 1696
        
      25

    Updated my notes with the topic of this discussion (chapter 7.8.3).

    Thanks Dieter for this discussion!
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: @Resource(name="x",lookup="y")