Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] How to inject a static field into a multitude of types with AspectJ?

Hi,

>  1. the getLogger() is a Test class do not get advised by the around statement
>  2. getLogger() is not available from a static context.

The existence of a compile time error can stop the weaver from
operating.  I suspect your problem (2) is causing (1).  If you remove
the attempt to call getLogger() from a static context (so that the
code is correct), it should advise just fine.

Now, on (2), the ITD isn't static, so you can't call it from a static context:

 public Logger ILoggable.getLogger() {
     return null;
 }

But then... static ITDs are not allowed on interfaces (because you
can't have static methods in interfaces):

// compile error "methods in interfaces cannot be declared static"
public static Logger ILoggable.getLogger() {
     return null;
 }

But I have had some requests in from another source to support
something like this, so I've raised:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=369261

However, I need to work through some use cases and check things hang
together before proceeding.

cheers,
Andy

On 20 January 2012 02:06, Dénes Németh <mr.nemeth.denes@xxxxxxxxx> wrote:
> Hi Andy
>
> Can you provide your source code that works? I could not come up
> with a working one. I had two problems
>  1. the getLogger() is a Test class do not get advised by the around statement
>  2. getLogger() is not available from a static context.
>
> @ILog
> public class Test {
>        public void test(){
>                getLogger().info("huu");
>        }
>        public static void main(String[] args) {
>                IWantToLog i = new IWantToLog();
>                i.test();
>                getLogger().info("huh from static context");
>        }
> }
>
> public aspect LoggerAspect {
>        private static aspect LoggerHolderAspect pertypewithin(@ILog *) {
>                private Logger logger;
>                public void initLogger() {
>                        logger = LogManager.getLogManager().getLogger(getWithinTypeName()); }
>                public Logger getLogger() {
>                        return null;
>                }
>        }
>        private interface ILoggable {};
>        declare parents: (@ILog *) implements ILoggable;
>        public Logger ILoggable.getLogger() {
>                return null;
>        }
>        Logger around(): call(Logger getLogger(..)) && !within(LoggerAspect) {
>                 return getLoggerHolder(thisEnclosingJoinPointStaticPart).getLogger();
>        }
>        public static Logger getLogger(@SuppressWarnings("rawtypes") Class clazz){
>                return LoggerHolderAspect.aspectOf(clazz).getLogger();
>        }
>        private static Logger getLogger(JoinPoint.StaticPart jp) {
>                return getLoggerHolder(jp).getLogger();
>        }
>        private static LoggerHolderAspect getLoggerHolder(JoinPoint.StaticPart jp){
>                return LoggerHolderAspect.aspectOf(jp.getSignature().getDeclaringType());
>        }
>        before(): staticinitialization(@ILog *) {
>                getLoggerHolder(thisJoinPointStaticPart).initLogger();
>        }
> }
>
> public @interface ILog {
>
> }
>
>
> Thanks Denes
>
> 2012/1/16 Andy Clement <andrew.clement@xxxxxxxxx>:
>> I would agree, *but* private ITD methods onto interfaces currently
>> still mangle the method name that is introduced.  So you can ITD
>> getLogger() but that won't be what gets into the interface and type.
>>
>> This is due to what 'private' means.  If you consider it means
>> 'private to the aspect' then we don't want the type or interface
>> tripping over it, hence it gets a new name that is unlikely to clash
>> with anything in the existing types (and code you write in the class
>> is unlikely to see it, use it).
>>
>> Now this definition of privacy has been evolving over the last few
>> releases because it isn't seen as useful, it isn't how users think,
>> they think they are creating a private method in the target.  I have
>> addressed the basic case of private ITD method onto a CLASS (that will
>> now not mangle the name) but the more complex form of an ITD onto an
>> interface is still mangled.  (there is a bugzilla somewhere about
>> it...)
>>
>> cheers,
>> Andy
>>
>> On 15 January 2012 23:54, Mark <mark.kharitonov@xxxxxxxxx> wrote:
>>> Would not you agree that getLogger must be made private? Otherwise, someone
>>> could have invoked it from an arbitrary context, in which case
>>> thisEnclosingJoinPointStaticPart would be something unaffected by the
>>> aspect.
>>>
>>>
>>> --
>>> View this message in context: http://aspectj.2085585.n4.nabble.com/How-to-inject-a-static-field-into-a-multitude-of-types-with-AspectJ-tp4168355p4298714.html
>>> Sent from the AspectJ - users mailing list archive at Nabble.com.
>>> _______________________________________________
>>> aspectj-users mailing list
>>> aspectj-users@xxxxxxxxxxx
>>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>> _______________________________________________
>> aspectj-users mailing list
>> aspectj-users@xxxxxxxxxxx
>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users


Back to the top