Announcement Announcement Module
Collapse
No announcement yet.
Differences in .class-files when using compile time weaving Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Differences in .class-files when using compile time weaving

    Hi,

    We use Spring AOP in a webapp to inject dependencies into tags. This works great, but we're having some problems with the generated class files.

    From one build to another, classes with @Configurable end up with differing bytecode. We're building with maven, and this happens from one "clean package" to the next, without any other changes. This is a practical problem since we use rsync to deploy and it detects differences in files which really shouldn't have changed.

    By doing a load of test builds, I've found that we end up with at least three different permutations of a class annotated with @Configurable.

    I've tried decompiling the resulting class files with JD (http://java.decompiler.free.fr/) and there are real differences between the files (not just differing serial version UID or other non-code differences).

    For the three variants of a @Configurable tag, these are the decompiled differences:

    Constructor in class 1 contains this if:

    if ((super.getClass().isAnnotationPresent(Configurabl e.class))&&(((!(super.getClass().isAnnotationPrese nt(Configurable.class)))||(!(AnnotationBeanConfigu rerAspect.ajc$if_1((Configurable)super.getClass(). getAnnotation(Configurable.class))))))&&(AbstractD ependencyInjectionAspect.ajc$if_0(localJoinPoint1) ))

    Constructor in class 2 contains this if (different order of statements, which with short circuit operators result in different bytecode):

    if ((((!(super.getClass().isAnnotationPresent(Configu rable.class))) || (!(AnnotationBeanConfigurerAspect.ajc$if_1((Config urable)super.getClass().getAnnotation(Configurable .class)))))) && (super.getClass().isAnnotationPresent(Configurable .class)) && (AbstractDependencyInjectionAspect.ajc$if_0(localJ oinPoint1)))

    Class 3 is equal with Class 2, except for the order of interfaces in the class declaration:

    implements AbstractInterfaceDrivenDependencyInjectionAspect.C onfigurableDeserializationSupport, ConfigurableObject

    vs.

    implements ConfigurableObject, AbstractInterfaceDrivenDependencyInjectionAspect.C onfigurableDeserializationSupport

    This is with Spring AOP 2.5.5.

    Anybody have any idea what might be causing this?

  • #2
    Please use [ code][/code ] tags when posting code.

    It has nothing to do with Spring AOP, the real culprit here is the AspectJ compiler as this is the thing that modifies the bytecode. You could try with a different version of AspectJ to see if it behaves more consistent.

    Comment


    • #3
      I don't know what's going on here, but this sounds to me like a bug. Class files should be consistent across compiles. I'd recommend raising a jira issue for it:

      http://jira.springframework.org/browse/SPR

      Comment


      • #4
        Reading seems to be an art.

        As I stated it isn't a spring issue (I guess that without the AspectJ compiler the class file is consistent) however due to the class modifications done by aspectj the byte code changes. Hence it is a AspectJ issue rather then a spring issue... Which is also why I suggested trying a different version of AspectJ.

        Comment


        • #5
          There is no defined ordering for those runtime tests that end up put into the bytecode by AspectJ.

          On each run the various objects representing the runtime tests will likely be allocated at different places on the heap, given different hashCodes/etc (since they don't override these methods themselves). This means if they are all added into some unordered collection during processing and then simply retrieved through an iterator at the end, they may well come out in a different order every time you compile the code.

          I would agree this is probably not ideal (especially in your rsync case) - and you should raise an AspectJ enhancement request to at least define a reliable ordering. Probably just overriding hashCode/equals in the types involved is likely to make it more reliable. Enhancements can be raised here: https://bugs.eclipse.org/bugs/enter_...roduct=AspectJ

          thanks,
          Andy Clement
          AspectJ Project Lead

          Comment

          Working...
          X