Bounded type disappearing after weaving

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Bounded type disappearing after weaving

Tim Webster
Hi,

I'm seeing a problem where a class with multiple bounds is 'losing' one of its bounds after weaving occurs.

Even more strange is that it is only happening on a specific platform.

a brief outline of the problem:

Source class:

public class ExistenceByIdSpecification<D extends AbstractDomainObject & Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification

What happens is the 'AbstractDomainObject' bound (which is a class) is disappearing, and in the bytecode we end up with something like this:

public class ExistenceByIdSpecification<D extends Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification, org.springframework.beans.factory.aspectj.ConfigurableObject


this results is a runtime error whenever the constructor is called (I've removed package names - this is from a unit test):


ExistenceByIdSpecification.&lt;init&gt;(L/Identifiable;)V" type="java.lang.NoSuchMethodError"><![CDATA[java.lang.NoSuchMethodError: ExistenceByIdSpecification.<init>(L/Identifiable;)V
        at ExistenceByIdSpecificationTest.<init>(ExistenceByIdSpecificationTest.java:33)



Also, the bytecode for the class is quite a bit larger on the environment where this isn't working properly - it looks like stuff related to @Configurable is repeated.

I'm suspecting AspectJ here because when I compile the code with AspectJ disabled, the bytecode looks correct.

The environments details I've tried are:

works properly:
Windows 7
Manjaro Linux (current version)
Oracle JDK 1.7.0_79
AspectJ 1.8.6

Doesn't work:
CentOS 7
Oracle JDK 1.7.0_79, Oracle JDK 1.8.0_65, OpenJDK 1.7.0
AspectJ 1.8.6, 1.8.8

Unfortunately we want to target CentOS as a build platform, so that's why this is a problem for us!

I've only included basic details here to see if anyone has heard of this problem.  I'm happy to provide more detail if required.  I know that a sample project is ideal, but I may struggle to reproduce that (although I will try).

Thanks,


_______________________________________________
aspectj-users mailing list
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
Reply | Threaded
Open this post in threaded view
|

Re: Bounded type disappearing after weaving

Andy Clement
Hi Tim,

I'm certainly interested in more details. I haven't heard of that problem but I suspect although we have some regression tests for generics we don't have a lot exercising multiple bounds. I'll have a look in the code but as you say, a sample that exhibits the problem will enable me to fix it much quicker (or sort out a temporary workaround - maybe something silly like reordering the bounds in the source code).  Please raise a bug and share any more info there or with me on email.

cheers,
Andy

On 26 January 2016 at 03:26, Tim Webster <[hidden email]> wrote:
Hi,

I'm seeing a problem where a class with multiple bounds is 'losing' one of its bounds after weaving occurs.

Even more strange is that it is only happening on a specific platform.

a brief outline of the problem:

Source class:

public class ExistenceByIdSpecification<D extends AbstractDomainObject & Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification

What happens is the 'AbstractDomainObject' bound (which is a class) is disappearing, and in the bytecode we end up with something like this:

public class ExistenceByIdSpecification<D extends Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification, org.springframework.beans.factory.aspectj.ConfigurableObject


this results is a runtime error whenever the constructor is called (I've removed package names - this is from a unit test):


ExistenceByIdSpecification.&lt;init&gt;(L/Identifiable;)V" type="java.lang.NoSuchMethodError"><![CDATA[java.lang.NoSuchMethodError: ExistenceByIdSpecification.<init>(L/Identifiable;)V
        at ExistenceByIdSpecificationTest.<init>(ExistenceByIdSpecificationTest.java:33)



Also, the bytecode for the class is quite a bit larger on the environment where this isn't working properly - it looks like stuff related to @Configurable is repeated.

I'm suspecting AspectJ here because when I compile the code with AspectJ disabled, the bytecode looks correct.

The environments details I've tried are:

works properly:
Windows 7
Manjaro Linux (current version)
Oracle JDK 1.7.0_79
AspectJ 1.8.6

Doesn't work:
CentOS 7
Oracle JDK 1.7.0_79, Oracle JDK 1.8.0_65, OpenJDK 1.7.0
AspectJ 1.8.6, 1.8.8

Unfortunately we want to target CentOS as a build platform, so that's why this is a problem for us!

I've only included basic details here to see if anyone has heard of this problem.  I'm happy to provide more detail if required.  I know that a sample project is ideal, but I may struggle to reproduce that (although I will try).

Thanks,


_______________________________________________
aspectj-users mailing list
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
Reply | Threaded
Open this post in threaded view
|

Re: Bounded type disappearing after weaving

Tim Webster
Hi Andy,

I'm trying to come up with a sample project but so far no luck - it's behaving itself so far.  I'll keep trying though.

Like I said it only seems to happen in CentOS at the moment.  I'd be surprised if it had anything to do with the OS itself, but my point is that even if I did come up with a sample do you think you could reproduce the conditions?  Is there anything else I can give you in the meantime (bytecode, source code, etc)>

Thanks,

Tim


On Tue, Jan 26, 2016 at 4:29 PM, Andy Clement <[hidden email]> wrote:
Hi Tim,

I'm certainly interested in more details. I haven't heard of that problem but I suspect although we have some regression tests for generics we don't have a lot exercising multiple bounds. I'll have a look in the code but as you say, a sample that exhibits the problem will enable me to fix it much quicker (or sort out a temporary workaround - maybe something silly like reordering the bounds in the source code).  Please raise a bug and share any more info there or with me on email.

cheers,
Andy

On 26 January 2016 at 03:26, Tim Webster <[hidden email]> wrote:
Hi,

I'm seeing a problem where a class with multiple bounds is 'losing' one of its bounds after weaving occurs.

Even more strange is that it is only happening on a specific platform.

a brief outline of the problem:

Source class:

public class ExistenceByIdSpecification<D extends AbstractDomainObject & Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification

What happens is the 'AbstractDomainObject' bound (which is a class) is disappearing, and in the bytecode we end up with something like this:

public class ExistenceByIdSpecification<D extends Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification, org.springframework.beans.factory.aspectj.ConfigurableObject


this results is a runtime error whenever the constructor is called (I've removed package names - this is from a unit test):


ExistenceByIdSpecification.&lt;init&gt;(L/Identifiable;)V" type="java.lang.NoSuchMethodError"><![CDATA[java.lang.NoSuchMethodError: ExistenceByIdSpecification.<init>(L/Identifiable;)V
        at ExistenceByIdSpecificationTest.<init>(ExistenceByIdSpecificationTest.java:33)



Also, the bytecode for the class is quite a bit larger on the environment where this isn't working properly - it looks like stuff related to @Configurable is repeated.

I'm suspecting AspectJ here because when I compile the code with AspectJ disabled, the bytecode looks correct.

The environments details I've tried are:

works properly:
Windows 7
Manjaro Linux (current version)
Oracle JDK 1.7.0_79
AspectJ 1.8.6

Doesn't work:
CentOS 7
Oracle JDK 1.7.0_79, Oracle JDK 1.8.0_65, OpenJDK 1.7.0
AspectJ 1.8.6, 1.8.8

Unfortunately we want to target CentOS as a build platform, so that's why this is a problem for us!

I've only included basic details here to see if anyone has heard of this problem.  I'm happy to provide more detail if required.  I know that a sample project is ideal, but I may struggle to reproduce that (although I will try).

Thanks,


_______________________________________________
aspectj-users mailing list
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
Reply | Threaded
Open this post in threaded view
|

Re: Bounded type disappearing after weaving

Andy Clement
Typically this would end up being that the JVM on the target OS just happens to put things in a different place on the heap which might then cause things to be iterated over in a different order. For example if we slot a bunch of objects into a ‘Set’ without caring about an order an then ask for all the entries. It will typically be a bug in the code that is accidentally relying on an ordering when it shouldn’t - and we’ve been getting away with it because we’ve never seen this other order before or in any testing. I presume you are not doing anything that might affect the type definition, like an inter type declaration or declare parents? (Although you might be advising code within the affected type).

I would first try it on my linux (ubuntu i think I have)  but if that doesn’t show an issue I’d probably try running a centos virtual machine or some such. If all else fails I’d need to construct you some debug builds to perhaps collect extra diagnostics.  Hmm, do you compile that original source on centos or just weave it there?  I’m vaguely wondering if the java compiler used to build the original source produces a subtley different class file on centos vs windows.

cheers,
Andy

On Jan 26, 2016, at 9:09 AM, Tim Webster <[hidden email]> wrote:

Hi Andy,

I'm trying to come up with a sample project but so far no luck - it's behaving itself so far.  I'll keep trying though.

Like I said it only seems to happen in CentOS at the moment.  I'd be surprised if it had anything to do with the OS itself, but my point is that even if I did come up with a sample do you think you could reproduce the conditions?  Is there anything else I can give you in the meantime (bytecode, source code, etc)>

Thanks,

Tim


On Tue, Jan 26, 2016 at 4:29 PM, Andy Clement <[hidden email]> wrote:
Hi Tim,

I'm certainly interested in more details. I haven't heard of that problem but I suspect although we have some regression tests for generics we don't have a lot exercising multiple bounds. I'll have a look in the code but as you say, a sample that exhibits the problem will enable me to fix it much quicker (or sort out a temporary workaround - maybe something silly like reordering the bounds in the source code).  Please raise a bug and share any more info there or with me on email.

cheers,
Andy

On 26 January 2016 at 03:26, Tim Webster <[hidden email]> wrote:
Hi,

I'm seeing a problem where a class with multiple bounds is 'losing' one of its bounds after weaving occurs.

Even more strange is that it is only happening on a specific platform.

a brief outline of the problem:

Source class:

public class ExistenceByIdSpecification<D extends AbstractDomainObject & Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification

What happens is the 'AbstractDomainObject' bound (which is a class) is disappearing, and in the bytecode we end up with something like this:

public class ExistenceByIdSpecification<D extends Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification, org.springframework.beans.factory.aspectj.ConfigurableObject


this results is a runtime error whenever the constructor is called (I've removed package names - this is from a unit test):


ExistenceByIdSpecification.&lt;init&gt;(L/Identifiable;)V" type="java.lang.NoSuchMethodError"><![CDATA[java.lang.NoSuchMethodError: ExistenceByIdSpecification.<init>(L/Identifiable;)V
        at ExistenceByIdSpecificationTest.<init>(ExistenceByIdSpecificationTest.java:33)



Also, the bytecode for the class is quite a bit larger on the environment where this isn't working properly - it looks like stuff related to @Configurable is repeated.

I'm suspecting AspectJ here because when I compile the code with AspectJ disabled, the bytecode looks correct.

The environments details I've tried are:

works properly:
Windows 7
Manjaro Linux (current version)
Oracle JDK 1.7.0_79
AspectJ 1.8.6

Doesn't work:
CentOS 7
Oracle JDK 1.7.0_79, Oracle JDK 1.8.0_65, OpenJDK 1.7.0
AspectJ 1.8.6, 1.8.8

Unfortunately we want to target CentOS as a build platform, so that's why this is a problem for us!

I've only included basic details here to see if anyone has heard of this problem.  I'm happy to provide more detail if required.  I know that a sample project is ideal, but I may struggle to reproduce that (although I will try).

Thanks,


_______________________________________________
aspectj-users mailing list
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
Reply | Threaded
Open this post in threaded view
|

Re: Bounded type disappearing after weaving

Andy Clement
I’ve recreated it and am currently sorting it out. For me this code exhibits the problem:

— Code.java —
class B<T extends SomeClass & SomeInterface> {}
class SomeClass {}
interface SomeInterface {}

aspect X {
  declare parents: B implements java.io.Serializable;
}
—Code.java—

ajc -1.8 Code.java
javap B
class B<T extends SomeInterface> implements java.o.Serializable {

See how the type variable has lost the class bound. It only happens if you have interface bounds in addition to a class bound. Maybe your problem isn’t caused by doing declare parents but clearly there is a code path in AspectJ that produces the wrong signature attribute - and maybe whatever you do causes us to go down that path too.


cheers,
Andy


On Jan 26, 2016, at 11:56 AM, Andy Clement <[hidden email]> wrote:

Typically this would end up being that the JVM on the target OS just happens to put things in a different place on the heap which might then cause things to be iterated over in a different order. For example if we slot a bunch of objects into a ‘Set’ without caring about an order an then ask for all the entries. It will typically be a bug in the code that is accidentally relying on an ordering when it shouldn’t - and we’ve been getting away with it because we’ve never seen this other order before or in any testing. I presume you are not doing anything that might affect the type definition, like an inter type declaration or declare parents? (Although you might be advising code within the affected type).

I would first try it on my linux (ubuntu i think I have)  but if that doesn’t show an issue I’d probably try running a centos virtual machine or some such. If all else fails I’d need to construct you some debug builds to perhaps collect extra diagnostics.  Hmm, do you compile that original source on centos or just weave it there?  I’m vaguely wondering if the java compiler used to build the original source produces a subtley different class file on centos vs windows.

cheers,
Andy

On Jan 26, 2016, at 9:09 AM, Tim Webster <[hidden email]> wrote:

Hi Andy,

I'm trying to come up with a sample project but so far no luck - it's behaving itself so far.  I'll keep trying though.

Like I said it only seems to happen in CentOS at the moment.  I'd be surprised if it had anything to do with the OS itself, but my point is that even if I did come up with a sample do you think you could reproduce the conditions?  Is there anything else I can give you in the meantime (bytecode, source code, etc)>

Thanks,

Tim


On Tue, Jan 26, 2016 at 4:29 PM, Andy Clement <[hidden email]> wrote:
Hi Tim,

I'm certainly interested in more details. I haven't heard of that problem but I suspect although we have some regression tests for generics we don't have a lot exercising multiple bounds. I'll have a look in the code but as you say, a sample that exhibits the problem will enable me to fix it much quicker (or sort out a temporary workaround - maybe something silly like reordering the bounds in the source code).  Please raise a bug and share any more info there or with me on email.

cheers,
Andy

On 26 January 2016 at 03:26, Tim Webster <[hidden email]> wrote:
Hi,

I'm seeing a problem where a class with multiple bounds is 'losing' one of its bounds after weaving occurs.

Even more strange is that it is only happening on a specific platform.

a brief outline of the problem:

Source class:

public class ExistenceByIdSpecification<D extends AbstractDomainObject & Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification

What happens is the 'AbstractDomainObject' bound (which is a class) is disappearing, and in the bytecode we end up with something like this:

public class ExistenceByIdSpecification<D extends Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification, org.springframework.beans.factory.aspectj.ConfigurableObject


this results is a runtime error whenever the constructor is called (I've removed package names - this is from a unit test):


ExistenceByIdSpecification.&lt;init&gt;(L/Identifiable;)V" type="java.lang.NoSuchMethodError"><![CDATA[java.lang.NoSuchMethodError: ExistenceByIdSpecification.<init>(L/Identifiable;)V
        at ExistenceByIdSpecificationTest.<init>(ExistenceByIdSpecificationTest.java:33)



Also, the bytecode for the class is quite a bit larger on the environment where this isn't working properly - it looks like stuff related to @Configurable is repeated.

I'm suspecting AspectJ here because when I compile the code with AspectJ disabled, the bytecode looks correct.

The environments details I've tried are:

works properly:
Windows 7
Manjaro Linux (current version)
Oracle JDK 1.7.0_79
AspectJ 1.8.6

Doesn't work:
CentOS 7
Oracle JDK 1.7.0_79, Oracle JDK 1.8.0_65, OpenJDK 1.7.0
AspectJ 1.8.6, 1.8.8

Unfortunately we want to target CentOS as a build platform, so that's why this is a problem for us!

I've only included basic details here to see if anyone has heard of this problem.  I'm happy to provide more detail if required.  I know that a sample project is ideal, but I may struggle to reproduce that (although I will try).

Thanks,


_______________________________________________
aspectj-users mailing list
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
Reply | Threaded
Open this post in threaded view
|

Re: Bounded type disappearing after weaving

Andy Clement
I've put in some changes to fix the version of the problem I uncovered. If you want to try it out there is a new dev build available on the download page ( https://www.eclipse.org/aspectj/downloads.php ) or a new AspectJ maven snapshot in repo.spring.io (version 1.8.9.BUILD-SNAPSHOT)
<repository>
    <id>repo.spring.io</id>
    <name>SpringSource snapshots</name>
    <url>http://repo.spring.io/snapshot</url>
</repository>
If you get a chance to try them out, let me know if it makes any difference.

cheers,
Andy


On 26 January 2016 at 16:49, Andy Clement <[hidden email]> wrote:
I’ve recreated it and am currently sorting it out. For me this code exhibits the problem:

— Code.java —
class B<T extends SomeClass & SomeInterface> {}
class SomeClass {}
interface SomeInterface {}

aspect X {
  declare parents: B implements java.io.Serializable;
}
—Code.java—

ajc -1.8 Code.java
javap B
class B<T extends SomeInterface> implements java.o.Serializable {

See how the type variable has lost the class bound. It only happens if you have interface bounds in addition to a class bound. Maybe your problem isn’t caused by doing declare parents but clearly there is a code path in AspectJ that produces the wrong signature attribute - and maybe whatever you do causes us to go down that path too.


cheers,
Andy


On Jan 26, 2016, at 11:56 AM, Andy Clement <[hidden email]> wrote:

Typically this would end up being that the JVM on the target OS just happens to put things in a different place on the heap which might then cause things to be iterated over in a different order. For example if we slot a bunch of objects into a ‘Set’ without caring about an order an then ask for all the entries. It will typically be a bug in the code that is accidentally relying on an ordering when it shouldn’t - and we’ve been getting away with it because we’ve never seen this other order before or in any testing. I presume you are not doing anything that might affect the type definition, like an inter type declaration or declare parents? (Although you might be advising code within the affected type).

I would first try it on my linux (ubuntu i think I have)  but if that doesn’t show an issue I’d probably try running a centos virtual machine or some such. If all else fails I’d need to construct you some debug builds to perhaps collect extra diagnostics.  Hmm, do you compile that original source on centos or just weave it there?  I’m vaguely wondering if the java compiler used to build the original source produces a subtley different class file on centos vs windows.

cheers,
Andy

On Jan 26, 2016, at 9:09 AM, Tim Webster <[hidden email]> wrote:

Hi Andy,

I'm trying to come up with a sample project but so far no luck - it's behaving itself so far.  I'll keep trying though.

Like I said it only seems to happen in CentOS at the moment.  I'd be surprised if it had anything to do with the OS itself, but my point is that even if I did come up with a sample do you think you could reproduce the conditions?  Is there anything else I can give you in the meantime (bytecode, source code, etc)>

Thanks,

Tim


On Tue, Jan 26, 2016 at 4:29 PM, Andy Clement <[hidden email]> wrote:
Hi Tim,

I'm certainly interested in more details. I haven't heard of that problem but I suspect although we have some regression tests for generics we don't have a lot exercising multiple bounds. I'll have a look in the code but as you say, a sample that exhibits the problem will enable me to fix it much quicker (or sort out a temporary workaround - maybe something silly like reordering the bounds in the source code).  Please raise a bug and share any more info there or with me on email.

cheers,
Andy

On 26 January 2016 at 03:26, Tim Webster <[hidden email]> wrote:
Hi,

I'm seeing a problem where a class with multiple bounds is 'losing' one of its bounds after weaving occurs.

Even more strange is that it is only happening on a specific platform.

a brief outline of the problem:

Source class:

public class ExistenceByIdSpecification<D extends AbstractDomainObject & Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification

What happens is the 'AbstractDomainObject' bound (which is a class) is disappearing, and in the bytecode we end up with something like this:

public class ExistenceByIdSpecification<D extends Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification, org.springframework.beans.factory.aspectj.ConfigurableObject


this results is a runtime error whenever the constructor is called (I've removed package names - this is from a unit test):


ExistenceByIdSpecification.&lt;init&gt;(L/Identifiable;)V" type="java.lang.NoSuchMethodError"><![CDATA[java.lang.NoSuchMethodError: ExistenceByIdSpecification.<init>(L/Identifiable;)V
        at ExistenceByIdSpecificationTest.<init>(ExistenceByIdSpecificationTest.java:33)



Also, the bytecode for the class is quite a bit larger on the environment where this isn't working properly - it looks like stuff related to @Configurable is repeated.

I'm suspecting AspectJ here because when I compile the code with AspectJ disabled, the bytecode looks correct.

The environments details I've tried are:

works properly:
Windows 7
Manjaro Linux (current version)
Oracle JDK 1.7.0_79
AspectJ 1.8.6

Doesn't work:
CentOS 7
Oracle JDK 1.7.0_79, Oracle JDK 1.8.0_65, OpenJDK 1.7.0
AspectJ 1.8.6, 1.8.8

Unfortunately we want to target CentOS as a build platform, so that's why this is a problem for us!

I've only included basic details here to see if anyone has heard of this problem.  I'm happy to provide more detail if required.  I know that a sample project is ideal, but I may struggle to reproduce that (although I will try).

Thanks,


_______________________________________________
aspectj-users mailing list
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
Reply | Threaded
Open this post in threaded view
|

Re: Bounded type disappearing after weaving

Tim Webster
Hi Andy,

OK that fix looks like it worked.  I'm doing some more testing but so far so good.

...but I'm wondering if there is another issue.  I mentioned this briefly in the original email - the bytecode on the CentOS build looks quite different...it's larger with what looks like more references to the aspects.  This might be a different issue so I'm happy to start a new thread / open a new issue.

I've include 3 files (attached).  If you look at the Windows and Manjaro Linux ones they are identical.  The CentOS one is the different one.  There doesn't seem to be any problem with the code execution, but it doesn't look right, and I don't have the expertise to really determine if it's a problem or not. Can you have a look?

Anyway - big thanks for fixing this so quickly...:-)



On Wed, Jan 27, 2016 at 5:59 AM, Andy Clement <[hidden email]> wrote:
I've put in some changes to fix the version of the problem I uncovered. If you want to try it out there is a new dev build available on the download page ( https://www.eclipse.org/aspectj/downloads.php ) or a new AspectJ maven snapshot in repo.spring.io (version 1.8.9.BUILD-SNAPSHOT)
<repository>
    <id>repo.spring.io</id>
    <name>SpringSource snapshots</name>
    <url>http://repo.spring.io/snapshot</url>
</repository>
If you get a chance to try them out, let me know if it makes any difference.

cheers,
Andy


On 26 January 2016 at 16:49, Andy Clement <[hidden email]> wrote:
I’ve recreated it and am currently sorting it out. For me this code exhibits the problem:

— Code.java —
class B<T extends SomeClass & SomeInterface> {}
class SomeClass {}
interface SomeInterface {}

aspect X {
  declare parents: B implements java.io.Serializable;
}
—Code.java—

ajc -1.8 Code.java
javap B
class B<T extends SomeInterface> implements java.o.Serializable {

See how the type variable has lost the class bound. It only happens if you have interface bounds in addition to a class bound. Maybe your problem isn’t caused by doing declare parents but clearly there is a code path in AspectJ that produces the wrong signature attribute - and maybe whatever you do causes us to go down that path too.


cheers,
Andy


On Jan 26, 2016, at 11:56 AM, Andy Clement <[hidden email]> wrote:

Typically this would end up being that the JVM on the target OS just happens to put things in a different place on the heap which might then cause things to be iterated over in a different order. For example if we slot a bunch of objects into a ‘Set’ without caring about an order an then ask for all the entries. It will typically be a bug in the code that is accidentally relying on an ordering when it shouldn’t - and we’ve been getting away with it because we’ve never seen this other order before or in any testing. I presume you are not doing anything that might affect the type definition, like an inter type declaration or declare parents? (Although you might be advising code within the affected type).

I would first try it on my linux (ubuntu i think I have)  but if that doesn’t show an issue I’d probably try running a centos virtual machine or some such. If all else fails I’d need to construct you some debug builds to perhaps collect extra diagnostics.  Hmm, do you compile that original source on centos or just weave it there?  I’m vaguely wondering if the java compiler used to build the original source produces a subtley different class file on centos vs windows.

cheers,
Andy

On Jan 26, 2016, at 9:09 AM, Tim Webster <[hidden email]> wrote:

Hi Andy,

I'm trying to come up with a sample project but so far no luck - it's behaving itself so far.  I'll keep trying though.

Like I said it only seems to happen in CentOS at the moment.  I'd be surprised if it had anything to do with the OS itself, but my point is that even if I did come up with a sample do you think you could reproduce the conditions?  Is there anything else I can give you in the meantime (bytecode, source code, etc)>

Thanks,

Tim


On Tue, Jan 26, 2016 at 4:29 PM, Andy Clement <[hidden email]> wrote:
Hi Tim,

I'm certainly interested in more details. I haven't heard of that problem but I suspect although we have some regression tests for generics we don't have a lot exercising multiple bounds. I'll have a look in the code but as you say, a sample that exhibits the problem will enable me to fix it much quicker (or sort out a temporary workaround - maybe something silly like reordering the bounds in the source code).  Please raise a bug and share any more info there or with me on email.

cheers,
Andy

On 26 January 2016 at 03:26, Tim Webster <[hidden email]> wrote:
Hi,

I'm seeing a problem where a class with multiple bounds is 'losing' one of its bounds after weaving occurs.

Even more strange is that it is only happening on a specific platform.

a brief outline of the problem:

Source class:

public class ExistenceByIdSpecification<D extends AbstractDomainObject & Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification

What happens is the 'AbstractDomainObject' bound (which is a class) is disappearing, and in the bytecode we end up with something like this:

public class ExistenceByIdSpecification<D extends Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification, org.springframework.beans.factory.aspectj.ConfigurableObject


this results is a runtime error whenever the constructor is called (I've removed package names - this is from a unit test):


ExistenceByIdSpecification.&lt;init&gt;(L/Identifiable;)V" type="java.lang.NoSuchMethodError"><![CDATA[java.lang.NoSuchMethodError: ExistenceByIdSpecification.<init>(L/Identifiable;)V
        at ExistenceByIdSpecificationTest.<init>(ExistenceByIdSpecificationTest.java:33)



Also, the bytecode for the class is quite a bit larger on the environment where this isn't working properly - it looks like stuff related to @Configurable is repeated.

I'm suspecting AspectJ here because when I compile the code with AspectJ disabled, the bytecode looks correct.

The environments details I've tried are:

works properly:
Windows 7
Manjaro Linux (current version)
Oracle JDK 1.7.0_79
AspectJ 1.8.6

Doesn't work:
CentOS 7
Oracle JDK 1.7.0_79, Oracle JDK 1.8.0_65, OpenJDK 1.7.0
AspectJ 1.8.6, 1.8.8

Unfortunately we want to target CentOS as a build platform, so that's why this is a problem for us!

I've only included basic details here to see if anyone has heard of this problem.  I'm happy to provide more detail if required.  I know that a sample project is ideal, but I may struggle to reproduce that (although I will try).

Thanks,


_______________________________________________
aspectj-users mailing list
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users

bytecode.zip (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Bounded type disappearing after weaving

Andy Clement
I see a couple of things of interest:

- the type is marked ConfigurableObject
- there are numerous isAnnotationPresent checks guarding advice calls (checking if the type of ‘this’ in the method has the Configurable annotation).

Do you expect this type to be a ConfigurableObject? Are types further up this objects hierarchy marked with ConfigurableObject?
I ask because weaving may differ if the types are processed in a different order on each OS (which can happen because an ordering is not enforced/required).  If a type further up the hierarchy is woven first and matches the declare parents statement (from the spring aspect it is "declare parents: @Configurable * implements ConfigurableObject;”)  then it would get the ConfigurableObject interface and then when we hit your ExistenceByIdSpecification we would not add the interface again (because we were inheriting it).  But if hitting ExistenceByIdSpecification first we might add it here and then add it again when we hit the parent that also matches.

When this happens it is harmless, and not necessarily anything to worry about, it is just a different weave that basically does the same thing (although different weaves may offer a slight variance in performance). You could turn on the weaving output and see the order in which types are processed on different operating systems and see if there is a difference in ordering.

The isAnnotationPresent checks might be considered sub-optimal if the ‘alternate’ weaving ordering has determined they aren’t needed in this code - I’d need to recreate all this myself to debug further. When a pointcut element (like @this(Foo)) cannot be fully determined statically to be always true, it will insert a runtime check into the code that verifies it at runtime. It is possible these are also because on centos we aren’t weaving a super type of this type earlier than this type.

Thanks for testing the losing bounds fix, I’ll commit that now.

cheers,
Andy


On Jan 27, 2016, at 2:23 AM, Tim Webster <[hidden email]> wrote:

Hi Andy,

OK that fix looks like it worked.  I'm doing some more testing but so far so good.

...but I'm wondering if there is another issue.  I mentioned this briefly in the original email - the bytecode on the CentOS build looks quite different...it's larger with what looks like more references to the aspects.  This might be a different issue so I'm happy to start a new thread / open a new issue.

I've include 3 files (attached).  If you look at the Windows and Manjaro Linux ones they are identical.  The CentOS one is the different one.  There doesn't seem to be any problem with the code execution, but it doesn't look right, and I don't have the expertise to really determine if it's a problem or not. Can you have a look?

Anyway - big thanks for fixing this so quickly...:-)



On Wed, Jan 27, 2016 at 5:59 AM, Andy Clement <[hidden email]> wrote:
I've put in some changes to fix the version of the problem I uncovered. If you want to try it out there is a new dev build available on the download page ( https://www.eclipse.org/aspectj/downloads.php ) or a new AspectJ maven snapshot in repo.spring.io (version 1.8.9.BUILD-SNAPSHOT)
<repository>
    <id>repo.spring.io</id>
    <name>SpringSource snapshots</name>
    <url>http://repo.spring.io/snapshot</url>
</repository>
If you get a chance to try them out, let me know if it makes any difference.

cheers,
Andy


On 26 January 2016 at 16:49, Andy Clement <[hidden email]> wrote:
I’ve recreated it and am currently sorting it out. For me this code exhibits the problem:

— Code.java —
class B<T extends SomeClass & SomeInterface> {}
class SomeClass {}
interface SomeInterface {}

aspect X {
  declare parents: B implements java.io.Serializable;
}
—Code.java—

ajc -1.8 Code.java
javap B
class B<T extends SomeInterface> implements java.o.Serializable {

See how the type variable has lost the class bound. It only happens if you have interface bounds in addition to a class bound. Maybe your problem isn’t caused by doing declare parents but clearly there is a code path in AspectJ that produces the wrong signature attribute - and maybe whatever you do causes us to go down that path too.


cheers,
Andy


On Jan 26, 2016, at 11:56 AM, Andy Clement <[hidden email]> wrote:

Typically this would end up being that the JVM on the target OS just happens to put things in a different place on the heap which might then cause things to be iterated over in a different order. For example if we slot a bunch of objects into a ‘Set’ without caring about an order an then ask for all the entries. It will typically be a bug in the code that is accidentally relying on an ordering when it shouldn’t - and we’ve been getting away with it because we’ve never seen this other order before or in any testing. I presume you are not doing anything that might affect the type definition, like an inter type declaration or declare parents? (Although you might be advising code within the affected type).

I would first try it on my linux (ubuntu i think I have)  but if that doesn’t show an issue I’d probably try running a centos virtual machine or some such. If all else fails I’d need to construct you some debug builds to perhaps collect extra diagnostics.  Hmm, do you compile that original source on centos or just weave it there?  I’m vaguely wondering if the java compiler used to build the original source produces a subtley different class file on centos vs windows.

cheers,
Andy

On Jan 26, 2016, at 9:09 AM, Tim Webster <[hidden email]> wrote:

Hi Andy,

I'm trying to come up with a sample project but so far no luck - it's behaving itself so far.  I'll keep trying though.

Like I said it only seems to happen in CentOS at the moment.  I'd be surprised if it had anything to do with the OS itself, but my point is that even if I did come up with a sample do you think you could reproduce the conditions?  Is there anything else I can give you in the meantime (bytecode, source code, etc)>

Thanks,

Tim


On Tue, Jan 26, 2016 at 4:29 PM, Andy Clement <[hidden email]> wrote:
Hi Tim,

I'm certainly interested in more details. I haven't heard of that problem but I suspect although we have some regression tests for generics we don't have a lot exercising multiple bounds. I'll have a look in the code but as you say, a sample that exhibits the problem will enable me to fix it much quicker (or sort out a temporary workaround - maybe something silly like reordering the bounds in the source code).  Please raise a bug and share any more info there or with me on email.

cheers,
Andy

On 26 January 2016 at 03:26, Tim Webster <[hidden email]> wrote:
Hi,

I'm seeing a problem where a class with multiple bounds is 'losing' one of its bounds after weaving occurs.

Even more strange is that it is only happening on a specific platform.

a brief outline of the problem:

Source class:

public class ExistenceByIdSpecification<D extends AbstractDomainObject & Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification

What happens is the 'AbstractDomainObject' bound (which is a class) is disappearing, and in the bytecode we end up with something like this:

public class ExistenceByIdSpecification<D extends Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification, org.springframework.beans.factory.aspectj.ConfigurableObject


this results is a runtime error whenever the constructor is called (I've removed package names - this is from a unit test):


ExistenceByIdSpecification.&lt;init&gt;(L/Identifiable;)V" type="java.lang.NoSuchMethodError"><![CDATA[java.lang.NoSuchMethodError: ExistenceByIdSpecification.<init>(L/Identifiable;)V
        at ExistenceByIdSpecificationTest.<init>(ExistenceByIdSpecificationTest.java:33)



Also, the bytecode for the class is quite a bit larger on the environment where this isn't working properly - it looks like stuff related to @Configurable is repeated.

I'm suspecting AspectJ here because when I compile the code with AspectJ disabled, the bytecode looks correct.

The environments details I've tried are:

works properly:
Windows 7
Manjaro Linux (current version)
Oracle JDK 1.7.0_79
AspectJ 1.8.6

Doesn't work:
CentOS 7
Oracle JDK 1.7.0_79, Oracle JDK 1.8.0_65, OpenJDK 1.7.0
AspectJ 1.8.6, 1.8.8

Unfortunately we want to target CentOS as a build platform, so that's why this is a problem for us!

I've only included basic details here to see if anyone has heard of this problem.  I'm happy to provide more detail if required.  I know that a sample project is ideal, but I may struggle to reproduce that (although I will try).

Thanks,


_______________________________________________
aspectj-users mailing list
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users

<bytecode.zip>_______________________________________________
aspectj-users mailing list
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
Reply | Threaded
Open this post in threaded view
|

Re: Bounded type disappearing after weaving

Tim Webster
Hi Andy,

The ExistenceByIdSpecification object isn't annotated with @Configurable, but its parent is.

Also FYI the 'bounds' problem showed up in Ubuntu as well as CentOS, so maybe it's a bit more common that I realized.  However, this 'extra weaving' seems limited to CentOS.

Either way, I'm a bit less worried about it thanks to your explanation.  If you think it's a problem or if you would like to investigate more, I'm happy to help if I can provide anything else.

Thanks again,

Tim






On Wed, Jan 27, 2016 at 7:43 PM, Andy Clement <[hidden email]> wrote:
I see a couple of things of interest:

- the type is marked ConfigurableObject
- there are numerous isAnnotationPresent checks guarding advice calls (checking if the type of ‘this’ in the method has the Configurable annotation).

Do you expect this type to be a ConfigurableObject? Are types further up this objects hierarchy marked with ConfigurableObject?
I ask because weaving may differ if the types are processed in a different order on each OS (which can happen because an ordering is not enforced/required).  If a type further up the hierarchy is woven first and matches the declare parents statement (from the spring aspect it is "declare parents: @Configurable * implements ConfigurableObject;”)  then it would get the ConfigurableObject interface and then when we hit your ExistenceByIdSpecification we would not add the interface again (because we were inheriting it).  But if hitting ExistenceByIdSpecification first we might add it here and then add it again when we hit the parent that also matches.

When this happens it is harmless, and not necessarily anything to worry about, it is just a different weave that basically does the same thing (although different weaves may offer a slight variance in performance). You could turn on the weaving output and see the order in which types are processed on different operating systems and see if there is a difference in ordering.

The isAnnotationPresent checks might be considered sub-optimal if the ‘alternate’ weaving ordering has determined they aren’t needed in this code - I’d need to recreate all this myself to debug further. When a pointcut element (like @this(Foo)) cannot be fully determined statically to be always true, it will insert a runtime check into the code that verifies it at runtime. It is possible these are also because on centos we aren’t weaving a super type of this type earlier than this type.

Thanks for testing the losing bounds fix, I’ll commit that now.

cheers,
Andy


On Jan 27, 2016, at 2:23 AM, Tim Webster <[hidden email]> wrote:

Hi Andy,

OK that fix looks like it worked.  I'm doing some more testing but so far so good.

...but I'm wondering if there is another issue.  I mentioned this briefly in the original email - the bytecode on the CentOS build looks quite different...it's larger with what looks like more references to the aspects.  This might be a different issue so I'm happy to start a new thread / open a new issue.

I've include 3 files (attached).  If you look at the Windows and Manjaro Linux ones they are identical.  The CentOS one is the different one.  There doesn't seem to be any problem with the code execution, but it doesn't look right, and I don't have the expertise to really determine if it's a problem or not. Can you have a look?

Anyway - big thanks for fixing this so quickly...:-)



On Wed, Jan 27, 2016 at 5:59 AM, Andy Clement <[hidden email]> wrote:
I've put in some changes to fix the version of the problem I uncovered. If you want to try it out there is a new dev build available on the download page ( https://www.eclipse.org/aspectj/downloads.php ) or a new AspectJ maven snapshot in repo.spring.io (version 1.8.9.BUILD-SNAPSHOT)
<repository>
    <id>repo.spring.io</id>
    <name>SpringSource snapshots</name>
    <url>http://repo.spring.io/snapshot</url>
</repository>
If you get a chance to try them out, let me know if it makes any difference.

cheers,
Andy


On 26 January 2016 at 16:49, Andy Clement <[hidden email]> wrote:
I’ve recreated it and am currently sorting it out. For me this code exhibits the problem:

— Code.java —
class B<T extends SomeClass & SomeInterface> {}
class SomeClass {}
interface SomeInterface {}

aspect X {
  declare parents: B implements java.io.Serializable;
}
—Code.java—

ajc -1.8 Code.java
javap B
class B<T extends SomeInterface> implements java.o.Serializable {

See how the type variable has lost the class bound. It only happens if you have interface bounds in addition to a class bound. Maybe your problem isn’t caused by doing declare parents but clearly there is a code path in AspectJ that produces the wrong signature attribute - and maybe whatever you do causes us to go down that path too.


cheers,
Andy


On Jan 26, 2016, at 11:56 AM, Andy Clement <[hidden email]> wrote:

Typically this would end up being that the JVM on the target OS just happens to put things in a different place on the heap which might then cause things to be iterated over in a different order. For example if we slot a bunch of objects into a ‘Set’ without caring about an order an then ask for all the entries. It will typically be a bug in the code that is accidentally relying on an ordering when it shouldn’t - and we’ve been getting away with it because we’ve never seen this other order before or in any testing. I presume you are not doing anything that might affect the type definition, like an inter type declaration or declare parents? (Although you might be advising code within the affected type).

I would first try it on my linux (ubuntu i think I have)  but if that doesn’t show an issue I’d probably try running a centos virtual machine or some such. If all else fails I’d need to construct you some debug builds to perhaps collect extra diagnostics.  Hmm, do you compile that original source on centos or just weave it there?  I’m vaguely wondering if the java compiler used to build the original source produces a subtley different class file on centos vs windows.

cheers,
Andy

On Jan 26, 2016, at 9:09 AM, Tim Webster <[hidden email]> wrote:

Hi Andy,

I'm trying to come up with a sample project but so far no luck - it's behaving itself so far.  I'll keep trying though.

Like I said it only seems to happen in CentOS at the moment.  I'd be surprised if it had anything to do with the OS itself, but my point is that even if I did come up with a sample do you think you could reproduce the conditions?  Is there anything else I can give you in the meantime (bytecode, source code, etc)>

Thanks,

Tim


On Tue, Jan 26, 2016 at 4:29 PM, Andy Clement <[hidden email]> wrote:
Hi Tim,

I'm certainly interested in more details. I haven't heard of that problem but I suspect although we have some regression tests for generics we don't have a lot exercising multiple bounds. I'll have a look in the code but as you say, a sample that exhibits the problem will enable me to fix it much quicker (or sort out a temporary workaround - maybe something silly like reordering the bounds in the source code).  Please raise a bug and share any more info there or with me on email.

cheers,
Andy

On 26 January 2016 at 03:26, Tim Webster <[hidden email]> wrote:
Hi,

I'm seeing a problem where a class with multiple bounds is 'losing' one of its bounds after weaving occurs.

Even more strange is that it is only happening on a specific platform.

a brief outline of the problem:

Source class:

public class ExistenceByIdSpecification<D extends AbstractDomainObject & Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification

What happens is the 'AbstractDomainObject' bound (which is a class) is disappearing, and in the bytecode we end up with something like this:

public class ExistenceByIdSpecification<D extends Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification, org.springframework.beans.factory.aspectj.ConfigurableObject


this results is a runtime error whenever the constructor is called (I've removed package names - this is from a unit test):


ExistenceByIdSpecification.&lt;init&gt;(L/Identifiable;)V" type="java.lang.NoSuchMethodError"><![CDATA[java.lang.NoSuchMethodError: ExistenceByIdSpecification.<init>(L/Identifiable;)V
        at ExistenceByIdSpecificationTest.<init>(ExistenceByIdSpecificationTest.java:33)



Also, the bytecode for the class is quite a bit larger on the environment where this isn't working properly - it looks like stuff related to @Configurable is repeated.

I'm suspecting AspectJ here because when I compile the code with AspectJ disabled, the bytecode looks correct.

The environments details I've tried are:

works properly:
Windows 7
Manjaro Linux (current version)
Oracle JDK 1.7.0_79
AspectJ 1.8.6

Doesn't work:
CentOS 7
Oracle JDK 1.7.0_79, Oracle JDK 1.8.0_65, OpenJDK 1.7.0
AspectJ 1.8.6, 1.8.8

Unfortunately we want to target CentOS as a build platform, so that's why this is a problem for us!

I've only included basic details here to see if anyone has heard of this problem.  I'm happy to provide more detail if required.  I know that a sample project is ideal, but I may struggle to reproduce that (although I will try).

Thanks,


_______________________________________________
aspectj-users mailing list
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users

<bytecode.zip>_______________________________________________
aspectj-users mailing list
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users
Reply | Threaded
Open this post in threaded view
|

Re: Bounded type disappearing after weaving

Tim Webster
In reply to this post by Andy Clement
Hi Andy - any idea when 1.8.9 will be released?  This issue has cropped up again for us (on Windows this time), so I'm keen to know when the next version will be available (roughly)..

Thanks,

Tim


On Wed, Jan 27, 2016 at 7:43 PM, Andy Clement <[hidden email]> wrote:
I see a couple of things of interest:

- the type is marked ConfigurableObject
- there are numerous isAnnotationPresent checks guarding advice calls (checking if the type of ‘this’ in the method has the Configurable annotation).

Do you expect this type to be a ConfigurableObject? Are types further up this objects hierarchy marked with ConfigurableObject?
I ask because weaving may differ if the types are processed in a different order on each OS (which can happen because an ordering is not enforced/required).  If a type further up the hierarchy is woven first and matches the declare parents statement (from the spring aspect it is "declare parents: @Configurable * implements ConfigurableObject;”)  then it would get the ConfigurableObject interface and then when we hit your ExistenceByIdSpecification we would not add the interface again (because we were inheriting it).  But if hitting ExistenceByIdSpecification first we might add it here and then add it again when we hit the parent that also matches.

When this happens it is harmless, and not necessarily anything to worry about, it is just a different weave that basically does the same thing (although different weaves may offer a slight variance in performance). You could turn on the weaving output and see the order in which types are processed on different operating systems and see if there is a difference in ordering.

The isAnnotationPresent checks might be considered sub-optimal if the ‘alternate’ weaving ordering has determined they aren’t needed in this code - I’d need to recreate all this myself to debug further. When a pointcut element (like @this(Foo)) cannot be fully determined statically to be always true, it will insert a runtime check into the code that verifies it at runtime. It is possible these are also because on centos we aren’t weaving a super type of this type earlier than this type.

Thanks for testing the losing bounds fix, I’ll commit that now.

cheers,
Andy


On Jan 27, 2016, at 2:23 AM, Tim Webster <[hidden email]> wrote:

Hi Andy,

OK that fix looks like it worked.  I'm doing some more testing but so far so good.

...but I'm wondering if there is another issue.  I mentioned this briefly in the original email - the bytecode on the CentOS build looks quite different...it's larger with what looks like more references to the aspects.  This might be a different issue so I'm happy to start a new thread / open a new issue.

I've include 3 files (attached).  If you look at the Windows and Manjaro Linux ones they are identical.  The CentOS one is the different one.  There doesn't seem to be any problem with the code execution, but it doesn't look right, and I don't have the expertise to really determine if it's a problem or not. Can you have a look?

Anyway - big thanks for fixing this so quickly...:-)



On Wed, Jan 27, 2016 at 5:59 AM, Andy Clement <[hidden email]> wrote:
I've put in some changes to fix the version of the problem I uncovered. If you want to try it out there is a new dev build available on the download page ( https://www.eclipse.org/aspectj/downloads.php ) or a new AspectJ maven snapshot in repo.spring.io (version 1.8.9.BUILD-SNAPSHOT)
<repository>
    <id>repo.spring.io</id>
    <name>SpringSource snapshots</name>
    <url>http://repo.spring.io/snapshot</url>
</repository>
If you get a chance to try them out, let me know if it makes any difference.

cheers,
Andy


On 26 January 2016 at 16:49, Andy Clement <[hidden email]> wrote:
I’ve recreated it and am currently sorting it out. For me this code exhibits the problem:

— Code.java —
class B<T extends SomeClass & SomeInterface> {}
class SomeClass {}
interface SomeInterface {}

aspect X {
  declare parents: B implements java.io.Serializable;
}
—Code.java—

ajc -1.8 Code.java
javap B
class B<T extends SomeInterface> implements java.o.Serializable {

See how the type variable has lost the class bound. It only happens if you have interface bounds in addition to a class bound. Maybe your problem isn’t caused by doing declare parents but clearly there is a code path in AspectJ that produces the wrong signature attribute - and maybe whatever you do causes us to go down that path too.


cheers,
Andy


On Jan 26, 2016, at 11:56 AM, Andy Clement <[hidden email]> wrote:

Typically this would end up being that the JVM on the target OS just happens to put things in a different place on the heap which might then cause things to be iterated over in a different order. For example if we slot a bunch of objects into a ‘Set’ without caring about an order an then ask for all the entries. It will typically be a bug in the code that is accidentally relying on an ordering when it shouldn’t - and we’ve been getting away with it because we’ve never seen this other order before or in any testing. I presume you are not doing anything that might affect the type definition, like an inter type declaration or declare parents? (Although you might be advising code within the affected type).

I would first try it on my linux (ubuntu i think I have)  but if that doesn’t show an issue I’d probably try running a centos virtual machine or some such. If all else fails I’d need to construct you some debug builds to perhaps collect extra diagnostics.  Hmm, do you compile that original source on centos or just weave it there?  I’m vaguely wondering if the java compiler used to build the original source produces a subtley different class file on centos vs windows.

cheers,
Andy

On Jan 26, 2016, at 9:09 AM, Tim Webster <[hidden email]> wrote:

Hi Andy,

I'm trying to come up with a sample project but so far no luck - it's behaving itself so far.  I'll keep trying though.

Like I said it only seems to happen in CentOS at the moment.  I'd be surprised if it had anything to do with the OS itself, but my point is that even if I did come up with a sample do you think you could reproduce the conditions?  Is there anything else I can give you in the meantime (bytecode, source code, etc)>

Thanks,

Tim


On Tue, Jan 26, 2016 at 4:29 PM, Andy Clement <[hidden email]> wrote:
Hi Tim,

I'm certainly interested in more details. I haven't heard of that problem but I suspect although we have some regression tests for generics we don't have a lot exercising multiple bounds. I'll have a look in the code but as you say, a sample that exhibits the problem will enable me to fix it much quicker (or sort out a temporary workaround - maybe something silly like reordering the bounds in the source code).  Please raise a bug and share any more info there or with me on email.

cheers,
Andy

On 26 January 2016 at 03:26, Tim Webster <[hidden email]> wrote:
Hi,

I'm seeing a problem where a class with multiple bounds is 'losing' one of its bounds after weaving occurs.

Even more strange is that it is only happening on a specific platform.

a brief outline of the problem:

Source class:

public class ExistenceByIdSpecification<D extends AbstractDomainObject & Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification

What happens is the 'AbstractDomainObject' bound (which is a class) is disappearing, and in the bytecode we end up with something like this:

public class ExistenceByIdSpecification<D extends Identifiable> extends ExistenceSpecification<D> implements IExistenceByIdSpecification, org.springframework.beans.factory.aspectj.ConfigurableObject


this results is a runtime error whenever the constructor is called (I've removed package names - this is from a unit test):


ExistenceByIdSpecification.&lt;init&gt;(L/Identifiable;)V" type="java.lang.NoSuchMethodError"><![CDATA[java.lang.NoSuchMethodError: ExistenceByIdSpecification.<init>(L/Identifiable;)V
        at ExistenceByIdSpecificationTest.<init>(ExistenceByIdSpecificationTest.java:33)



Also, the bytecode for the class is quite a bit larger on the environment where this isn't working properly - it looks like stuff related to @Configurable is repeated.

I'm suspecting AspectJ here because when I compile the code with AspectJ disabled, the bytecode looks correct.

The environments details I've tried are:

works properly:
Windows 7
Manjaro Linux (current version)
Oracle JDK 1.7.0_79
AspectJ 1.8.6

Doesn't work:
CentOS 7
Oracle JDK 1.7.0_79, Oracle JDK 1.8.0_65, OpenJDK 1.7.0
AspectJ 1.8.6, 1.8.8

Unfortunately we want to target CentOS as a build platform, so that's why this is a problem for us!

I've only included basic details here to see if anyone has heard of this problem.  I'm happy to provide more detail if required.  I know that a sample project is ideal, but I may struggle to reproduce that (although I will try).

Thanks,


_______________________________________________
aspectj-users mailing list
[hidden email]
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
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users

<bytecode.zip>_______________________________________________
aspectj-users mailing list
[hidden email]
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
[hidden email]
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
[hidden email]
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users