Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Fwd: Round advice on constructor?

btw, it works if I go with this:

class MyObject(text: String) {

  println("init:" + text)
  var v = text

  def talk(): String = {
    println(v)
    v
  }
}

I'll try to find how scala init the object, maybe I need to intercept at other place instead of the new(..)


Thanks

Leon




On Tue, Jun 10, 2014 at 2:01 PM, Alexander Kriegisch <Alexander@xxxxxxxxxxxxxx> wrote:
Read my answer again and apply my suggestions, please. Bind arguments via args() and be fine. If you do not bind them, there is no point in calling proceed with any parameters. That it works seems to be pure chance or even a regression rather than by design. Use the force, young Padawan.


Am 10.06.2014 um 18:17 schrieb Leon Ma <tutufool@xxxxxxxxx>:

No lucky to get it work in scala.

Here's my java version:

public class AopTest {

    @Test
    public void test(){
        MyJob t = new MyJob("leon");
        String result = t.talk();
        System.out.println(result);
        Assert.assertEquals(result, "LEON");
    }

}


public class MyJob {
    private String text;
    public MyJob(String value){
        text = value;
    }

    public String talk(){
        System.out.println(text);
        return text;
    }
}

@Aspect
public class MyJobAspect {

    @Around(value = "execution (com.leon.aop.MyJob.new(..))")
    public Object constructCP(ProceedingJoinPoint jp) throws Throwable {
        try {
            System.out.println("Start..");
            Object[] args = jp.getArgs();
            args[0] = args[0].toString().toUpperCase();
            return jp.proceed(args);
        } finally {
            System.out.println("End...");
        }

    }

}


The java version works well ( btw, the jp.getArgs() do return values)


No idea why scala not works.

Is there any work around? any point even before execution I can try?


Thanks

Leon




On Tue, Jun 10, 2014 at 2:05 AM, Alexander Kriegisch <alexander@xxxxxxxxxxxxxx> wrote:
>        jp.proceed(text..toUpperCase)

Sorry, typo. I mean text.toUpperCase, and probably you need to wrap that into an Object[], i.e.

        jp.proceed(new Object[] { text..toUpperCase })



Alexander Kriegisch schrieb am 10.06.2014 11:02:

> Hello again, Leon.
>
> The Object[] returned by jp.getArgs() will not be passed on to jp.proceed().
> You need to bind the parameter(s) you want to modify via args(), e.g. like this
> (untested, I hope I got the Scala syntax right):
>
> @Around("execution (com.leon.aop.MyObject.new(String, ..)) && args(text)")
> def constructCP(jp: ProceedingJoinPoint, String text): Object = {
>    try {
>        println("Start...")
>        jp.proceed(text..toUpperCase)
>    } finally {
>        println("End...")
>    }
> }
>
> CAVEAT: If you manipulate parameters in subclass constructors this way, they
> will not be passed on to base class constructors via super() calls due to the
> execution order of
>  - preinitialization(*.new())
>  - initialization(*.new())
>  - execution(*.new()).
>
> If you really want to catch the former two as well, you need and around()
> advice on
>  - call(*.new())
>
> For background information see my answer and its sample output on
> http://stackoverflow.com/a/15571384/1082681.
>
> Regards
> --
> Alexander Kriegisch
> http://scrum-master.de
>
>
> Leon Ma schrieb am 10.06.2014 10:10:
>
>> I've successfully used round advice to intercept input parameter for a method.
>>
>>
>> However, it seems constructor does not work for me. Here're my test: (It's in
>> scala, but should be easy to understand)
>>
>>
>> class MyObjectTest extends FlatSpecLike with Matchers {
>>
>>
>>   "MyObjectAspect" should "work" in {
>>
>>     val t = new MyObject("leon")
>>
>>     val result = t.talk()
>>
>>     println(result)
>>
>>     result should be("LEON")
>>
>>   }
>>
>> }
>>
>>
>> class MyObject(text: String) {
>>
>>
>>   def talk(): String = {
>>
>>     println("MyObject " + text)
>>
>>     text
>>
>>   }
>>
>> }
>>
>>
>> @Aspect
>>
>> class MyObjectAspect {
>>
>>
>>   @Around(value = "execution (com.leon.aop.MyObject.new(..))")
>>
>>   def constructCP(jp: ProceedingJoinPoint): Object = {
>>
>>
>>     try {
>>
>>       println("Start...")
>>
>>       val args = jp.getArgs
>>
>>       args(0) = args(0).toString.toUpperCase
>>
>>       jp.proceed(args)
>>
>>     } finally {
>>
>>       println("End...")
>>
>>     }
>>
>>
>>   }
>>
>>
>> }
>>
>>
>> output:
>>
>>
>> Start...
>>
>> End...
>>
>> MyObject leon
>>
>> leon
>>
>>
>> "[leon]" was not equal to "[LEON]"
>>
>> org.scalatest.exceptions.TestFailedException: "[leon]" was not equal to
>> "[LEON]"
>>
>> at
>> org.scalatest.MatchersHelper$.newTestFailedException(MatchersHelper.scala:160)
>>
>> at
>> org.scalatest.Matchers$ShouldMethodHelper$.shouldMatcher(Matchers.scala:6141)
>>
>> at org.scalatest.Matchers$AnyShouldWrapper.should(Matchers.scala:6175)
>>
>> at com.leon.aop.MyObjectTest$$anonfun$1.apply$mcV$sp(ConstructorTest.scala:18)
>>
>>
>> Anything wrong?
>>
>>
>> Thanks
>>
>>
>> Leon
>>
>>
>
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users

_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users

_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users



Back to the top