users@ejb-spec.java.net

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

From: Carlo de Wolf <cdewolf_at_redhat.com>
Date: Thu, 22 Mar 2012 16:23:10 +0100

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/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
>>>
>>>
>>>
>>>
>>>
>>>
>>>