Community
Participate
Working Groups
You can currently provide your own implementation of IMessageHolder and use it via iajc (using messageHolderClass="myMessageHolderClass" and showWeaveInfo="true"), however, you can't do a similar thing when using ajc.
try and look at this for 1.5.0 ...
Extended Ajde to allow specification of a custom IMessageHandler (which would also allow passing an IMessageHolder since that is a sub-interface). AJDT would call Ajde.init(....) as normal. Then optionally can call Ajde.getDefault().setMessageHandler(IMessageHandler aHandler). If this call is made all messages will be routed to the user-supplied handler bypassing the default handler (which pushes messages out to the TaskListManager). A subsequent call to setMessageHandler(null) will remove any custom handler and restore default processing.
Reopening this bug to cover the remaining issues..... There is currently the "-XmessageHandlerClass" option which is used for LTW and requires a class which implements IMessageHandler. On the other hand, with iajc there is the messageHolderClass option which requires a class which implements IMessageHolder. IMessageHolder extends IMessageHandler. The remaining issues are based around how best to surface this in ajdt and the corresponding implementation that is required for this. Do we use the ltw -X option and loose the consistency between what users can do with ant and the compiler in AJDT, or do we provide another option which keeps the consistency with ant but is different to the ltw option? Also, should it be a -X option?
Hmmm. I think I need to clear up what exactly we want here - from Helens last note on the bug, I might have been getting a couple of cases mixed up.... I thought Helen wanted the extension to 'ajc' so that she could collect messages and sift through them for the purposes of analysing coverage. If so, we should properly support -XmessageHandlerClass that LTW uses. As with all -X options, if it proves useful we'll migrate it to be a standard option. Any old user can exploit this with: ajc -XmessageHandlerClass:Someclass A.java X.aj If, however, we just want to enable users of *AJDT* to specify their own message handler class then what Adrian has done should be sufficient and AJDT just needs the ability for a user to set and remember a class name which can then be set via the usual interface with AJDE. The difference between a holder and a handler is that a holder is expected to maintain the set of messages for querying sometime later - a handler is free to process each one and then move on. We wouldnt want the LTW to have a holder (think of the memory use over time...) - we might do for the ANT support as some operation after the compiler has run could process the output - probably don't want a holder for inside AJDT either..I think.
I looked at what it takes to add this option. There is already a bunch of infrastructure for intercepting messages and it seems a shame to make it even more complicated for this option. Given that ajc is supposedly comparable with javac, I don't see a similar option in javac. And it does seem a little odd to me that I could write a class to pass to the command line compiler. Anyway, the easiest way to run the compiler and intercept the messages is like this - and maybe the problem all along is that the ease with which this can be done has not been documented and thats what we should do. In order to continue after the compiler finishes, may need to pass -noExit. import java.util.List; import org.aspectj.bridge.AbortException; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.IMessageHolder; import org.aspectj.bridge.IMessage.Kind; import org.aspectj.tools.ajc.Main; public class RunCompiler { public static void main(String[] args) { Main compiler = new Main(); compiler.run(args,new MyLocalHolder()); } } class MyLocalHolder implements IMessageHolder { public boolean hasAnyMessage(Kind kind, boolean orGreater) {return false;} public int numMessages(Kind kind, boolean orGreater) {return 0;} public IMessage[] getMessages(Kind kind, boolean orGreater) {return null;} public List getUnmodifiableListView() { return null;} public void clearMessages() throws UnsupportedOperationException {} public boolean isIgnoring(Kind kind) { return false;} public void dontIgnore(Kind kind) {} public boolean handleMessage(IMessage message) throws AbortException { System.err.println("Intercepted: "+message); return false; } } java RunCompiler A.java B.aj -noExit -showWeaveInfo The handleMessage() gets full control to do whatever it wants. I think this would give Helen ample ability to process the IMessage objects to confirm code coverage.
Hi Wes - just wondered if I could get a 2nd opinion. What do you think about us doc'ing my final comment here? For users who want to process compiler output.
Sounds good -- I can add to end of devguideDB/ajc.xml. I'd use (poorly-named) MessageHandler rather than MyLocalHolder. The compiler plumbing might downcast from IMessageHandler to IMessageHolder (for incremental mode to check whether to bail?), so without further review I'd agree ..Holder is the safe way.
thanks Wes - I also thought you'd know where it would live in the docs. If you could put it in for me, that would be great! Another bug down...
This was already documented in the devguide ajc section: "To access compiler messages programmatically, use the methods setHolder(IMessageHolder holder) and/or run(String[] args, IMessageHolder holder)." I added to ajc.xml:1.14 ---------- ajc reports each message to the holder using IMessageHolder.handleMessage(..). If you just want to collect the messages, use MessageHandler as your IMessageHolder. For example, compile and run the following with aspectjtools.jar on the classpath: import org.aspectj.bridge.*; import org.aspectj.tools.ajc.Main; import java.util.Arrays; public class WrapAjc { public static void main(String[] args) { Main compiler = new Main(); MessageHandler m = new MessageHandler(); compiler.run(args, m); IMessage[] ms = m.getMessages(null, true); System.out.println("messages: " + Arrays.asList(ms)); } ---------- Ok to close?
thanks Wes!