users@ejb-spec.java.net

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

From: Samuel Santos <samaxes_at_gmail.com>
Date: Fri, 23 Mar 2012 01:44:09 +0000

Hi Carlo,

Yep, having something like that in the spec would definitively help.

In my previous scenario, and considering the current spec, the only way I
can come up with looking for an EJB which is in the EJBJAR module from the
WAR (without asking the developer for the moduleName where to look for), is
to scan the entire classloader...

Best,

--
Samuel Santos
http://www.samaxes.com/
On Thu, Mar 22, 2012 at 3:23 PM, Carlo de Wolf <cdewolf_at_redhat.com> wrote:
> I believe you are looking for a resolver which can lookup EJBs from within
> the callers context with just the @EJB information.
>
> @Resource // or through java:comp/EJBResolver (maybe
> java:global/EJBResolver?)
> EJBResolver resolver;
>
> EJBResolver {
> <V> V lookup(EJB ejb, Class<V> beanInterface) throws EJBNotFoundException;
>
> <V> V lookup(Class<V> beanInterface, String beanName, String lookup,
> String mappedName, String name) throws EJBNotFoundException;
> }
>
> Where ejb.beanInterface == beanInterface or null. (Can annotations have a
> generic?)
>
> Carlo
>
>
> On 03/22/2012 02:38 AM, Samuel Santos wrote:
>
>> 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/**Mo​duleName") [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/**FooSer​viceBean!com.foo.bar.**FooServic​e"))
>> 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/**Mo​duleName"):
>>
>>  jndi.lookup.modules=EJBJAR,**FOO​JAR,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/**str​ipes-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/**
>> te​stenrichers/ejb/src/main/**java/​org/jboss/arquillian/**
>> testenric​her/ejb/**EJBInjectionEnricher.​java<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>**wro​te:
>>
>>  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<**mail​to:marina.vatkina_at_oracle.****​​com<
>>>> 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<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/****FooS​er​viceBean")
>>>>                       // or @EJB(lookup =
>>>>                          "java:app/EJBJAR/****
>>>> FooService​Be​an!com.foo.bar.***
>>>> *FooService")
>>>>                       // or @EJB(lookup =
>>>>        "java:app/EJBJAR/****FooService​Be​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,****F​OO​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<h**
>>>> ​ttps://github.com/samaxes/**stri​pes-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/​**arquill​ian/**
>>>> arquillian-core/​blob/**master​/**testenrichers/ejb/​**src/​main/**
>>>> java/org/jboss/​arquillian/***​*testenricher/ejb/**
>>>> EJ​BInjectionEnricher.java<h**​ttps://github.com/arquillian/**
>>>> a​rquillian-core/blob/master/**tes​tenrichers/ejb/src/main/**
>>>> java/​org/jboss/arquillian/**testenric​her/ejb/**
>>>> EJBInjectionEnricher.​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@**oracle​.com <marina.vatkina_at_oracle.com>>
>>>>        <mailto:marina.vatkina@​**ora​cle.**com<marina.vatkina@**
>>>> oracl​e.com <marina.vatkina_at_oracle.com>>>
>>>>                   <mailto:marina.vatkina_at_oracle.**​**​com<
>>>> marina.vatkina@**oracle​.com <marina.vatkina_at_oracle.com>>
>>>>
>>>>        <mailto:marina.vatkina@​**ora​cle.**com<marina.vatkina@**
>>>> oracl​e.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/****App​Na​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<h**
>>>> ​ttps://github.com/samaxes/**stri​pes-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.**stripesframe​work.org <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
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>