Re: [ljc] RFC - Default service implementation structure

From: Gerald L.
Sent on: Friday, March 8, 2013 9:37 AM
you're right that there is that separate, seemingly stand-alone
class-file for each static inner class, which the class-path scanner
might pick up if instructed to find all classes with a certain
annotation (@Component, for instance). The de-facto standard for
class-path scanning seems to be ASM, so in some way it depends how ASM
behaves in that respect.

What i don't know is if the byte-code of a static inner class actually
identifies it as an inner class - or if it's just compiler magic, as
you say, and all the information about the class-relationship is just
in the class name ($). In any case, once the class is loaded,
reflection does tell you if it's an inner class or not.

Where there is a spec, however, i.e. for all Java EE technologies but
not for Spring, the situation is more clear-cut insofar as i would
stay away from doing anything (like using inner classes for
components) that the spec prohibits - even if in practice it happens
to work (unless there's a very good reason to violate the spec).

  cheers
  gerald


On Fri, Mar 8, 2013 at 7:52 AM, Wesley Hall <[address removed]> wrote:
> I would actually be interested to try this out.
>
> I am not sure it really is that clever of spring really. Inner classes
> (to my knowledge) are all just compiler magic. Post-compilation there
> isn't really anything different about them, and I *think* that my
> static inner implementation results in exactly the same compiler
> output as if I had created a top-level class called
> AccountService$Defau­lt.java in the same package.
>
> With this in mind I think you would have to go to extra effort to
> exclude these classes from runtime annotations scanning (by rejecting
> classes with $ in the name for example).
>
> I am about 80% sure of this but someone with better knowledge of the
> JVM (ping: Ben or Martijn) can probably confirm.
>
> Wes
>
> On Thu, Mar 7, 2013 at 4:30 PM, Gerald Loeffler
> <[address removed]> wrote:
>> On Thu, Mar 7, 2013 at 12:36 PM, Wesley Hall <[address removed]> wrote:
>>> I am using DI with the spring annotations, spring has no problem
>>> finding annotated static inner-classes though I am not sure about
>>> other technologies.
>>
>> that's surprisingly clever of Spring (and not atypical for the
>> attention to detail they typically show).
>> For EJB and CDI, however, i'm certain that the specs demand that
>> auto-discovered components are top-level classes. And i'd be surprised
>> if this were different for JAX-WS and JAXRS webservice implementations
>> (although i don't remember what the spec says).
>>
>>> I guess non-static inner classes will not work because they need a
>>> reference to the containing instance.
>>
>> sure.
>>
>>   cheers
>>   gerald
>>
>>>
>>>
>>>
>>> On Thu, Mar 7, 2013 at 10:55 AM, Gerald Loeffler
>>> <[address removed]> wrote:
>>>> I assume that any technology that depends on class-path scanning to
>>>> automatically discover your service implementation (without you having
>>>> to register it anywhere) will only find it if it is a top-level class.
>>>> This means that your nested default service implementations cannot
>>>> - be annotated with @Stateless to become stateless session beans
>>>> - be CDI managed beans (which doesn't require them to be annotated)
>>>> and so cannot be @Inject-ed
>>>> - be annotated with Spring's @Component (or similar) in order to be
>>>> auto-discovered as Spring beans
>>>> - be auto-discovered as SOAP or REST webservice implementations
>>>> - and probably many more.
>>>>
>>>> This is a purely technical point, of course.
>>>>
>>>>   cheers
>>>>   gerald
>>>>
>>>>
>>>> On Mon, Mar 4, 2013 at 12:25 PM, Wesley Hall <[address removed]> wrote:
>>>>>­ Hello folks,
>>>>>­
>>>>>­ I have a little issue that I am sure has crossed the minds of a few
>>>>>­ folks here and thought I would open it up for comments.
>>>>>­
>>>>>­ I am currently working on one of my little toy projects. I usually
>>>>>­ have at least one of these on the go at any given point as it allows
>>>>>­ me to play with new versions of libraries and technologies and also
>>>>>­ lets me develop some of my ideas in terms of structure and layout.
>>>>>­
>>>>>­ Once again, I am finding myself visiting the age old problem of
>>>>>­ service interfaces with single implementations. There seems to be
>>>>>­ quite a few ideas on how to deal with this. Some say not to use an
>>>>>­ interface at all and just have the implementation class, some say to
>>>>>­ use an interface, and then there are suggestions for the naming of the
>>>>>­ implementation class, <Interface>Imp­l? Default<Interface­>? Try really
>>>>>­ hard to come up with a prefix or suffix that is less generic?
>>>>>­
>>>>>­ Over the years I have flitted back and forward between these options,
>>>>>­ never really finding an answer that was all that satisfactory to me.
>>>>>­ Not using an interface always seems the tidiest in terms of code
>>>>>­ structure, but I find that I run into issues around things like AOP
>>>>>­ proxies and having to use cglib proxies rather than JDK ones, which
>>>>>­ adds a lot of complexity and seems to outright break some things.
>>>>>­
>>>>>­ *Impl and Default* seems like a bit of a cop-out, and seem (Impl
>>>>>­ especially) as a bit of a tautology.
>>>>>­
>>>>>­ Coming up with a more specific name seems OK but I sometimes struggle
>>>>>­ to do this. My services generally use spring, but 'SpringXyzService',
>>>>>­ seems a bit crappy too, other than this there is usually nothing much
>>>>>­ to distinguish them. They are simply the pretty bog-standard
>>>>>­ implementation of the required interface.
>>>>>­
>>>>>­ On my new project, I have been trying something a little different,
>>>>>­ which I think I quite like but is perhaps a little unconventional.
>>>>>­
>>>>>­ I have been creating the 'Default' implementation of the interface as
>>>>>­ a package scope inner class within the interface definition itself.
>>>>>­ Like this...
>>>>>­
>>>>>­ public interface AccountService {
>>>>>­
>>>>>­    Account createAccount(String­ email);
>>>>>­
>>>>>­    @Service
>>>>>­    class Default implements AccountService {
>>>>>­
>>>>>­        private Collaborator collaborator;
>>>>>­
>>>>>­        Default(Collaborator­ collaborator) {
>>>>>­            this.collaborator = collaborator;
>>>>>­        }
>>>>>­
>>>>>­        public Account createAccount(String­ email) {
>>>>>­            //Implementation here
>>>>>­        }
>>>>>­    }
>>>>>­ }
>>>>>­
>>>>>­ This kind of thing seems to work functionally, allows for alternative
>>>>>­ implementations either by creating another implementation of the
>>>>>­ AccountService interface or even by extending the default
>>>>>­ implementation and my unit tests have things like this...
>>>>>­
>>>>>­ AccountService accountService = new AccountService.Defau­lt(mockCollaborator);­
>>>>>­
>>>>>­ Which actually looks quite pretty to my eyes.
>>>>>­
>>>>>­ I appreciate that it is all style really, but I am interested if
>>>>>­ anyone has any thoughts, do you use a standard that I haven't
>>>>>­ mentioned here? Do you have any major objection to my new experimental
>>>>>­ approach (either stylistically or because you happen to know it is
>>>>>­ going to break some feature of some important library)?
>>>>>­
>>>>>­ Keen to hear any thoughts that anybody has.
>>>>>­
>>>>>­ Regards
>>>>>­
>>>>>­ Wes
>>>>>­
>>>>>­
>>>>>­
>>>>>­
>>>>>­ --
>>>>>­ Please Note: If you hit "REPLY", your message will be sent to everyone on this mailing list ([address removed])
>>>>>­ http://www.meetup...­
>>>>>­ This message was sent by Wesley Hall ([address removed]) from LJC - London Java Community.
>>>>>­ To learn more about Wesley Hall, visit his/her member profile: http://www.meetup...­
>>>>>­ Set my mailing list to email me
>>>>>­
>>>>>­ As they are sent
>>>>>­ http://www.meetup...­
>>>>>­
>>>>>­ In one daily email
>>>>>­ http://www.meetup...­
>>>>>­
>>>>>­ Don't send me mailing list messages
>>>>>­ http://www.meetup...­
>>>>>­ Meetup, POB 4668 #37895 NY NY USA 10163 | [address removed]
>>>>>­
>>>>
>>>>
>>>>
>>>> --
>>>> Gerald Loeffler
>>>> mailto:[address removed]
>>>> http://www.gerald...­
>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Please Note: If you hit "REPLY", your message will be sent to everyone on this mailing list ([address removed])
>>>> http://www.meetup...­
>>>> This message was sent by Gerald Loeffler ([address removed]) from LJC - London Java Community.
>>>> To learn more about Gerald Loeffler, visit his/her member profile: http://www.meetup...­
>>>> Set my mailing list to email me
>>>>
>>>> As they are sent
>>>> http://www.meetup...­
>>>>
>>>> In one daily email
>>>> http://www.meetup...­
>>>>
>>>> Don't send me mailing list messages
>>>> http://www.meetup...­
>>>> Meetup, POB 4668 #37895 NY NY USA 10163 | [address removed]
>>>>
>>>
>>>
>>>
>>>
>>> --
>>> Please Note: If you hit "REPLY", your message will be sent to everyone on this mailing list ([address removed])
>>> http://www.meetup...­
>>> This message was sent by Wesley Hall ([address removed]) from LJC - London Java Community.
>>> To learn more about Wesley Hall, visit his/her member profile: http://www.meetup...­
>>> Set my mailing list to email me
>>>
>>> As they are sent
>>> http://www.meetup...­
>>>
>>> In one daily email
>>> http://www.meetup...­
>>>
>>> Don't send me mailing list messages
>>> http://www.meetup...­
>>> Meetup, POB 4668 #37895 NY NY USA 10163 | [address removed]
>>>
>>
>>
>>
>> --
>> Gerald Loeffler
>> mailto:[address removed]
>> http://www.gerald...­
>>
>>
>>
>>
>> --
>> Please Note: If you hit "REPLY", your message will be sent to everyone on this mailing list ([address removed])
>> http://www.meetup...­
>> This message was sent by Gerald Loeffler ([address removed]) from LJC - London Java Community.
>> To learn more about Gerald Loeffler, visit his/her member profile: http://www.meetup...­
>> Set my mailing list to email me
>>
>> As they are sent
>> http://www.meetup...­
>>
>> In one daily email
>> http://www.meetup...­
>>
>> Don't send me mailing list messages
>> http://www.meetup...­
>> Meetup, POB 4668 #37895 NY NY USA 10163 | [address removed]
>>
>
>
>
>
> --
> Please Note: If you hit "REPLY", your message will be sent to everyone on this mailing list ([address removed])
> http://www.meetup...­
> This message was sent by Wesley Hall ([address removed]) from LJC - London Java Community.
> To learn more about Wesley Hall, visit his/her member profile: http://www.meetup...­
> Set my mailing list to email me
>
> As they are sent
> http://www.meetup...­
>
> In one daily email
> http://www.meetup...­
>
> Don't send me mailing list messages
> http://www.meetup...­
> Meetup, POB 4668 #37895 NY NY USA 10163 | [address removed]
>



--
Gerald Loeffler
mailto:[address removed]
http://www.gerald...­

Our Sponsors

  • Our Blog

    Read the latest news from the LJC

  • RecWorks Ltd

    Fixing Tech Recruitment using the Power of Community

  • jClarity

    Java/JVM Performance Analysis Tools & mentoring for Java related matters

  • LJC Aggrity

    Our LJC Aggrity site contains blog posts from our members

  • LJC Book Club

    Our Book club with book reviews from our members

  • Devoxx UK

    Java Community Conference, in collaboration with the LJC 12/13 Jun 14

  • SkillsMatter

    "Host, help organise, promote, film many of our meetings."

  • Packt Publishing

    A publishing company specializing on specific technologies and solutions

  • Java.Net

    We are an official Java User Group recognised by Oracle's JUG program

  • JRebel

    Free 3 month J-Rebel license.

  • O'Reilly

    40% discount on printed books and 50% on e-books.

People in this
Meetup are also in:

Sign up

Meetup members, Log in

By clicking "Sign up" or "Sign up using Facebook", you confirm that you accept our Terms of Service & Privacy Policy