Visibility of inter-type members with @DeclareMixin and @DeclareParents

View: New views
8 Messages — Rating Filter:   Alert me  

Visibility of inter-type members with @DeclareMixin and @DeclareParents

by João Gonçalves-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Greetings,

In "traditional" AspectJ syntax, to make a field private relative to the aspect (so that only code within the aspect can refer to it), it sufficed to declare an inter-type field as private.

With @DeclareMixin/@DeclareParents I use an interface with a setter and a getter to emulate an inter-type field. How do I make this “emulated field” private?

Using the private keyword in the factory method (for @DeclareMixin) / field (for @DeclareParents)?
That is:
    @DeclareMixin("ClassName")
    private static IFood create FoodImplementation() {
        return new FoodImpl();
    }

and
    @DeclareParents(value="ClassName",defaultImpl=FoodImpl.class)
    private IFood food;


Thanks. Also, in the above examples, the visibility will be private, even if the interface/implementation class is public, right?

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

Re: Visibility of inter-type members with @DeclareMixin and @DeclareParents

by Andrew Eisenberg :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

If the interface used as the introduced parent is only accessible
inside the aspect (ie- it is private), then its methods should only be
accessible from within the aspect.  So, your strategy below should
work (however, I have not tried this out myself).

2009/8/31 João Gonçalves <jocolimonada@...>:

> Using the private keyword in the factory method (for @DeclareMixin) / field
> (for @DeclareParents)?
> That is:
>     @DeclareMixin("ClassName")
>     private static IFood create FoodImplementation() {
>         return new FoodImpl();
>     }
>
> and
>     @DeclareParents(value="ClassName",defaultImpl=FoodImpl.class)
>     private IFood food;
>
>
> Thanks. Also, in the above examples, the visibility will be private, even if
> the interface/implementation class is public, right?
_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Parent Message unknown Re: Visibility of inter-type members with @DeclareMixin and @DeclareParents

by João Gonçalves-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Unfortunately, I've noticed that the constructor in the implementation class must always be at least as visible as the aspect type. If the aspect is public, this class will also have to be. The interface can be private, though.

On Mon, Aug 31, 2009 at 7:21 PM, Andrew Eisenberg <andrew@...> wrote:
If the interface used as the introduced parent is only accessible
inside the aspect (ie- it is private), then its methods should only be
accessible from within the aspect.  So, your strategy below should
work (however, I have not tried this out myself).

2009/8/31 João Gonçalves <jocolimonada@...>:
> Using the private keyword in the factory method (for @DeclareMixin) / field
> (for @DeclareParents)?
> That is:
>     @DeclareMixin("ClassName")
>     private static IFood create FoodImplementation() {
>         return new FoodImpl();
>     }
>
> and
>     @DeclareParents(value="ClassName",defaultImpl=FoodImpl.class)
>     private IFood food;
>
>
> Thanks. Also, in the above examples, the visibility will be private, even if
> the interface/implementation class is public, right?
_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users


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

Re: Visibility of inter-type members with @DeclareMixin and @DeclareParents

by matthewadams12 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I've noticed that introduced fields appear to be more public than I'd like.

Consider the following code, all in package "intro.test":

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface HasBar {}
=================
@HasBar
public class Foo {}
=================
public aspect HasBarIntro {

        private interface HasBar {}
       
        declare parents: (@intro.test.HasBar *) implements HasBar;
       
        private String HasBar.bar;
       
        public String HasBar.getBar() {
                return bar;
        }

        public void HasBar.setBar(String bar) {
                this.bar = bar;
        }
}
=================

After compiling, the introduced String "bar" appears as a public field on Foo.  When I run "javap -private intro.test.Foo", I get the following:

Compiled from "Foo.java"
public class intro.test.Foo extends java.lang.Object implements intro.test.HasBarIntro$HasBar{
    public java.lang.String ajc$interField$intro_test_HasBarIntro$intro_test_HasBarIntro$HasBar$bar;
    public intro.test.Foo();
    public java.lang.String ajc$interFieldGet$intro_test_HasBarIntro$intro_test_HasBarIntro$HasBar$bar();
    public void ajc$interFieldSet$intro_test_HasBarIntro$intro_test_HasBarIntro$HasBar$bar(java.lang.String);
    public java.lang.String getBar();
    public void setBar(java.lang.String);
}

Notice the first field, a public String field introduced by HasBarIntro.  Why is the field public?  Is there a way for all of the members prefaced with "ajc$" to be non-public?

I tried to ask this question once already:
http://www.nabble.com/ITD-public-fields-break-encapsulation--ts25154702.html

Thanks,
Matthew

Andrew Eisenberg wrote:
If the interface used as the introduced parent is only accessible
inside the aspect (ie- it is private), then its methods should only be
accessible from within the aspect.  So, your strategy below should
work (however, I have not tried this out myself).

2009/8/31 João Gonçalves <jocolimonada@gmail.com>:
> Using the private keyword in the factory method (for @DeclareMixin) / field
> (for @DeclareParents)?
> That is:
>     @DeclareMixin("ClassName")
>     private static IFood create FoodImplementation() {
>         return new FoodImpl();
>     }
>
> and
>     @DeclareParents(value="ClassName",defaultImpl=FoodImpl.class)
>     private IFood food;
>
>
> Thanks. Also, in the above examples, the visibility will be private, even if
> the interface/implementation class is public, right?
_______________________________________________
aspectj-users mailing list
aspectj-users@eclipse.org
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Re: Visibility of inter-type members with @DeclareMixin and @DeclareParents

by Andrew Eisenberg :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Matthew,

I don't think that's currently possible, so you should probably raise
an enhancement request for that.

However, I would like to know why this is so important to you.

These methods are synthetic and someone who wants to call them must
either look at the byte code or have knowledge about AspectJ.  In the
IDE, they are filtered from content assist.  And even if these methods
were made private, they could still be accessible via reflection.

I'm not entirely sure how security policies work, but I know they can
be used to restrict reflective access to fields.  Can they also be
used to restrict other kinds of access?

On Mon, Aug 31, 2009 at 1:13 PM, matthewadams12<matthew@...> wrote:

>
> I've noticed that introduced fields appear to be more public than I'd like.
>
> Consider the following code, all in package "intro.test":
>
> @Target(ElementType.TYPE)
> @Retention(RetentionPolicy.RUNTIME)
> public @interface HasBar {}
> =================
> @HasBar
> public class Foo {}
> =================
> public aspect HasBarIntro {
>
>        private interface HasBar {}
>
>        declare parents: (@intro.test.HasBar *) implements HasBar;
>
>        private String HasBar.bar;
>
>        public String HasBar.getBar() {
>                return bar;
>        }
>
>        public void HasBar.setBar(String bar) {
>                this.bar = bar;
>        }
> }
> =================
>
> After compiling, the introduced String "bar" appears as a public field on
> Foo.  When I run "javap -private intro.test.Foo", I get the following:
>
> Compiled from "Foo.java"
> public class intro.test.Foo extends java.lang.Object implements
> intro.test.HasBarIntro$HasBar{
>    public java.lang.String
> ajc$interField$intro_test_HasBarIntro$intro_test_HasBarIntro$HasBar$bar;
>    public intro.test.Foo();
>    public java.lang.String
> ajc$interFieldGet$intro_test_HasBarIntro$intro_test_HasBarIntro$HasBar$bar();
>    public void
> ajc$interFieldSet$intro_test_HasBarIntro$intro_test_HasBarIntro$HasBar$bar(java.lang.String);
>    public java.lang.String getBar();
>    public void setBar(java.lang.String);
> }
>
> Notice the first field, a public String field introduced by HasBarIntro.
> Why is the field public?  Is there a way for all of the members prefaced
> with "ajc$" to be non-public?
>
> I tried to ask this question once already:
> http://www.nabble.com/ITD-public-fields-break-encapsulation--ts25154702.html
>
> Thanks,
> Matthew
>
>
> Andrew Eisenberg wrote:
>>
>> If the interface used as the introduced parent is only accessible
>> inside the aspect (ie- it is private), then its methods should only be
>> accessible from within the aspect.  So, your strategy below should
>> work (however, I have not tried this out myself).
>>
>> 2009/8/31 João Gonçalves <jocolimonada@...>:
>>> Using the private keyword in the factory method (for @DeclareMixin) /
>>> field
>>> (for @DeclareParents)?
>>> That is:
>>>     @DeclareMixin("ClassName")
>>>     private static IFood create FoodImplementation() {
>>>         return new FoodImpl();
>>>     }
>>>
>>> and
>>>     @DeclareParents(value="ClassName",defaultImpl=FoodImpl.class)
>>>     private IFood food;
>>>
>>>
>>> Thanks. Also, in the above examples, the visibility will be private, even
>>> if
>>> the interface/implementation class is public, right?
>> _______________________________________________
>> aspectj-users mailing list
>> aspectj-users@...
>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>
>>
>
> --
> View this message in context: http://www.nabble.com/Visibility-of-inter-type-members-with-%40DeclareMixin-and-%40DeclareParents-tp25226224p25229677.html
> Sent from the AspectJ - users mailing list archive at Nabble.com.
>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@...
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>
_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Re: Visibility of inter-type members with @DeclareMixin and @DeclareParents

by matthewadams12 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Andrew,

If you publish a jar whose classes have introduced methods and then
you use that jar in another project, the synthetic methods are visible
via content assist in the consuming project.  I don't mind if someone
wants to go to the trouble of using reflection to access non-publics,
but I do care that the consumer of the introduced classes can see the
fact that they have been woven with new public fields and methods.
IMHO, the public interface of the woven classes should not change,
unless the change(s) is(are) to implement a new public interface, in
which case you should only see the class declaration's additional
"implements" clause and the additional public methods of that
interface.  The public consumer of a class in normal usage
(non-reflection) should not have any clue that AspectJ was used to
weave the class.

With regard to synthetic method filtering, the introduced methods
would only be filtered during content assistance in an editor that
knew about AspectJ, which is only eclipse with AJDT installed, if I'm
not mistaken.  Other editors, and eclipse without AJDT, would display
the introduced methods, which is undesirable.

If only load-time weaving were used, then this is a non-issue, but I
feel that compile-time weaving is more pragmatic, especially in
application server environments, and that's when this issue is
experienced.

I don't want to ask for something that doesn't make sense.  Does it
now?  Please confirm.

Thanks,
Matthew

On Mon, Aug 31, 2009 at 1:42 PM, Andrew Eisenberg<andrew@...> wrote:

> Hi Matthew,
>
> I don't think that's currently possible, so you should probably raise
> an enhancement request for that.
>
> However, I would like to know why this is so important to you.
>
> These methods are synthetic and someone who wants to call them must
> either look at the byte code or have knowledge about AspectJ.  In the
> IDE, they are filtered from content assist.  And even if these methods
> were made private, they could still be accessible via reflection.
>
> I'm not entirely sure how security policies work, but I know they can
> be used to restrict reflective access to fields.  Can they also be
> used to restrict other kinds of access?
>
> On Mon, Aug 31, 2009 at 1:13 PM, matthewadams12<matthew@...> wrote:
>>
>> I've noticed that introduced fields appear to be more public than I'd like.
>>
>> Consider the following code, all in package "intro.test":
>>
>> @Target(ElementType.TYPE)
>> @Retention(RetentionPolicy.RUNTIME)
>> public @interface HasBar {}
>> =================
>> @HasBar
>> public class Foo {}
>> =================
>> public aspect HasBarIntro {
>>
>>        private interface HasBar {}
>>
>>        declare parents: (@intro.test.HasBar *) implements HasBar;
>>
>>        private String HasBar.bar;
>>
>>        public String HasBar.getBar() {
>>                return bar;
>>        }
>>
>>        public void HasBar.setBar(String bar) {
>>                this.bar = bar;
>>        }
>> }
>> =================
>>
>> After compiling, the introduced String "bar" appears as a public field on
>> Foo.  When I run "javap -private intro.test.Foo", I get the following:
>>
>> Compiled from "Foo.java"
>> public class intro.test.Foo extends java.lang.Object implements
>> intro.test.HasBarIntro$HasBar{
>>    public java.lang.String
>> ajc$interField$intro_test_HasBarIntro$intro_test_HasBarIntro$HasBar$bar;
>>    public intro.test.Foo();
>>    public java.lang.String
>> ajc$interFieldGet$intro_test_HasBarIntro$intro_test_HasBarIntro$HasBar$bar();
>>    public void
>> ajc$interFieldSet$intro_test_HasBarIntro$intro_test_HasBarIntro$HasBar$bar(java.lang.String);
>>    public java.lang.String getBar();
>>    public void setBar(java.lang.String);
>> }
>>
>> Notice the first field, a public String field introduced by HasBarIntro.
>> Why is the field public?  Is there a way for all of the members prefaced
>> with "ajc$" to be non-public?
>>
>> I tried to ask this question once already:
>> http://www.nabble.com/ITD-public-fields-break-encapsulation--ts25154702.html
>>
>> Thanks,
>> Matthew
>>
>>
>> Andrew Eisenberg wrote:
>>>
>>> If the interface used as the introduced parent is only accessible
>>> inside the aspect (ie- it is private), then its methods should only be
>>> accessible from within the aspect.  So, your strategy below should
>>> work (however, I have not tried this out myself).
>>>
>>> 2009/8/31 João Gonçalves <jocolimonada@...>:
>>>> Using the private keyword in the factory method (for @DeclareMixin) /
>>>> field
>>>> (for @DeclareParents)?
>>>> That is:
>>>>     @DeclareMixin("ClassName")
>>>>     private static IFood create FoodImplementation() {
>>>>         return new FoodImpl();
>>>>     }
>>>>
>>>> and
>>>>     @DeclareParents(value="ClassName",defaultImpl=FoodImpl.class)
>>>>     private IFood food;
>>>>
>>>>
>>>> Thanks. Also, in the above examples, the visibility will be private, even
>>>> if
>>>> the interface/implementation class is public, right?
>>> _______________________________________________
>>> aspectj-users mailing list
>>> aspectj-users@...
>>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>>
>>>
>>
>> --
>> View this message in context: http://www.nabble.com/Visibility-of-inter-type-members-with-%40DeclareMixin-and-%40DeclareParents-tp25226224p25229677.html
>> Sent from the AspectJ - users mailing list archive at Nabble.com.
>>
>> _______________________________________________
>> aspectj-users mailing list
>> aspectj-users@...
>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@...
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>



--
mailto:matthew@...
skype:matthewadams12
yahoo:matthewadams
aol:matthewadams12
google-talk:matthewadams12@...
msn:matthew@...
http://matthewadams.me
http://www.linkedin.com/in/matthewadams
_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Re: Visibility of inter-type members with @DeclareMixin and @DeclareParents

by Andrew Eisenberg :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> With regard to synthetic method filtering, the introduced methods
> would only be filtered during content assistance in an editor that
> knew about AspectJ, which is only eclipse with AJDT installed, if I'm
> not mistaken.  Other editors, and eclipse without AJDT, would display
> the introduced methods, which is undesirable.

I can see how this can be confusing to users who do not have AJDT
installed.  It is a bit of a leaky abstraction.  It is worth making an
enhancement request for AspectJ.  Is the problem only with content
assist, or are there other places that you see the introduced fields
and methods appearing?  Andy will get back to you on it when he
returns.
_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Parent Message unknown Re: Visibility of inter-type members with @DeclareMixin and @DeclareParents

by matthewadams12 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Bug filed.

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

Thanks,
Matthew

On Tue, Sep 1, 2009 at 8:29 AM, Matthew Adams<matthew@...> wrote:

>> It is a bit of a leaky abstraction.  It is worth making an
>> enhancement request for AspectJ.
>>
> Ok, will do.
>
>>  Is the problem only with content
>> assist, or are there other places that you see the introduced fields
>> and methods appearing?  Andy will get back to you on it when he
>> returns.
>>
> Really, that's it.  The issues that I'm concerned about are:
>
> 1. Fear factor.
> Let's face it, introducing introduction to a dev team can be scary,
> and when a member of the team hits dot in the IDE and sees all kinds
> of incredibly long "ajc$..." fields & methods, they kind of freak out.
>  If they only saw conventionally-named java methods when using the
> public interface of the class, it easy to achieve adoption.
>
> 2. Encapsulation.
> When introducing fields, they end up public in the class, which means
> that anyone could set them, bypassing the business logic governing the
> setting of their values.  I think this is a rarer use case, because
> most people on a dev team tend to be cooperative and not malicious,
> but the fact remains that public fields on classes are very rare.
>
> Again, I'm primarily concerned with AspectJ's obfuscation of the
> **public** interface of the class.  Once you can see the soft
> underbelly of a class (other classes in the same package, subclasses,
> etc), I say anything goes.  You're under the hood at that point.
>
> Thanks,
> Matthew
>
>
> --
> mailto:matthew@...
> skype:matthewadams12
> yahoo:matthewadams
> aol:matthewadams12
> google-talk:matthewadams12@...
> msn:matthew@...
> http://matthewadams.me
> http://www.linkedin.com/in/matthewadams
>



--
mailto:matthew@...
skype:matthewadams12
yahoo:matthewadams
aol:matthewadams12
google-talk:matthewadams12@...
msn:matthew@...
http://matthewadams.me
http://www.linkedin.com/in/matthewadams
_______________________________________________
aspectj-users mailing list
aspectj-users@...
https://dev.eclipse.org/mailman/listinfo/aspectj-users