You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomee.apache.org by Gurkan Erdogdu <cg...@gmail.com> on 2009/08/17 22:06:02 UTC

Injection in OpenEJB Tomcat

Hi;

I would like to inject @EJB,@WebServiceRef, @Resource, @PersistenceUnit,
@PersistenceContext into the  OpenWebbeans Managed Bean instance in the
Tomcat Environment. For example, in managed bean instance Person

@RequestScoped
@Named
public class Person
{
    @EJB, @WebServiceRef, bla... bla...
}

I tried to understand the "assembler tomcat" but no success. There are no
comments for understanding code. So, my question is how to inject those type
of instances into the Managed Bean instance ? Is there any API to use?

I will give Managed Bean instance to the OpenEJB and it injects above types
of instances.

Thanks;

--Gurkan

Re: Injection in OpenEJB Tomcat

Posted by David Blevins <da...@visi.com>.
On Aug 18, 2009, at 1:19 AM, Gurkan Erdogdu wrote:

> Scanning code is
>
> https://svn.apache.org/repos/asf/incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/spi/ee/deployer/WarMetaDataDiscoveryImpl.java
>
> Listener code;
> https://svn.apache.org/repos/asf/incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/servlet/WebBeansConfigurationListener.java
>
> Some explanation :
>
> Context initialized method calls
> https://svn.apache.org/repos/asf/incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/lifecycle/WebBeansLifeCycle.java
> instance's *"applicationStarted"* method.This method gets discovery  
> class
> instance and call its "init" and "scan" methods respectively.
>
>   this.discovery =  
> ServiceLoader.getService(MetaDataDiscoveryService.class);
>
>   this.discovery.init(event.getServletContext());
>
>   this.discovery.scan();
>
> After that it calls,
> https://svn.apache.org/repos/asf/incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansContainerDeployer.java
> "deploy" method to deploy all classes.
>
> deployer.deploy(this.discovery);
>
> WebBeansContainerDeployer "deploy" method calls  
> "deployFromClassPath" method
> to resolve "Managed Beans" and "EJB Beans". It gets all scanned  
> classes via
> given scanner.
>
> protected void deployFromClassPath(MetaDataDiscoveryService scanner)
> throws ClassNotFoundException

I had a look at the boot/scan code.  The boot process and scanning  
abstraction uses servlet apis.  For Geronimo and OpenEJB, we'll need  
to scan all EE injectable classes at deploy time at the same time we  
scan servlets, filters, listeners, and JSF managed beans.  Bottom line  
is that there is no "webapp" at the moment we do scanning, so any code  
that leverages servlet apis for scanning is not workable -- at least  
in the Geronimo/OpenEJB sense.

For Servlets and JSF, we actually read the web.xml and faces- 
config.xml files so that we can discover all the classes we need to  
scan.  We then process all the Java EE ref types (@Resource, @EJB,  
@PersistenceUnit, @PersistenceContext, @WebServiceRef, etc.) found in  
those classes and fill out the web.xml adding every ref as a <resource- 
ref>, <ejb-ref>, etc. so that the descriptor data represents a  
complete list of the things we need to build and link into JNDI when  
the webapp is eventually created.  All this is done in our  
AnnotationDeployer class.  All the metadata we use to do injection at  
runtime is only possible because of the work done in that class.   
Attempting to inject into something at runtime which hasn't gone  
through scanning in the AnnotationDeployer is not possible with our  
code.  Geronimo has a class similar to AnnotationDeployer with  
identical scanning requirements.

That's how things work from a high level at least.  Not sure on the  
next step forward just yet.  It'll definitely involved finding a way  
to get the 299 managed bean classes scanned like we do for servlets,  
jsf, etc.

-David



Re: Injection in OpenEJB Tomcat

Posted by Gurkan Erdogdu <cg...@gmail.com>.
>>>I was really asking how you implemented the scanning.  I.e. the code
details rather than the spec details.
>>>A link the scanning code will work too.
Scanning code is

https://svn.apache.org/repos/asf/incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/spi/ee/deployer/WarMetaDataDiscoveryImpl.java

>>>Do you have a link to the listener?
Listener code;
https://svn.apache.org/repos/asf/incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/servlet/WebBeansConfigurationListener.java

Some explanation :

Context initialized method calls
https://svn.apache.org/repos/asf/incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/lifecycle/WebBeansLifeCycle.java
instance's *"applicationStarted"* method.This method gets discovery class
instance and call its "init" and "scan" methods respectively.

   this.discovery = ServiceLoader.getService(MetaDataDiscoveryService.class);
>    this.discovery.init(event.getServletContext());
>
>    this.discovery.scan();
>
>

After that it calls,
https://svn.apache.org/repos/asf/incubator/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansContainerDeployer.java
"deploy" method to deploy all classes.

deployer.deploy(this.discovery);
>
>
WebBeansContainerDeployer "deploy" method calls "deployFromClassPath" method
to resolve "Managed Beans" and "EJB Beans". It gets all scanned classes via
given scanner.

protected void deployFromClassPath(MetaDataDiscoveryService scanner)
throws ClassNotFoundException
>
>
I hope this help

Thanks;

--Gurkan

2009/8/18 David Blevins <da...@visi.com>

>
> On Aug 17, 2009, at 11:13 PM, Gurkan Erdogdu wrote:
>
>  Hi David,
>>
>> Firstly, thanks for answering.
>>
>> As you specified we currently boot OpenWebBeans as a servlet context
>> listener to get all OWB  classes and to create OWB specific beans. For
>> each
>> class, we ask OpenEJB whether it is an EJB related class or not. If it is
>> not an EJB class, we define OWB "*Managed Bean*" instance, if it is we
>> create "*EJB Bean*" instance.
>>
>
> Nice.
>
>  OWB beans are used for creating actual object instances whenever they are
>> injected into some other beans. OWB container finds which bean it injects
>> using type safe algorithm. (In below example, it tries to find OWB Managed
>> Bean with "*API Type*" PaymentProcessor and "*Binding Type*" is @Payment)
>>
>> For Example;
>>
>> class Person{
>>  @Payment PaymentProcessor processor;
>> }
>>
>
> I was really asking how you implemented the scanning.  I.e. the code
> details rather than the spec details.
>
> A link the scanning code will work too.
>
>  We could probably boot you a lot sooner so you can participate more
>>>>>
>>>> closely in deployment.
>> Tomcat calls our context listener after deployment, so we are able to use
>> EJB integration. So there is no problem for deployment ordering
>>
>
> We do need to scan those classes at deploy time to ensure all the resources
> they need are created, added to JNDI, etc. by the time the app starts.  So
> we will need to find a way to boot you a bit sooner.
>
> Do you have a link to the listener?
>
> -David
>
>


-- 
Gurkan Erdogdu
http://gurkanerdogdu.blogspot.com

Re: Injection in OpenEJB Tomcat

Posted by David Blevins <da...@visi.com>.
On Aug 17, 2009, at 11:13 PM, Gurkan Erdogdu wrote:

> Hi David,
>
> Firstly, thanks for answering.
>
> As you specified we currently boot OpenWebBeans as a servlet context
> listener to get all OWB  classes and to create OWB specific beans.  
> For each
> class, we ask OpenEJB whether it is an EJB related class or not. If  
> it is
> not an EJB class, we define OWB "*Managed Bean*" instance, if it is we
> create "*EJB Bean*" instance.

Nice.

> OWB beans are used for creating actual object instances whenever  
> they are
> injected into some other beans. OWB container finds which bean it  
> injects
> using type safe algorithm. (In below example, it tries to find OWB  
> Managed
> Bean with "*API Type*" PaymentProcessor and "*Binding Type*" is  
> @Payment)
>
> For Example;
>
> class Person{
>   @Payment PaymentProcessor processor;
> }

I was really asking how you implemented the scanning.  I.e. the code  
details rather than the spec details.

A link the scanning code will work too.

>>>> We could probably boot you a lot sooner so you can participate more
> closely in deployment.
> Tomcat calls our context listener after deployment, so we are able  
> to use
> EJB integration. So there is no problem for deployment ordering

We do need to scan those classes at deploy time to ensure all the  
resources they need are created, added to JNDI, etc. by the time the  
app starts.  So we will need to find a way to boot you a bit sooner.

Do you have a link to the listener?

-David


Re: Injection in OpenEJB Tomcat

Posted by Gurkan Erdogdu <cg...@gmail.com>.
Hi David,

Firstly, thanks for answering.

As you specified we currently boot OpenWebBeans as a servlet context
listener to get all OWB  classes and to create OWB specific beans. For each
class, we ask OpenEJB whether it is an EJB related class or not. If it is
not an EJB class, we define OWB "*Managed Bean*" instance, if it is we
create "*EJB Bean*" instance.

OWB beans are used for creating actual object instances whenever they are
injected into some other beans. OWB container finds which bean it injects
using type safe algorithm. (In below example, it tries to find OWB Managed
Bean with "*API Type*" PaymentProcessor and "*Binding Type*" is @Payment)

For Example;

class Person{
   @Payment PaymentProcessor processor;
}

After the "Managed Bean" creates an object instance , it handles post
construct operations like injection of instance's fields. My aim is to call
OpenEJB specific injections into newly created object instance here. If
created object instance is EJB instance, we are done because, OpenEJB
handles injections for us.

>>>On the OpenWebBeans side, what kind of code would be needed to get a list
of Managed bean classes?
As explained above. So we get all classes in booting.

>>>What do you guys have going on in that area now and could it be possible
to reuse that ClassFinder instance?
We also scans paths as explained above using servlet context listener.

>>>I guess on that same question, how is OpenWebBeans booted?
As explained above.

>>>We could probably boot you a lot sooner so you can participate more
closely in deployment.
Tomcat calls our context listener after deployment, so we are able to use
EJB integration. So there is no problem for deployment ordering

Thanks;

--Gurkan

2009/8/18 David Blevins <da...@visi.com>

> On Aug 17, 2009, at 1:06 PM, Gurkan Erdogdu wrote:
>
>  Hi;
>>
>> I would like to inject @EJB,@WebServiceRef, @Resource, @PersistenceUnit,
>> @PersistenceContext into the  OpenWebbeans Managed Bean instance in the
>> Tomcat Environment. For example, in managed bean instance Person
>>
>> @RequestScoped
>> @Named
>> public class Person
>> {
>>   @EJB, @WebServiceRef, bla... bla...
>> }
>>
>> I tried to understand the "assembler tomcat" but no success. There are no
>> comments for understanding code. So, my question is how to inject those
>> type
>> of instances into the Managed Bean instance ? Is there any API to use?
>>
>> I will give Managed Bean instance to the OpenEJB and it injects above
>> types
>> of instances.
>>
>
> We'd have to do something custom for this to get the bean classes scanned
> at deploy time.  After that you can inject on an existing instance with code
> like so:
>
>    Object instance = ...//
>    List<Injection> metadata = ...// can worry about this one later
>    Context javaCompEnv = ..// the result of new
> InitialContext().lookup("java:comp/env")
>
>    InjectionProcessor processor = new InjectionProcessor(instance,
> metadata, javaCompEnv);
>
>    processor.createInstance();
>
> On the OpenWebBeans side, what kind of code would be needed to get a list
> of Managed bean classes?
>
> On that same topic, we will have already scanned the webapp classpath for
> all annotations using the ClassFinder from xbean-finder.  Ideally you
> wouldn't need to scan the classpath again and could just reuse that cached
> data.  What do you guys have going on in that area now and could it be
> possible to reuse that ClassFinder instance?  Geronimo does the same thing
> with a cached ClassFinder.
>
> I guess on that same question, how is OpenWebBeans booted?  I have to
> imagine you're using a servlet that loads on startup.  We could probably
> boot you a lot sooner so you can participate more closely in deployment.
>
>
> -David
>
>


-- 
Gurkan Erdogdu
http://gurkanerdogdu.blogspot.com

Re: Injection in OpenEJB Tomcat

Posted by David Blevins <da...@visi.com>.
On Aug 17, 2009, at 1:06 PM, Gurkan Erdogdu wrote:

> Hi;
>
> I would like to inject @EJB,@WebServiceRef, @Resource,  
> @PersistenceUnit,
> @PersistenceContext into the  OpenWebbeans Managed Bean instance in  
> the
> Tomcat Environment. For example, in managed bean instance Person
>
> @RequestScoped
> @Named
> public class Person
> {
>    @EJB, @WebServiceRef, bla... bla...
> }
>
> I tried to understand the "assembler tomcat" but no success. There  
> are no
> comments for understanding code. So, my question is how to inject  
> those type
> of instances into the Managed Bean instance ? Is there any API to use?
>
> I will give Managed Bean instance to the OpenEJB and it injects  
> above types
> of instances.

We'd have to do something custom for this to get the bean classes  
scanned at deploy time.  After that you can inject on an existing  
instance with code like so:

     Object instance = ...//
     List<Injection> metadata = ...// can worry about this one later
     Context javaCompEnv = ..// the result of new  
InitialContext().lookup("java:comp/env")

     InjectionProcessor processor = new InjectionProcessor(instance,  
metadata, javaCompEnv);

     processor.createInstance();

On the OpenWebBeans side, what kind of code would be needed to get a  
list of Managed bean classes?

On that same topic, we will have already scanned the webapp classpath  
for all annotations using the ClassFinder from xbean-finder.  Ideally  
you wouldn't need to scan the classpath again and could just reuse  
that cached data.  What do you guys have going on in that area now and  
could it be possible to reuse that ClassFinder instance?  Geronimo  
does the same thing with a cached ClassFinder.

I guess on that same question, how is OpenWebBeans booted?  I have to  
imagine you're using a servlet that loads on startup.  We could  
probably boot you a lot sooner so you can participate more closely in  
deployment.


-David