You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Igor Drobiazko <ig...@gmail.com> on 2011/06/04 08:58:41 UTC

Plastic & proxy annotations

Looks like we need to discuss the "copying annotations to proxies with
plastic" issue again. I just tried to migrate tapestry-jpa to plastic and
experience some problems. I didn't commit it because I don't want to break
the build, so here is an example of CommitAfterMethodAdvice.

public class CommitAfterMethodAdvice implements MethodAdvice
{

    private final EntityManagerManager manager;

    public CommitAfterMethodAdvice(final EntityManagerManager manager)
    {
        super();
        this.manager = manager;
    }

    public void advise(final MethodInvocation invocation)
    {
        final EntityTransaction transaction = getTransaction(invocation);

        if (transaction != null && !transaction.isActive())
        {
            transaction.begin();
        }

        try
        {
            invocation.proceed();
        }
        catch (final RuntimeException e)
        {
            if (transaction != null && transaction.isActive())
            {
                transaction.rollback();
            }

            throw e;
        }

        // Success or checked exception:

        if (transaction != null && transaction.isActive())
        {
            transaction.commit();
        }

    }

    private EntityTransaction getTransaction(final MethodInvocation
invocation)
    {
        final PersistenceContext annotation =
invocation.getAnnotation(PersistenceContext.class);

        EntityManager em = JpaInternalUtils.getEntityManager(manager,
annotation);

        if (em == null)
            return null;

        return em.getTransaction();
    }

}


The problem is invocation.getAnnotation(PersistenceContext.class) which
always returns null. If I recall it correctly, Plastic doesn't copy
annotations to proxies, so that my DAO proxies loose the annotations. Here
is the DAO:

public interface UserDAO
{
    @CommitAfter
    @PersistenceContext(unitName = AppConstants.TEST_PERSISTENCE_UNIT)
    void add(User user);

    .....
}

What I don't get, is why PlasticClass is able to see the
@ CommitAfter annotation, but the MethodInvocation of the corresponding
advise not. Here is the Worker.

public class CommitAfterWorker implements ComponentClassTransformWorker2
{
    private final CommitAfterMethodAdvice advice;

    public CommitAfterWorker(final EntityManagerManager manager)
    {
        advice = new CommitAfterMethodAdvice(manager);
    }

    public void transform(PlasticClass plasticClass, TransformationSupport
support, MutableComponentModel model)
    {
        for (final PlasticMethod method :
plasticClass.getMethodsWithAnnotation(CommitAfter.class))
        {
            method.addAdvice(advice);
        }
    }
}


Any ideas?

-- 
Best regards,

Igor Drobiazko
http://tapestry5.de

Re: Plastic & proxy annotations

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Mon, 06 Jun 2011 14:43:28 -0300, Igor Drobiazko  
<ig...@gmail.com> wrote:

> On Mon, Jun 6, 2011 at 7:21 PM, Howard Lewis Ship <hl...@gmail.com>  
> wrote:
>>
>> I've never been happy with exposing the details of
>> the service implementation class to decorators.
>>
> Well, in this case in looks like the annotations from the service  
> interface are not accessible from a MethodAdvice.

And all other libraries and frameworks which aren't based on T-IoC will  
still not see the annotations . . .

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: Plastic & proxy annotations

Posted by Igor Drobiazko <ig...@gmail.com>.
On Mon, Jun 6, 2011 at 7:21 PM, Howard Lewis Ship <hl...@gmail.com> wrote:
>
>
> I've never been happy with exposing the details of
> the service implementation class to decorators.
>
>
Well, in this case in looks like the annotations from the service interface
are not accessible from a MethodAdvice.


-- 
Best regards,

Igor Drobiazko
http://tapestry5.de

Re: Plastic & proxy annotations

Posted by Howard Lewis Ship <hl...@gmail.com>.
On Mon, Jun 6, 2011 at 9:58 AM, Thiago H. de Paula Figueiredo
<th...@gmail.com> wrote:
> On Sat, 04 Jun 2011 03:58:41 -0300, Igor Drobiazko
> <ig...@gmail.com> wrote:
>
>> Looks like we need to discuss the "copying annotations to proxies with
>> plastic" issue again.
>
> +1 for copying annotations to proxies. This is a huge limiting factor for
> Tapestry-IoC. Unfortunately, I don't have the time to investigate it myself,
> even being very curious about it.

I went down that route and hit a roadblock of some kind; instead I
changed other APIs to expose a mix of annotations from the
implementation class (when known) and from the service interface.
Perhaps with Javassist/ClassFactory so marginalized now, the roadblock
won't be a big issue, but the more we can do using the API, the more
comfortable I feel. I've never been happy with exposing the details of
the service implementation class to decorators.

>
> --
> Thiago H. de Paula Figueiredo
> Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and
> instructor
> Owner, Ars Machina Tecnologia da Informação Ltda.
> http://www.arsmachina.com.br
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: dev-help@tapestry.apache.org
>
>



-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: Plastic & proxy annotations

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Sat, 04 Jun 2011 03:58:41 -0300, Igor Drobiazko  
<ig...@gmail.com> wrote:

> Looks like we need to discuss the "copying annotations to proxies with
> plastic" issue again.

+1 for copying annotations to proxies. This is a huge limiting factor for  
Tapestry-IoC. Unfortunately, I don't have the time to investigate it  
myself, even being very curious about it.

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: Plastic & proxy annotations

Posted by Igor Drobiazko <ig...@gmail.com>.
The @CommitAfter annotation is not the problem. It visible as we access it
from PlastiClass, as shown here:

 for (final PlasticMethod method :
> plasticClass.getMethodsWithAnnotation(CommitAfter.class))
>        {
>            method.addAdvice(advice);
>        }
>    }
> }


Tthe problem is @PersistenceContex annotation which is accessed from
MethodInvocation in an advice. See here:

>    private EntityTransaction getTransaction(final MethodInvocation
> invocation)
>    {
>        final PersistenceContext annotation =
> invocation.getAnnotation(PersistenceContext.class);


Note that there is a significant difference between these two use cases. The
@CommitAfter annotation is accessed at class transformation time. The
@ PersistenceContext annotation at runtime. Might be the reason for
different behaviour?

-- 
Best regards,

Igor Drobiazko
http://tapestry5.de

Re: Plastic & proxy annotations

Posted by Howard Lewis Ship <hl...@gmail.com>.
On Fri, Jun 3, 2011 at 11:58 PM, Igor Drobiazko
<ig...@gmail.com> wrote:
> Looks like we need to discuss the "copying annotations to proxies with
> plastic" issue again. I just tried to migrate tapestry-jpa to plastic and
> experience some problems. I didn't commit it because I don't want to break
> the build, so here is an example of CommitAfterMethodAdvice.
>
> public class CommitAfterMethodAdvice implements MethodAdvice
> {
>
>    private final EntityManagerManager manager;
>
>    public CommitAfterMethodAdvice(final EntityManagerManager manager)
>    {
>        super();
>        this.manager = manager;
>    }
>
>    public void advise(final MethodInvocation invocation)
>    {
>        final EntityTransaction transaction = getTransaction(invocation);
>
>        if (transaction != null && !transaction.isActive())
>        {
>            transaction.begin();
>        }
>
>        try
>        {
>            invocation.proceed();
>        }
>        catch (final RuntimeException e)
>        {
>            if (transaction != null && transaction.isActive())
>            {
>                transaction.rollback();
>            }
>
>            throw e;
>        }
>
>        // Success or checked exception:
>
>        if (transaction != null && transaction.isActive())
>        {
>            transaction.commit();
>        }
>
>    }
>
>    private EntityTransaction getTransaction(final MethodInvocation
> invocation)
>    {
>        final PersistenceContext annotation =
> invocation.getAnnotation(PersistenceContext.class);

So you're saying that the annotation isn't visible here?  I would
think that it would be visible here, on a component class.  I'm not as
sure what happens when this advise is used in the context of a service
and a MethodAdviceReceiver.


>
>        EntityManager em = JpaInternalUtils.getEntityManager(manager,
> annotation);
>
>        if (em == null)
>            return null;
>
>        return em.getTransaction();
>    }
>
> }
>
>
> The problem is invocation.getAnnotation(PersistenceContext.class) which
> always returns null. If I recall it correctly, Plastic doesn't copy
> annotations to proxies, so that my DAO proxies loose the annotations. Here
> is the DAO:
>
> public interface UserDAO
> {
>    @CommitAfter
>    @PersistenceContext(unitName = AppConstants.TEST_PERSISTENCE_UNIT)
>    void add(User user);
>
>    .....
> }
>
> What I don't get, is why PlasticClass is able to see the
> @ CommitAfter annotation, but the MethodInvocation of the corresponding
> advise not. Here is the Worker.
>
> public class CommitAfterWorker implements ComponentClassTransformWorker2
> {
>    private final CommitAfterMethodAdvice advice;
>
>    public CommitAfterWorker(final EntityManagerManager manager)
>    {
>        advice = new CommitAfterMethodAdvice(manager);
>    }
>
>    public void transform(PlasticClass plasticClass, TransformationSupport
> support, MutableComponentModel model)
>    {

Here, the @CommitAfter is actually on the class. No interface vs.
implementation confusion.

>        for (final PlasticMethod method :
> plasticClass.getMethodsWithAnnotation(CommitAfter.class))
>        {
>            method.addAdvice(advice);
>        }
>    }
> }
>
>
> Any ideas?
>
> --
> Best regards,
>
> Igor Drobiazko
> http://tapestry5.de
>



-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org