Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Possible percflow compiler bug

(replying separately to the build question)

> Currently, I have been jarring up everything in the project
> in a single jar (using -XnoWeave) then recompiling any dependant
> projects with that jar in both the -aspectPath and -inJar options.

I have no idea if this approach will produce meaningful results.
Listing a jar in two options and using -XnoWeave both make me
nervous.

> In my common project, I have interfaces and classes that can
> be compiled with javac.  Also in the same project are aspects
> that introduce and give advice to the regular java code.

It also sounds like the aspects are making changes to the common
types that are to be visible to the dependent projects, right?
This is the tough part.

If the aspects make visible changes to the common classes but
do not affect other modules, then you should be able to
use all the common output on the module compile classpath:

   ajc -outjar common.jar -sourceroots "aspectj-src:src" ...
   cd ../otherProject
   javac -classpath "../common/common.jar:${aspectjrt.jar}" {src}

If the aspects are also to affect the other modules, then
it should work to keep them in binary form and reuse them:

   ajc -outjar common-aspects.jar
       -sourceroots "aspectj-src" ...

   ajc -outjar common.jar
       -sourceroots "src"
       -aspectpath common-aspects.jar ...

   cd ../otherProject
   ajc -outjar module1.jar
       -sourceroots "src"
       -classpath common.jar
       -aspectpath ../common-aspects.jar ...

It's safest to assume that all aspects can affect all
types in a namespace; using build boundaries to effect
crosscutting limits causes a dangerous dependency on
the build process and might cause problems.
(hand-waving here for the moment...)

Which suggests saving the aspects for a final weaving pass.
You can precompile projects that can compile without
seeing aspect-induced API's:

   javac/jar to create common-noaspects.jar
   javac/jar to create module1-noaspects.jar

and then do the aspects and the final weave...

   ajc -outjar aspects.jar {aspectSrc}
   ajc -injars "common-noaspects.jar:module1-noaspects.jar.."
       -aspectpath aspects.jar

Of course, this partitioning works well for ant builds of
modules developed by separate teams, but clashes horribly
with incremental compilation ala Eclipse.  Having tried to
do external builders to create jar files used as -injars,
I can only say it's not altogether clean.

For that, I prefer Ron's suggestion of creating a top-level
project with symbolic links out to the sources:

   app-assembly/
     {link common/aspects}
     {link common/src}
     {link module1/src}
     ...

Then everything is part of one huge incremental compile.  Also, you
can close this master project and work the others using the Java
compiler or AJDT.

The links make incremental development possible without affecting
the modularized Ant builds.  (Our practice runs along those lines.)

The model for aspects is that the aspects apply to everything
in a namespace, as if everything is done at once.  Sometimes
you can break it down into separate steps without breaking this
model, but we haven't stated exactly where it could break.

Regards,
Wes

Bozic, Chris wrote:

Wes,

I did check out and use the latest code from the AJ repos today and the cflow fixes in there didn't fix my particular problem.  However, I have a question about what you are suggesting.  I believe I may have tried something similar and I want to clarify just to make sure I understand you correctly.

In my common project, I have interfaces and classes that can be compiled with javac. Also in the same project are aspects that introduce and give advice to the regular java code. Are you suggesting that I compile all the java code in the project seperately from all the aspect code and jar them seperately as well?
Currently, I have been jarring up everything in the project in a single jar (using -XnoWeave) then recompiling any dependant projects with that jar in both the -aspectPath and -inJar options.  This has proved to work on all my testcases except the TransactionContext percflow.

Here's a code fragment that might help you out.

public abstract aspect TransactionContext percflow( topOfFlow() ){

	protected abstract pointcut entryPoint();
	protected pointcut topOfFlow(): entryPoint() && !cflowbelow(entryPoint() );

	after() returning : topOfFlow() {
		this.commitConnections( this.commitable );
} after() throwing : topOfFlow() {
		this.commitConnections( false );
} after() : topOfFlow() {
		this.returnConnections();
}
	protected void returnConnections(){ ... };
	protected void commitConnections(boolean commit){ ... };
}

There's also logic in there that sets this.commitable to false if any exceptions were thrown in a any DB interactions.  The above gets jarred up and I have a test case in a different project that extends TransactionContext and defines the abstract pointcut.  When I use the jar (the way I described earlier), I get the same aspect instance for each entryPoint().  The TransactionContext and percflow passes all my tests if I include the common project's source instead of using it in jar form.

I haven't tried separating the common project in to two different jar's yet.  If this is what you're suggesting, I'll give it a try.  Still, I think I expected to be able to jar up my compiled and woven classes, include the jar in another project's -aspectPath option, and have the other project be affected properly without the jar being checked for interface Exceptions (or anything since it is already woven and it's not listed in the -inJar option).  I'm not entirely sure why that is happening or even if it's happening exactly like I am interpreting it but I know you all have excellent reasons for doing things the way you are.

As for the interfaces, I have a Persistable interface like:

public interface Persistable{
	public void update() throws PersistanceException;
}

and I have a seperate aspect that introduces implementations on Persistable like:

public aspect PersistableImpl {
	public void Persistable.update() throws PersistanceException {...}
}

Using a decompiler, I can see how the AJcompiler handles the different options.  When I compile without the -XnoWeave option Persistable.class decompiles to something like:

public interface Persistable{
	public abstract void update();
}

And, when I compile with the -XnoWeave option Persistable.class decompiles to an empty interface leaving it free for any method introduction.

public interface Persistable{}

I hope that gives you some helpful information.

Chris Bozic

-----Original Message-----
From:	Wes Isberg [mailto:wes@xxxxxxxxxxxxxx]
Sent:	Tue 8/5/2003 9:04 PM
To:	aspectj-users@xxxxxxxxxxx
Cc:	
Subject:	Re: [aspectj-users] Possible percflow compiler bug
A test case would of course be great!

But I'm still hoping that the current fixes would work for you,
so perhaps you can wait until the release candidate before
writing tests or refactoring your code.  I'm also trying it.

btw, I'm still not exactly sure what you're doing, and why the interfaces aren't behaving as expected. Note that the methods declared on the interfaces in the aspect must explicitly be declared public for them to be visible to types. What I recommend:

- compile library as usual: ajc -outjar library.jar ...
- compile others as usual: javac ...; jar cf others.jar ...
- weave:  ajc -outjar system.jar
               -injars others.jar
               -aspectpath library.jar
               -classpath aspectjrt.jar
- run: java -classpath "aspectjrt.jar;system.jar;library.jar" ...

Wes

Bozic, Chris wrote:


Wes,
Thanks for responding so quickly.  I've tried the options you gave but without success.  I think as things are now, the stateless aspect solution you suggested might be the best thing for me to look into now.  However, since we're talking about a potential bug, I'll try to be more helpful by giving a little more detail.

I have a project of common components that I would like to jar up and include in other projects.  This common project contains mostly interfaces with aspect introduced implementations (for mixins) along with a few other handy tools like the TransactionContext I mentioned earlier.  The interfaces declare methods that throw exceptions.  If I compile without the -XnoWeave option, the project compiles and the jar builds fine.  But, when I use that jar in another project in the -aspectPath option, I get compiler errors saying the interface methods throwing exceptions in the original source are no longer throwing them in the jar.
     [ajc]C:\apps\eclipse30M2\workspace\commonSAIC\src\java\com\saic\uri\persistance\UriPersistableAspect.java
:55 overriden method doesn't throw com.saic.persistance.PersistanceException

If I compile and create the jar with the -XnoWeave option, I can use it in dependant projects by compiling them with that jar in the -aspectPath and -inJar options.  Everything passes tests except for the TransactionContext where it tries to get a new instance of the aspect percflow.

To summarize, I basically have two mutually exclusive problems. One is that my introduction seems to be stepping on itself in jar form and the other is the percflow giving me only one instance of an aspect.  Unless I'm missing something, I can't jar up my code already woven becuase the exceptions on the interface methods vanish and the compiler seems to want to re-weave the jar even when it's not used in the -inJar option.  If there's a way I can do that, then my problem might be solved.  Otherwise, I might need to submit a bug report for the single instance of a percflow aspect.  Maybe it's not really an official bug at all because it happens when I use experimental compiler options.

Please let me know if some code examples are needed or if you would like me to write test cases for anything.

Chris Bozic

-----Original Message-----
From:	Wes Isberg [mailto:wes@xxxxxxxxxxxxxx]
Sent:	Tue 8/5/2003 1:54 PM
To:	aspectj-users@xxxxxxxxxxx
Cc:	
Subject:	Re: [aspectj-users] Possible percflow compiler bug
-XnoWeave is an experimental (read: unsupported) option.
To use binary aspects, compile them without the -Xnoweave option
and then weave them with your classes using -aspectpath.

Let us know if that works.  If it doesn't, there was a cflow(..)
bug that has been fixed in the tree.  We're soon to post a link
on aspectj-dev@xxxxxxxxxxx to the 1.1.1 release candidate which
will include that fix.  Try the release candidate.  If that
doesn't work, then we'd want to write up a bug and work up a
reproducible test case so we can investigate if possible
before the release of 1.1.1.  Finally, as a workaround
you can be thread-safe if your aspect is stateless (or
has no state changes).  Sometimes you can use around
advice and local variables to manage any required
thread-specific state, or declare fields on targets
that themselves are thread-safe, to avoid having a
stateful aspect.

Thanks for bringing this up.
Wes

https://bugs.eclipse.org/bugs/show_bug.cgi?id=40876

Bozic, Chris wrote:


All,

My team has a TransactionContext that either commits or rolls back a set of DB interactions based on whether an exception has occured during one of the interactions.  In order to be thread safe, we have declared this aspect to be a percflow aspect ( "percflow( topOfFlow() )" ).  Everything works fine if we compile the original TransactionContext source with our test cases.  However when we jar our source (compiled with the -noweave option) and then bytecode weave it in to our testcase source files, we get the same instance of TransactionContext for every topOfFlow().

We were wondering if anyone could suggest a way to fix this or if we have found a bug that we should submit.

Thanks,
Chris Bozic
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/aspectj-users



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





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






Back to the top