Thanks for the help Andy.  I ended up going back to the project that
generates the incoming jar and applying the new interfaces with aspects
there so when they get to the dependent project, no weaving is necessary as
everything needed is already built into the incoming jar.

On Thu, Oct 26, 2017 at 11:07 AM, Andy Clement <[email protected]>
wrote:

> Hey,
>
> So sorry! I noticed I wrote this the other day but have left it in draft,
> finally sending now...
>
> What you are doing looks OK but as you surmise your new code will only
> work if the aspect has had a chance to apply.  Let’s step through it. I’ll
> use real code:
>
> === 8< ==== A.java ======
> public interface A {}
>
> === 8< ==== Impl.java ======
> public class Impl implements A {}
>
> Let’s build those:
>
> ajc -1.9 A.java Impl.java -outjar original.jar
>
>
>
> === 8< ==== A.java ======
> public interface B {}
>
> Let’s build our new interface:
> ajc -1.9 B.java -outjar b.jar
>
>
> === 8< ==== Azpect.java ======
> aspect Azpect {
>         declare parents: A+ implements B;
> }
>
> === 8< ==== Test.java ======
> public class Test {
>   public static void main(String []argv) {
>      A impl = new Impl();
>      B b = impl;
>   }
> }
>
>
> So the Test program will only compile if the aspect can make the change it
> needs to:
>
> ajc -1.9 -classpath ../aspectjrt.jar:original.jar:b.jar Test.java
> Azpect.java
> Azpect.java:2 [warning] this affected type is not exposed to the weaver: A
> [Xlint:typeNotExposedToWeaver]
> declare parents: A+ implements B;
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>         [Xlint:typeNotExposedToWeaver]
> Test.java:4 [error] Type mismatch: cannot convert from A to B
> B b = impl;
>
> Notice here, it can’t. Because A.java is on the class path, it does not
> get woven (we need to write out a new version of A that extends B).
>
> (Yes, in this case "A+ implements B" is being implemented as changing A to
> make it extend B rather than changing all implementors of A to also
> implement B).
>
> There are a few options for tackling this. Perhaps the cleanest/simplest
> is to modify the jar with our changes before using it:
>
> ajc -1.9 -inpath original.jar -outjar new.jar Azpect.java B.java
> -showWeaveInfo
> Extending interface set for type 'A' (A.java) to include 'B' (Azpect.java)
>
> Now we can use it:
>
> ajc -1.9 -classpath ../aspectjrt.jar:new.jar Test.java
>
> java -classpath new.jar:. Test
>
> Works OK
>
> We could get it to compile all in one go by combining those steps:
>
> ajc -1.9 -inpath original.jar Azpect.java B.java Test.java -showWeaveInfo
> Extending interface set for type 'A' (A.java) to include 'B' (Azpect.java)
>
> java -classpath . Test
>
> This works because we are making A/Impl available to the weaver as
> candidates for change by passing them on the inpath. But you are left with
> a mess of everything in the target folder.  You could use -outjar here but
> your test will then all be in your output jar.
>
> I hope that helps explain what is happening.
>
> Andy
>
> > On Oct 21, 2017, at 12:18 PM, Jason Britton <[email protected]>
> wrote:
> >
> > Hi -
> > I've got a bunch of generated classes across multiple jars that I cannot
> change the source on, nor can I change how they are generated.  These
> generated classes all implement interface "A"
> >
> > I'd like to add another interface to all these generated classes to make
> use of a handful of other methods they all already implement.  Essentially
> I'd like to simply add in another "implements B" to their definitions at
> compile time.  I've defined "B" interface and my aspect looks like this:
> >
> >       public aspect ImplementBInterfaceAspect {
> >
> >       declare parents : A+ implements B;
> >
> >       }
> >
> > Does that look correct?  I wrote some code that I thought would
> correctly prove the new "implements B" was being weaved in correctly.  That
> code looks like:
> >
> >       // C implements A by source code definition, and should have be
> known to "implements B" due to weaving of the aspect defined above
> >       C cInstance = new C();
> >
> >       // B is an interface, cInstance should be known to implements B if
> weaving is taking place
> >       B refToCInstance = cInstance;
> >
> > The code above doesn't compile.  Complaining that cInstance cannot be
> assigned to refToCInstance.  I'm now realizing that weaving must not happen
> until after all existing code is already compiled??  Sorry for my
> beginner's understanding of AspectJ.  What would be a better test to
> validate that my desired weaving is happening?
> >
> > Thank you any clarity you can provide.
> >
> > Jason
> > _______________________________________________
> > aspectj-users mailing list
> > [email protected]
> > 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
> [email protected]
> 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
[email protected]
To change your delivery options, retrieve your password, or unsubscribe from 
this list, visit
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Reply via email to