users@ejb-spec.java.net

[ejb-spec users] Re: Portable JNDI names comments

From: Samuel Santos <samaxes_at_gmail.com>
Date: Thu, 22 Mar 2012 01:38:46 +0000

Hi Marina,

What I'm suggesting is not related with classpath issues at all.

Using the same archive structure as in one of my previous emails:

> |-- EJBJAR
> | |-- FooService.java
> | `-- FooServiceBean.java
> `-- WAR
> |-- BarActionBean.java
> `-- WEB-INF
> `-- web.xml
>
Nothing is stopping you to import FooService.java and FooServiceBean.javainto
BarActionBean.java.

However if you are trying to inject an EJB in an object that is *not
managed by the container* you need to implement something like an
InjectionEnricher [1] or [2]:
In that InjectionEnricher you need to lookup for the EJB to be able to do
something like this:

> class BarActionBean {
> @EJB
> FooService fooService;
> }
>

The issue here is that the InjectionEnricher will be running in the WAR,
meaning that context.lookup("java:module/ModuleName") [1] will always
return the name of the WAR module, causing the EJB not to be found.
Yes, forcing the developer to specify the full JNDI name (i.e. @EJB(lookup
= "java:global/EAR/EJBJAR/FooServiceBean!com.foo.bar.FooService")) will
work and is supported by the InjectionEnricher, but is not as clean as it
could be.

A different solution would be to include a properties file in the WAR (e.g.
jndi.properties) and have the InjectionEnricher look for the EJBs in the
modules specified in that file instead of using
context.lookup("java:module/ModuleName"):

> jndi.lookup.modules=EJBJAR,FOOJAR,BARJAR,...
>
However, I believe it would be helpful having the spec defining a standard
way to do this.

Is this completely inappropriate?

[1]
https://github.com/samaxes/stripes-injection-enricher/blob/master/src/main/java/com/samaxes/stripes/enricher/EJBInjectionEnricher.java
[2]
https://github.com/arquillian/arquillian-core/blob/master/testenrichers/ejb/src/main/java/org/jboss/arquillian/testenricher/ejb/EJBInjectionEnricher.java

Thanks and please excuse my insistence,

--
Samuel Santos
http://www.samaxes.com/
On Wed, Mar 14, 2012 at 1:32 AM, Marina Vatkina
<marina.vatkina_at_oracle.com>wrote:
> Hi Samuel,
>
> Samuel Santos wrote:
>
>> Hi Marina,
>>
>> Sorry for the late reply, I've been outside the country and I'm now
>> getting back to old emails.
>>
>> I can use @EJB injection using context.lookup("java:module/**Mo​duleName")
>> to inject Session Beans from an EJB module in the same EAR directly in my
>> WAR (please see my email from Feb 10 for more detail), if:
>>
>> - An EJB client JAR in the lib folder of my WAR;
>>
>
> Of your EAR.
>
>  - Or by referencing the EJB module in the Class-Path attribute of the
>> manifest file in my WAR.
>>
>
> Yes.
>
>>
>> Have I understood you correctly?
>>
>> Best,
>>
>> --
>> Samuel Santos
>> http://www.samaxes.com/
>>
>>
>> On Wed, Feb 15, 2012 at 4:44 AM, Marina Vatkina <
>> marina.vatkina_at_oracle.com <mailto:marina.vatkina_at_oracle.**​com<marina.vatkina_at_oracle.com>>>
>> wrote:
>>
>>    Aren't these the visibility rules in an EAR file defined by the
>>    Java EE 6 spec EE.8.3.1 Web Container Class Loading Requirements?
>>
>>    "Components in the web container may have access to the following
>>    classes and resources. Portable applications must not depend on
>>    having or not having access to these classes or resources.
>>    •The classes and resources accessible to any other web modules
>>    included in the same ear file, as described above.
>>    •The content of any EJB jar files included in the same ear file."
>>
>>    To do the @EJB injection the EJB interface needs to be placed into
>>    a library or the EJB module needs to be referenced in the
>>    Class-Path attribute of the manifest file in the WAR or another
>>    EJB module.
>>
>>    If the library solution doesn't work, I would consider it a bug.
>>    Without a library, the lookup work around seems like something
>>    that happens to work in a particular appserver.
>>
>>
>>    Best,
>>    -marina
>>
>>    Samuel Santos wrote:
>>
>>        Hi David,
>>
>>        Yes, perform @EJB injection without having to specify the full
>>        JNDI name (i.e. @EJB(lookup = "FULL_JNDI_NAME")) on objects
>>        inside the container that are *not* managed by it.
>>        That is why we need plugins like Stripes Injection Enricher
>>        that I mentioned earlier.
>>
>>        Best,
>>
>>        --
>>        Samuel Santos
>>        http://www.samaxes.com/
>>
>>
>>        On Wed, Feb 15, 2012 at 12:32 AM, Reza Rahman
>>        <reza_rahman_at_lycos.com <mailto:reza_rahman_at_lycos.com>
>>        <mailto:reza_rahman_at_lycos.com <mailto:reza_rahman_at_lycos.com>**​>>
>>
>>        wrote:
>>
>>           You can use CDI to do this.
>>
>>
>>           On 2/14/2012 7:29 PM, David Blevins wrote:
>>
>>               Hi Samuel,
>>
>>               To make sure I'm understanding correctly, it looks like
>>        what
>>               you really want is to perform @EJB injection on objects
>>               running inside the container.  Is that more or less the
>>               high-level goal?
>>
>>
>>               -David
>>
>>               On Feb 10, 2012, at 10:51 AM, Samuel Santos wrote:
>>
>>                   Hi Marina,
>>
>>                   Judging from your reply, my text was not clear enough.
>>                   I apologize for that, English is not my first language.
>>                   I will try to exemplify it using code.
>>
>>                   Lets say that the project has the following structure:
>>
>>                   EAR
>>                   |-- EJBJAR
>>                   |   |-- FooService.java
>>                   |   `-- FooServiceBean.java
>>                   `-- WAR
>>                       |-- BarActionBean.java
>>                       |-- WEB-INF
>>                       |   `-- web.xml
>>
>>                   Guessing JNDI names as we do in Stripes Injection
>>        Enricher
>>                   [1] or in JBoss Arquillian [2] will not allow us to
>>        inject
>>                   an EJB in BarActionBean.java like this:
>>                   class BarActionBean {
>>                       @EJB
>>                       FooService fooService;
>>                   }
>>
>>                   We must always specify the lookup or mappedName
>>        elements
>>                   of the @EJB annotation:
>>                   class BarActionBean {
>>                       @EJB(lookup =
>>                          "java:global/EAR/EJBJAR/**
>> FooSe​rviceBean!com.foo.bar.**FooServi​ce")
>>                       // or @EJB(lookup =
>>                   "java:global/EAR/EJBJAR/**FooSer​viceBean")
>>                       // or @EJB(lookup =
>>                          "java:app/EJBJAR/**FooServiceBe​an!com.foo.bar.*
>> *FooService")
>>                       // or @EJB(lookup =
>>        "java:app/EJBJAR/**FooServiceBe​an")
>>                       FooService fooService;
>>                   }
>>
>>                   What I'm trying to suggest is to have a standard
>>        allowing
>>                   us to configure a project (in this example the WAR
>>                   archive) to lookup for EJBs in external modules.
>>
>>                   Either by defining them in the deployment descriptor:
>>                   <jndi-lookup>
>>                       <modules>
>>                           <module>EJBJAR</module>
>>                           <module>FOOJAR</module>
>>                           <module>BARJAR</module>
>>                           <module>...</module>
>>                       </modules>
>>                   </jndi-lookup>
>>
>>                   Or in a properties file (e.g. jndi.properties):
>>                   jndi.lookup.modules=EJBJAR,**FOO​JAR,BARJAR,...
>>
>>                   That way we can read those configurations and
>>        lookup for
>>                   the EJBs in that particular modules without
>>        defining the
>>                   entire JNDI name each time we need to inject an EJB.
>>
>>                   [1]
>>                          https://github.com/samaxes/**
>> st​ripes-injection-enricher/**blob/​master/src/main/java/com/**
>> samax​es/stripes/enricher/**EJBInjecti​onEnricher.java<https://github.com/samaxes/stripes-injection-enricher/blob/master/src/main/java/com/samaxes/stripes/enricher/EJBInjectionEnricher.java>
>>                   [2]
>>                          https://github.com/​arquillian/**
>> arquillian-core/​blob/master/**testenrichers/ejb/​src/main/**
>> java/org/jboss/​arquillian/**testenricher/ejb/**
>> EJ​BInjectionEnricher.java<https://github.com/arquillian/arquillian-core/blob/master/testenrichers/ejb/src/main/java/org/jboss/arquillian/testenricher/ejb/EJBInjectionEnricher.java>
>>
>>                   Thank you and best regards,
>>
>>                   --
>>                   Samuel Santos
>>                   http://www.samaxes.com/
>>
>>
>>                   On Fri, Feb 10, 2012 at 2:37 AM, Marina
>>                   Vatkina<marina.vatkina_at_oracle.**​com<marina.vatkina_at_oracle.com>
>>        <mailto:marina.vatkina@​oracle.**com <marina.vatkina_at_oracle.com>>
>>                   <mailto:marina.vatkina_at_oracle.**​com<marina.vatkina_at_oracle.com>
>>
>>        <mailto:marina.vatkina@​oracle.**com <marina.vatkina_at_oracle.com>>>>
>>  wrote:
>>
>>                   Samuel,
>>
>>                   EJB spec (see 4.4.1.1java:app and
>>        4.4.1.2java:module) is
>>                   clear that you should use "java:app/ModuleName" to
>>        access
>>                   beans in other modules in your EAR file and
>>                   "java:module/BeanName" to access beans in the same
>>        EJB module.
>>
>>                   Best,
>>                   -marina
>>
>>
>>                   Samuel Santos wrote:
>>                   Hi all,
>>
>>                   I find the Global JNDI Namespace, and finally having
>>                   portable names across different containers, a
>>        really neat
>>                   feature.
>>                   However, it still is not easy to inject EJB from
>>        different
>>                   modules inside an EAR archive.
>>
>>                   I'm working on a small open source project [1] to
>>        support
>>                   @EJB, @Inject and @Resource standard Java EE
>>        annotations
>>                   on Stripes Framework [2] using portable JNDI names.
>>                   As you can see by looking at the code [1], I'm using
>>                   context.lookup("java:app/**AppNa​me") and
>>                   context.lookup("java:module/**Mo​duleName") to build
>>        the JNDI
>>                   names to lookup.
>>
>>                   Unfortunately it only works as long as you are
>>        injecting
>>                   EJBs inside the same module where it is.
>>                   If you have an EAR with two modules, one WAR and
>>        one EJB,
>>                   and try to inject an EJB in a class inside the WAR, the
>>                   code will not work.
>>                   We have to define the full JNDI name in the
>>        mappedName or
>>                   lookup elements of the @EJB annotation every time
>>        we are
>>                   injecting a session bean in a class inside the WAR
>>        archive.
>>
>>                   I believe it is the role of the EJB spec to make
>>        this easier.
>>                   Can we define a way to configure projects to lookup for
>>                   JNDI names in other modules (e.g. by
>>        defining/enumerating
>>                   them in web.xml or other deployment descriptor)?
>>
>>                   [1]
>>                          https://github.com/samaxes/**
>> st​ripes-injection-enricher/**blob/​master/src/main/java/com/**
>> samax​es/stripes/enricher/**EJBInjecti​onEnricher.java<https://github.com/samaxes/stripes-injection-enricher/blob/master/src/main/java/com/samaxes/stripes/enricher/EJBInjectionEnricher.java>
>>                   [2] http://www.stripesframework.**or​g<http://www.stripesframework.org>
>>
>>                   Thanks and best regards,
>>
>>                   --
>>                   Samuel Santos
>>                   http://www.samaxes.com/
>>
>>
>>
>>               -----
>>               No virus found in this message.
>>               Checked by AVG - www.avg.com <http://www.avg.com>
>>        <http://www.avg.com>
>>
>>               Version: 2012.0.1913 / Virus Database: 2112/4809 - Release
>>               Date: 02/14/12
>>
>>
>>
>>
>>
>>
>>