You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Ryan Zoerner <ry...@gmail.com> on 2011/05/24 07:28:43 UTC

some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner

I have some thoughts that I wanted to post to the dev list.

Here they are:

The RP will need to choose between lifecylces, possibly just selecting which
existing cxf
resourceProvider to choose, based upon annotation. The annotations may be
found in the
class resource info object, obtainable from the JAXRSService. Look up the
EJB annotations
and find out which EJB-lifecycle this class is subscribing to, then call the
appropriate
cxf RP. We will need to know which cxf RP, at the time of SF.setRP(EJB_RP);

"EJB_RP" will call Singleton- or per-request- RP's, or some other, based on
@'s.


Exceptions: if thrown, what does cxf normally do with it? Does this vary
between
            exceptions. If cxf always passes it off to the server container,
then
            that is just fine. Need to get a list of all possible exceptions

            throwable and map them to exception responses, via
customExMapper?

            will we need to have the exceptionMapper called automatically,
so that
            the user doesn't have to remember to set it, just to have cxf do

            what user should take for grantd?

What else do ejb annotation's do, besides dictate lifecycle? Does cxf
app-lifecycle
function handle, or need to handle any of these functions? Does java
normally
handle them? Does a server typically handle any of them?

ClassScanner idea:
-----------------------------------------------------------------------------------
Ok, so in terms of lifecycle management, when an ejb class is declared as a
root
resource, it will need to be handled by a given resourceProvider. This will
handle the various lifecycles that EJB's provide. When the setResourceClass
is
called on an ejb-annotated root resource, cxf should have a mechanism in
place
to recognize the ejb annotation, as-such, by looking it up in a list, and
force cxf to use the custom resource provider. The annotations are part of
the
information that goes into the classResourceInfo object that resides with
the
JAXRSServiceFactory. There may be some way to listen for the creation of the

classResourceInfo object, and then use it, at that time, to decide whether
the
customResourceProvider should be the default.
-----------------------------------------------------------------------------------

Thank you.

Ryan

Re: some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner

Posted by Ryan Zoerner <ry...@gmail.com>.
you will note that nabble mangled the ); in my email, which is what caused
me to think of this.

Ryan

Re: some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner

Posted by Ryan Zoerner <ry...@gmail.com>.
and btw, I didn't intend any pun on your initials.

Ryan

Re: some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner

Posted by Ryan Zoerner <ry...@gmail.com>.
Also, I suppose that you could just use AnnotationUtils on "o" in the formal
params and then find out isEJB() and ejbLifecycle from that.

Ryan

Re: some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner

Posted by Ryan Zoerner <ry...@gmail.com>.
Of course, resourceInstance should probably be resoureceProvider. Then you
can just call the variable provider from methods where necessary.

Ryan

Re: some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner

Posted by Sergey Beryozkin <sb...@gmail.com>.
Well, may be you need to have an EJB factory injected into that
provider, as shown here:
http://websvn.ow2.org/filedetails.php?repname=jonas&path=%2Fjonas%2Ftrunk%2Fjonas%2Fmodules%2Fservices%2Fwebservices%2Fcxf%2Fsrc%2Fmain%2Fjava%2Forg%2Fow2%2Fjonas%2Fws%2Fcxf%2Feasybeans%2FEasyBeansInvokerFactory.java

Or may be your provider (but only your provider, in the constructor),
can check a resourceClass's annotations and then do something similar
to what you prototyped but not delegating to CXF but to
container-specific EJB utility code/factories. I think you do need to
try CXF JAX-WS as suggested earlier, in order to understand how to
integrate (as far as the creation of instances is concerned) or at
least to peruse the relevant code, ask questions there, etc

Cheers, Sergey

On Wed, May 25, 2011 at 1:32 PM, Sergey Beryozkin <sb...@gmail.com> wrote:
> Hi Ryan
>
> Don't worry about those typos, it happens all the time, I can confirm that :-)
>
> On Wed, May 25, 2011 at 3:04 AM, Ryan Zoerner <ry...@gmail.com> wrote:
>> This is what I had in mind for an RP constructor: Incidentally, EJB
>> annotations show up in the cri. under
>> ClassResourceInfo.elementData[i].resourceClass.declaredAnnotations.table[j].
>> h.type.name  and
>> ClassResourceInfo.elementData[i].resourceClass.declaredAnnotations.table[j].h.memberValues.table[k].key
>> and
>> ClassResourceInfo.elementData[i].resourceClass.declaredAnnotations.table[j].h.memberValues.table[k].value
>>
>>
>> as an example, I annotated Customer.java with @EJB and find:
>> interface javax.ejb.EJB
>> @javax.ejb.EJB(beanName=, mappedName=, beanInterface=class java.lang.Object,
>> description=, name=)
>>
>> within the cri associated with serverF.serviceF.classResourceInfos...
>>
> They show up because those annotations are retained at runtime, but we
> don't have to deal with them. It's the job of EJB
> factories/proxies/etc to deal with them. The only thing we need to do
> is to have a provider that will ask a container-specific EJB
> factory/etc to create and release the instance.
>
>
>> ----------------------------------------------------------------------------------------------------------------------------------------------------
>> public class JAXRS_EJBResourceProvider implements ResourceProvider
>> {
>>    enum EjbLifecycle
>>    {
>>        STATELESS,
>>        STATEFUL,
>>        SINGLETON
>>    }
>>
>>    private Object resourceInstance;
>>
>>    public JAXRS_EJBResourceProvider(Object o, JAXRSServerFactoryBean sfb)
>>    {
>>        if( isEJB(o, sfb) )
>>        {
>>            EjbLifecycle ejbLifecycle = getLifecycleFromAnnotation( o, sfb
>> );
>>            if( ejbLifecycle == EjbLifecycle.STATELESS )
>>            {
>>                resourceInstance = delegateTo( STATELESS_delegatee );
>>            }
>>            else if( ejbLifecycle == EjbLifecycle.STATEFUL )
>>            {
>>                resourceInstance = delegateTo( STATEFUL_delegatee );
>>            }
>>            else if( ejbLifecycle == EjbLifecycle.SINGLETON )
>>            {
>>                resourceInstance = delegateTo( SINGLETON_delegatee );
>>            }
>>            else
>>            {
>>                throw new impossibleThingHappenedException();
>>            }
>>        }
>>        else
>>        {
>>            return;
>>        }
>>        return;
>>    }
>> }
>
> I can see how it may work in principle, but please accept that CXF
> itself can not manage instantiating EJB resource classes itself. It
> has to delegate to EJB factories because they may be keeping pools of
> EJB beans and do whatever EJB factories do for adding additional pre
> or post processing handlers around EJB beans.
> Thus you don't need a reference to JAXRSServerFactoryBean, and in fact
> you don't need Object reference because it your EJBProvider that will
> create Objects. Check CXF JAX-RS singleton or per-request
> ResourceProvider impls. It is only a reference to an (EJB) resource
> class that needs to be passed to a constructor. And you definitely do
> not need to cache create objects. That was the reason I thought
> writing a custom provider for your initial CustomerService project and
> debugging it would help you
>
> Cheers, Sergey
>



-- 
Sergey Beryozkin

Application Integration Division of Talend
http://sberyozkin.blogspot.com

Re: some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Ryan

Don't worry about those typos, it happens all the time, I can confirm that :-)

On Wed, May 25, 2011 at 3:04 AM, Ryan Zoerner <ry...@gmail.com> wrote:
> This is what I had in mind for an RP constructor: Incidentally, EJB
> annotations show up in the cri. under
> ClassResourceInfo.elementData[i].resourceClass.declaredAnnotations.table[j].
> h.type.name  and
> ClassResourceInfo.elementData[i].resourceClass.declaredAnnotations.table[j].h.memberValues.table[k].key
> and
> ClassResourceInfo.elementData[i].resourceClass.declaredAnnotations.table[j].h.memberValues.table[k].value
>
>
> as an example, I annotated Customer.java with @EJB and find:
> interface javax.ejb.EJB
> @javax.ejb.EJB(beanName=, mappedName=, beanInterface=class java.lang.Object,
> description=, name=)
>
> within the cri associated with serverF.serviceF.classResourceInfos...
>
They show up because those annotations are retained at runtime, but we
don't have to deal with them. It's the job of EJB
factories/proxies/etc to deal with them. The only thing we need to do
is to have a provider that will ask a container-specific EJB
factory/etc to create and release the instance.


> ----------------------------------------------------------------------------------------------------------------------------------------------------
> public class JAXRS_EJBResourceProvider implements ResourceProvider
> {
>    enum EjbLifecycle
>    {
>        STATELESS,
>        STATEFUL,
>        SINGLETON
>    }
>
>    private Object resourceInstance;
>
>    public JAXRS_EJBResourceProvider(Object o, JAXRSServerFactoryBean sfb)
>    {
>        if( isEJB(o, sfb) )
>        {
>            EjbLifecycle ejbLifecycle = getLifecycleFromAnnotation( o, sfb
> );
>            if( ejbLifecycle == EjbLifecycle.STATELESS )
>            {
>                resourceInstance = delegateTo( STATELESS_delegatee );
>            }
>            else if( ejbLifecycle == EjbLifecycle.STATEFUL )
>            {
>                resourceInstance = delegateTo( STATEFUL_delegatee );
>            }
>            else if( ejbLifecycle == EjbLifecycle.SINGLETON )
>            {
>                resourceInstance = delegateTo( SINGLETON_delegatee );
>            }
>            else
>            {
>                throw new impossibleThingHappenedException();
>            }
>        }
>        else
>        {
>            return;
>        }
>        return;
>    }
> }

I can see how it may work in principle, but please accept that CXF
itself can not manage instantiating EJB resource classes itself. It
has to delegate to EJB factories because they may be keeping pools of
EJB beans and do whatever EJB factories do for adding additional pre
or post processing handlers around EJB beans.
Thus you don't need a reference to JAXRSServerFactoryBean, and in fact
you don't need Object reference because it your EJBProvider that will
create Objects. Check CXF JAX-RS singleton or per-request
ResourceProvider impls. It is only a reference to an (EJB) resource
class that needs to be passed to a constructor. And you definitely do
not need to cache create objects. That was the reason I thought
writing a custom provider for your initial CustomerService project and
debugging it would help you

Cheers, Sergey

Re: some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner

Posted by Ryan Zoerner <ry...@gmail.com>.
This is what I had in mind for an RP constructor: Incidentally, EJB
annotations show up in the cri. under
ClassResourceInfo.elementData[i].resourceClass.declaredAnnotations.table[j].
h.type.name  and
ClassResourceInfo.elementData[i].resourceClass.declaredAnnotations.table[j].h.memberValues.table[k].key
and
ClassResourceInfo.elementData[i].resourceClass.declaredAnnotations.table[j].h.memberValues.table[k].value


as an example, I annotated Customer.java with @EJB and find:
interface javax.ejb.EJB
@javax.ejb.EJB(beanName=, mappedName=, beanInterface=class java.lang.Object,
description=, name=)

within the cri associated with serverF.serviceF.classResourceInfos...

----------------------------------------------------------------------------------------------------------------------------------------------------
public class JAXRS_EJBResourceProvider implements ResourceProvider
{
    enum EjbLifecycle
    {
        STATELESS,
        STATEFUL,
        SINGLETON
    }

    private Object resourceInstance;

    public JAXRS_EJBResourceProvider(Object o, JAXRSServerFactoryBean sfb)
    {
        if( isEJB(o, sfb) )
        {
            EjbLifecycle ejbLifecycle = getLifecycleFromAnnotation( o, sfb
);
            if( ejbLifecycle == EjbLifecycle.STATELESS )
            {
                resourceInstance = delegateTo( STATELESS_delegatee );
            }
            else if( ejbLifecycle == EjbLifecycle.STATEFUL )
            {
                resourceInstance = delegateTo( STATEFUL_delegatee );
            }
            else if( ejbLifecycle == EjbLifecycle.SINGLETON )
            {
                resourceInstance = delegateTo( SINGLETON_delegatee );
            }
            else
            {
                throw new impossibleThingHappenedException();
            }
        }
        else
        {
            return;
        }
        return;
    }
}
----------------------------------------------------------------------------------------------------------------------------------------------------

Re: some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Ryan

On Tue, May 24, 2011 at 6:28 AM, Ryan Zoerner <ry...@gmail.com> wrote:
> I have some thoughts that I wanted to post to the dev list.
>
> Here they are:
>
> The RP will need to choose between lifecylces, possibly just selecting which
> existing cxf
> resourceProvider to choose, based upon annotation. The annotations may be
> found in the
> class resource info object, obtainable from the JAXRSService. Look up the
> EJB annotations
> and find out which EJB-lifecycle this class is subscribing to, then call the
> appropriate
> cxf RP. We will need to know which cxf RP, at the time of SF.setRP(EJB_RP);
>
> "EJB_RP" will call Singleton- or per-request- RP's, or some other, based on
> @'s.
>

You are right that CXF JAX-RS EJBResourceProvider will need to make
sure EJB lifecycles are enforced properly.
But it is not what CXF itself should worry about, ResourceProvider
will just need to delegate to appropriate
EJB factory, check this link which was posted earlier on for example:

http://websvn.ow2.org/filedetails.php?repname=jonas&path=%2Fjonas%2Ftrunk%2Fjonas%2Fmodules%2Fservices%2Fwebservices%2Fcxf%2Fsrc%2Fmain%2Fjava%2Forg%2Fow2%2Fjonas%2Fws%2Fcxf%2Feasybeans%2FEasyBeansInvokerFactory.java

That is the custom implementation of CXF Invoker Factory - at the
moment CXF JAX-RS does not check such factories given that
ResourceProvider acts as the factory itself and it provides some more
information to the JAXA-RS runtime it needs when dealing with a given
invocation.

I don't  know right know if we can create  EJBResourceProvider which
would work equally well with say EJB in JBoss, Jonas, or Glassfish, as
it seems different containers provide different EJB integration
points. However, having it working with at least one container will
give us enough info to make sure a custom EJB ResourceProvider can be
provided for all EJB aware containers.

I'd personally go for JBoss or Jonas or Geronimo, because they have a
CXF JAX-WS integration. I'd try and see how CXF JAX-WS layer is
enhanced there to have EJB integrated.

For example, I'd download Jonas, and would checkout Jonas CXF JAX-WS
integration code. Then I'd ask some questions on Jonas lists or check
their docs on how to setup a CXF JAX-WS EJB endpoint. Then I'd start
Jonas in debug mode (recall the chat about the remote debugging), put
a breakpoint in EasyBeansInvokerFactory.java and run the client and
see what is going on in EJB Invoker.

Or I'd download JBoss Community Edition (see
http://www.jboss.org/jbossas/downloads/, probably 6.0), and then
either checkout the CXF JAX-WS integration code (see
http://www.jboss.org/jbossws/sourcecode.html) or download the relevant
JBoss WS/CXF source bundle. Then check these docs:
http://community.jboss.org/wiki/JBossWS-StackCXFUserGuide.

Or try Geronimo.

Before trying to debug I'd review EJB tutorials explaining how EJB
beans are created and released so that I could understand the relevant
code in Jonas/JBoss/Geronimo better.

And then, after the above process is finished, I'd just write my
custom EJBInvoker in 30 mins.

This is how I'd do it because it was a long time ago since I was doing
some work with EJB. Actually, I did a JBoss EJB test not that long
ago, but it was a security-related test I was working upon.

If you are confident and understand how EJB beans are managed then
perhaps you can start with writing a custom EJb ResourceProvider right
now.

You need to decide which container you are going to work with - I
haven't done EJB development myself so I can't recommend. Try to
select the container which will make it easier for you to get started.

>
> Exceptions: if thrown, what does cxf normally do with it? Does this vary
> between
>            exceptions. If cxf always passes it off to the server container,
> then
>            that is just fine. Need to get a list of all possible exceptions
>
>            throwable and map them to exception responses, via
> customExMapper?
>
>            will we need to have the exceptionMapper called automatically,
> so that
>            the user doesn't have to remember to set it, just to have cxf do
>
>            what user should take for grantd?
>

CXF JAX-RS will propagate a current exception if no ExceptionMapper is
found, otherwise it will
ask that mapper to convert it into HTTP response.

> What else do ejb annotation's do, besides dictate lifecycle? Does cxf
> app-lifecycle
> function handle, or need to handle any of these functions? Does java
> normally
> handle them? Does a server typically handle any of them?
>

I don't know. I think the only thing we need to worry about is about
manging the lifecycle of EJB beans

> ClassScanner idea:
> -----------------------------------------------------------------------------------
> Ok, so in terms of lifecycle management, when an ejb class is declared as a
> root
> resource, it will need to be handled by a given resourceProvider. This will
> handle the various lifecycles that EJB's provide. When the setResourceClass
> is
> called on an ejb-annotated root resource, cxf should have a mechanism in
> place
> to recognize the ejb annotation, as-such, by looking it up in a list, and
> force cxf to use the custom resource provider.

CXF JAX-RS code will only check for JAX-RS annotations. Your custom
provider will be asked to create and release instances and it will
probably won't check any annotations as well, it will just delegate to
the relevant EJB factory.
At this stage, please assume no auto discovery of EJB root resources
and providers is needed.
Assume you manually configure JAX-RS endpoints (from code or Spring),
if you can make it work then adding an auto-discovery feature will be
the easy thing to do.

> The annotations are part of
> the
> information that goes into the classResourceInfo object that resides with
> the
> JAXRSServiceFactory. There may be some way to listen for the creation of the
>
> classResourceInfo object, and then use it, at that time, to decide whether
> the
> customResourceProvider should be the default.
> -----------------------------------------------------------------------------------
>

Only the info deduced from JAX-RS annotations will make it
ClassResourceInfo. Your custom resource provider is the key piece.
I'd recommend you to get the most straighforward EJB 'case' working
first, by simplifying whatever possible, in order to see it working
and feel good about it. I actually think now that this is a very
complex project given how much info you have to filter through. I know
how seriously you are trying to approach it - but my advice is to stay
focused on the most relevant parts/info and get something working
fast.

Thanks, Sergey

> Thank you.
>
> Ryan
>



-- 
Sergey Beryozkin

Application Integration Division of Talend
http://sberyozkin.blogspot.com