Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Incorrect Code Generation on 1.9.1

Hi Andy!

Thanks for the reply!

I may have screwed this up in transit. The !within is important because we explicitly do not want to instrument our own code/package namespace.

My original expectation was that something akin to this would do the trick:
after() : throwing (call || call || call || call ) && !within(com.example.app) 

So any time any of the given calls(outside our Package namespace) throws we would instrument it.

Regarding running something by accident on my aspects:
I will have to recheck on this, but as far as I understand it, the new Android Java 8 build procedures require a desugaring step 
but I do not believe that would also transform depended upon aar files(?).

Thanks for the pointers I'll have a look how the compiled class files compare to the compiled class and if there is any indication of tool mucking!

Thanks,

Andreas Marschke.

On Wed, 1 Aug 2018 at 02:47, Andy Clement <andrew.clement@xxxxxxxxx> wrote:

Did you mean to apply your within condition to all of those call pointcuts? Right now your pointcut reads:

  within && call || call || call || call || call || call

and because && is higher precedence than || then your within() restriction only applies to the first call.  It says "I'm interested in all these calls anywhere except for getErrorStream() calls which I'm only interested in if getErrorStream() isn't called from com.company.example code".  If you meant to say "I'm interested in all these calls if they are made outside of the com.company.example code" then you need

  within && (call || call || call || call || call || call)

Once encoded in an attribute we actually use an OR construct that only takes two operands, this means your:

within && call || call || call || call || call || call || call

becomes
  (within && call) || (call || (call || (call || (call || ....

and that is what you see  in the compiled aspect you looked inside. So this:

@AfterThrowing(pointcut="((!within(com.company.example..*) && call(* java.net.HttpURLConnection.getErrorStream())) || (call(* java.net.HttpURLConnection.getResponseCode()) || (call(* java.net.HttpURLConnection.getResponseMessage()) || (call(* javax.net.ssl.HttpsURLConnection.getLocalCertificates()) || (call(* javax.net.ssl.HttpsURLConnection.getCipherSuite()) || (call(* javax.net.ssl.HttpsURLConnection.getServerCertificates()) || (call(* javax.net.ssl.HttpsURLConnection.getPeerPrincipal()) || (call(* javax.net.ssl.HttpsURLConnection.getLocalPrincipal()) || (call(* java.net.URLConnection.connect()) || (call(* java.net.URLConnection.getContent()) || (call(* java.net.URLConnection.getContentEncoding()) || (call(* java.net.URLConnection.getContentLength()) || (call(* java.net.URLConnection.getContentType()) || (call(* java.net.URLConnection.getDate()) || (call(* java.net.URLConnection.getExpiration()) || (call(* java.net.URLConnection.getHeaderField()) || (call(* java.net.URLConnection.getHeaderFieldDate()) || (call(* java.net.URLConnection.getHeaderFieldKey()) || (call(* java.net.URLConnection.getHeaderFields()) || (call(* java.net.URLConnection.getInputStream()) || call(* java.net.URLConnection.getLastModified())))))))))))))))))))))", throwing="ex", argNames="ex")

is right, based on your pointcut. But if you meant to apply the within to all your calls, then it wouldn't look like this. We do rewrite pointcuts during compilation, so don't expect what you find encoded in the aspect to be exactly the same as what you typed. But will be what you typed in your source code in a DNF form with various internal components sorted to put those that can be cheaply evaluated first.

Now, having said all that what is happening with your exception? You might find if you included the parentheses so within() applies to all of your calls, maybe it behaves, but when I see this:

    java.lang.RuntimeException: Problem processing attributes in com/company/example/android/aspects/URLConnectionExceptionsAspect.class
    Caused by: org.aspectj.apache.bcel.classfile.ClassFormatException: Index 151 into constant pool (size:150) is invalid
    	at org.aspectj.apache.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:119)

My first suspicion is that something has transformed the aspect in between when it got compiled and when it got used. If there is any other tool that transforms the class files it can damage the aspect if it isn't aware of what it is dealing with.  For example, if you compiled the aspect and then ran something on the compiled class that threw away constant pool entries that didn't look like they were being used, well it might throw out entries it shouldn't because it didn't realize they were referenced from the additional attributes in the class file.

So is there anything running on your compiled aspects before they get used?

Andy


On Mon, 30 Jul 2018 at 19:37, Andreas Marschke <andreas.marschke@xxxxxxxxx> wrote:
Hi all!

I am working on a larger project where we define Aspects in their own *.aj files.

In a recent trial against an Android project using Java 8 I found the exception as attached (exception.txt)

Reviewing the source code, the corresponding line looks like this:

after() throwing (Exception ex) : (!within(com.company.example..*) &&
    call (* java.net.HttpURLConnection.getErrorStream()) ||
    call (* java.net.HttpURLConnection.getResponseCode()) ||
    call (* java.net.HttpURLConnection.getResponseMessage()) ||
    call (* javax.net.ssl.HttpsURLConnection.getLocalCertificates()) ||
    call (* javax.net.ssl.HttpsURLConnection.getCipherSuite()) ||
    call (* javax.net.ssl.HttpsURLConnection.getServerCertificates()) ||
    call (* javax.net.ssl.HttpsURLConnection.getPeerPrincipal()) ||
    call (* javax.net.ssl.HttpsURLConnection.getLocalPrincipal()) ||
    call (* java.net.URLConnection.connect()) ||
    call (* java.net.URLConnection.getContent()) ||
    call (* java.net.URLConnection.getContentEncoding()) ||
    call (* java.net.URLConnection.getContentLength()) ||
    call (* java.net.URLConnection.getContentType()) ||
    call (* java.net.URLConnection.getDate()) ||
    call (* java.net.URLConnection.getExpiration()) ||
    call (* java.net.URLConnection.getHeaderField()) ||
    call (* java.net.URLConnection.getHeaderFieldDate()) ||
    call (* java.net.URLConnection.getHeaderFieldKey()) ||
    call (* java.net.URLConnection.getHeaderFields()) ||
    call (* java.net.URLConnection.getInputStream()) ||
    call (* java.net.URLConnection.getLastModified()))

As far as I understand the way after throwing conditions are supposed to be defined this should still apply for any 
of these getters except if they are thrown my project.

Keep in mind our Aspects aren't applied against our own code but against 3rd party code.

Decompiling the respective class file shows me the following like:

 @AfterThrowing(pointcut="((!within(com.company.example..*) && call(* java.net.HttpURLConnection.getErrorStream())) || (call(* java.net.HttpURLConnection.getResponseCode()) || (call(* java.net.HttpURLConnection.getResponseMessage()) || (call(* javax.net.ssl.HttpsURLConnection.getLocalCertificates()) || (call(* javax.net.ssl.HttpsURLConnection.getCipherSuite()) || (call(* javax.net.ssl.HttpsURLConnection.getServerCertificates()) || (call(* javax.net.ssl.HttpsURLConnection.getPeerPrincipal()) || (call(* javax.net.ssl.HttpsURLConnection.getLocalPrincipal()) || (call(* java.net.URLConnection.connect()) || (call(* java.net.URLConnection.getContent()) || (call(* java.net.URLConnection.getContentEncoding()) || (call(* java.net.URLConnection.getContentLength()) || (call(* java.net.URLConnection.getContentType()) || (call(* java.net.URLConnection.getDate()) || (call(* java.net.URLConnection.getExpiration()) || (call(* java.net.URLConnection.getHeaderField()) || (call(* java.net.URLConnection.getHeaderFieldDate()) || (call(* java.net.URLConnection.getHeaderFieldKey()) || (call(* java.net.URLConnection.getHeaderFields()) || (call(* java.net.URLConnection.getInputStream()) || call(* java.net.URLConnection.getLastModified())))))))))))))))))))))", throwing="ex", argNames="ex")

As you can see the compiled result filters for each after one another? That shouldn't happen right?

Any idea how I can fix this? Or avoid this from happening?

--
Kind regards,

Andreas Marschke.

_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users


--
Mit freundlichen Grüßen,

Andreas Marschke.
_________________________________________________________

Back to the top