On Jan 6, 2009, at 9:54 AM, Michael Keith wrote:
I would like to see all of the EE injection be in the same spec,
meaning that existing
EE resource injection would transition from its definition in the EE
document to being in this
one (if injection is to be a primary service defined and offered by
this spec). All injection
should be consistently defined, explained and implemented.
If it helps, we've run into related issues because we've implemented
@EJB, @Resource, etc. on top of an underlying WebBeans repository.
So, in our case, Java EE injection is a facade over WebBeans.
Theoretically, Java EE injection could be officially defined in a
similar way.
When a user configures a DataSource, we register it with the
appropriate WebBeans Manager (using a special Bean wrapper
implementation), and give it an internal binding name like
@Name("foo"). A user could theoretically inject the resource directly
using a pure webbeans-only injection.
So, @EJB, @PersistenceUnit, @Resource, etc. find the resource using
normal WebBeans rules, inject it if necessary, and bind to JNDI if
necessary. (We're still working out some of the details for the
internal binding, but it's essentially in place. If necessary, for
things like *-link, we can define a link Bean similar to Gavin's JNDI
bean.)
I believe it would be possible to specify Java EE injection entirely
in terms of an underlying WebBeans registry without too much
difficulty. The other way around would be a bit of a mess.
For the issue of component scoping for EJBs, we have a separate
WebBeans Manager associated with each EJB scope, web-app and ear
arranged in a tree. This lets us have scope-specific definitions and
links. For example, an <env-entry> defined in a session bean is
stored in its scoped Manager, not the global Manager. A child scope
might entirely consist of links to resources defined in the parent
scope. (Hierarchy scope rules apply, so a lookup that fails in the
client the tries the parent Manager.)
(I'm a bit behind in reading the latest EJB 3.1 draft, so there are
still probably details that aren't quite right, but the basic model
shouldn't change.)
Option 1, then, would work like a rebinding from the internal
configured resource, as a LinkBean which would be registered using the
new <binding> in the component's scope. (And published in JNDI using
the public JNDI name.) Pretty straightforward.
Options 2. hmmm. The scoping of the resources in the EJB's web-
beans.xml is a bit of a problem. IIRC, EJB doesn't create a foo.jar
scope, only bean-specific scopes, so I assume the <ResourceRef> would
be published in the application scope. But that means that option 2
doesn't really capture the concept of an <ejb-ref> defined in a
session bean's scope. I think.
BTW, I didn't want to bring up the idea of a Manager hierarchy because
it seemed beyond the spec's scope, but it's handy in order to properly
model the Java-EE, ear, web-app, EJB scopes and references in terms of
WebBeans capabilities.
-- Scott
-Mike
> -----Original Message-----
> From: Gavin King [mailto:gavin@hibernate.org]
> Sent: Monday, January 05, 2009 9:11 PM
> To: Java Community Process JSR #299 Expert List; Michael Keith; Scott
> Ferguson; Matt Drees; WebBeans
> Subject: Java EE resource injection
>
>
> Folks, it's time to address the problem of generalized Java EE
> resource injection.
>
> Web Beans needs to support injection of the following kinds of
> things:
>
> * EE resources (e.g. JDBC datasources, etc)
> * remote EJB references
> * web service references
>
> I believe we can treat all three as essentially the same kind of
> thing
> in the spec. Let's call it a "EE resource reference", or whatever.
> It's a new "kind" of Web Bean in Chapter 3. This functionality should
> not impact any other part of the specification.
>
> (An additional complication is that we need to unify the current
> notion of a "JMS endpoint" with this functionality. I don't believe
> that this is a difficult problem, we just need to make it a special
> case of a "EE resource reference", that supports additional
> semantics.)
>
> I see two possible paths we could go down here:
>
> Option 1:
> =======
>
> The spec could simply say that for every "EE resource reference"
> defined in web.xml or ejb-jar.xml, that a Web Bean exists with
> deployment type @Production and no name. The scope and binding types
> of this Web Bean have the usual defaults (@Depenent, @Current), but
> these may be specified explicitly in web.xml or ejb-jar.xml:
>
> <ejb-ref>
> <ejb-ref-name>foo</ejb-ref-name>
> <remote>org.myapp.FooRemote</remote>
> <binding>org.myapp.Bar</binding>
> <scope>javax.webbeans.Conversation</scope>
> </ejb-ref>
>
> <resource-ref>
> <res-ref-name>jdbc/DefaultDS</res-ref-name>
> <res-type>javax.sql.DataSource</res-type>
> <res-auth>Container</res-auth>
> <binding>org.myapp.Default</binding>
> </resource-ref>
>
> <service-ref>
> <service-ref-name>service/FooService</service-ref-name>
> <service-interface>org.myapp.Foo</service-interface>
> <wsdl-file>META-INF/wsdl/FooService.wsdl</wsdl-file>
>
> <jaxrpc-mapping-file>META-INF/foo-mapping.xml</jaxrpc-mapping-file>
> <binding>org.myapp.Bar</binding>
> <scope>javax.webbeans.Request</scope>
> </service-ref>
>
> The lifecycle of this Web Bean would be super-simple:
>
> * Bean.create() would be equivalent to a JNDI lookup for the resource
> * Bean.destroy() would simply discard the reference
>
> There is just one problem with this approach: EE resource references
> are by nature scoped to a particular EE module, whereas this is not
> naturally the case for Web Beans (which are naturally EAR scoped). I
> don't believe this is a really big problem but we would need to
> institute an additional layer of validation to ensure that injection
> points that refer to an EE resource are in the same module as the
> resource ref declaration. This would be a new section in the spec,
> but
> I don't believe it is difficult to write.
>
> Option 2:
> =======
>
> The second option would be to require explicit declaration of the
> resource in web-beans.xml, thus making them an EAR-global
> declaration.
>
> <ResourceRef jndiName=".....">
> <myapp:Foo>
> <myapp:Bar/>
> </myapp:Foo>
> <ResquestScoped/>
> </ResourceRef>
>
> There are a couple of major problems with this:
>
> * resources must be declared twice, in different places
> * the two declarations are correlated via a global JNDI name, which:
> - is still not really a well-defined construct in the EE spec
> - cannot be properly validated at development time
>
> Therefore I strongly prefer Option 1.
>
> WDYT?
>
> --
> Gavin King
> gavin.king(a)gmail.com
>
http://in.relation.to/Bloggers/Gavin
>
http://hibernate.org
>
http://seamframework.org
>