New annotation proposal @Singleton

1,863 views
Skip to first unread message

Alan Rodas

unread,
Aug 24, 2011, 9:48:49 PM8/24/11
to Project Lombok
Hello folks, first of anything, I just wanted to say that I love the
framework...it makes java look like a real language.

I wanted to propose a new annotation that would be nice to have,
@Singleton.

I think its more than obvious what the intention of this should be,
but just in case, the idea is to translate something like

@Singleton
public class MyClass {}

in

public class MyClass {
private static MyClass instance = new MyClass();
private MyClass() {}
private static getInstance { return instance;}
}
+Or maybe with additional verification such as sychronize for thread
safe singletons.

If it's possible, it would be really nice to have these feature
because
a) You eliminate a lot of boilerplate to implement this pattern that
is quite common
b) The annotation is worth as documentation for the class

I would love to try to code it myself and collaborate with the
project, but unfortunately I'm busy as hell to join now, so I though
to at least throw the idea for anyone who may find it interesnting and
want to implement it.


Cheers and kudos to the team

Reinier Zwitserloot

unread,
Aug 24, 2011, 10:52:28 PM8/24/11
to project...@googlegroups.com
We'd probably at least add a whole bunch of extensive boilerplate to make sure the singleton serializes and deserializes, and does so in a way that it remains a singleton.

However, having @Singleton available more or less suggests that we believe its a good idea to be able to build such classes, and it really isn't. It's the standard thing everybody thinks of, but rare is the case that a singleton is the right implementation strategy. We'd rather not make it that easy :P

Roel is on vacation, so we'll have to wait on his answer. Robbert Jan, you as underwhelmed by singletons as I am?

Leon Blakey

unread,
Aug 25, 2011, 12:21:38 AM8/25/11
to project...@googlegroups.com
Does creating a singleton come up enough times in a project to warrant an annotation? I think once you've gotten to that stage there is a serious design problem.


--
You received this message because you are subscribed to the Google
Groups group for http://projectlombok.org/
 
To post to this group, send email to project...@googlegroups.com
To unsubscribe from this group, send email to
project-lombo...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/project-lombok?hl=en

Maaartin G

unread,
Aug 25, 2011, 7:12:06 AM8/25/11
to Project Lombok
On Aug 25, 3:48 am, Alan Rodas <alanro...@gmail.com> wrote:
> I wanted to propose a new annotation that would be nice to have,
> @Singleton.

A real singleton is an anti-pattern. Consider switching to dependency
injection and use @com.google.inject.Singleton (or
@javax.inject.Singleton or whatever) instead.

Marius Kruger

unread,
Aug 25, 2011, 10:26:55 AM8/25/11
to project...@googlegroups.com
I think Singletons are really useful for managing stuff that you need to be sure there is at most one instance in a vm (eg. a JNI library like JR).

I think this is used often enough to warrant a properly implemented annotation.
Especially because most implementations are quite buggy or slow because of laziness, oversights and oblivion.

JavaEE already has a @Singleton annotation for stateless session beans with this requirement.

maybe have 2 variations:
@EagerSingleton :
private static MyObject instance = new MyObjest();
public MyObject getInstance() {
    return instance;
}

@LazySingleton :
private static MyObject instance = null;
private static Object instanceMutex = new Object[0];
public MyObject getInstance() {
    if (instance == null) {
        synchronize(instanceMutex) {
             if (instance == null) {
                   instance = new MyObjest();
             }
        }
    }
    return instance;
}

-- 
<>< Marius ><>

Marius Kruger

unread,
Aug 25, 2011, 10:31:29 AM8/25/11
to project...@googlegroups.com
On 25 August 2011 16:26, Marius Kruger <ama...@gmail.com> wrote:
(eg. a JNI library like JR).
that is a JNI library like JRI (java api to the R language) that freaks out if you try to have more than one instance.

Other resources also fall into that category, eg. a global cache,
some other system resources like a managed directory,
interfaces to other systems that are sensitive to multiple users like legacy systems,  modems, fax machines.

But I do agree that it can be overused..
--
<>< Marius ><>

Maaartin G

unread,
Aug 25, 2011, 10:47:29 AM8/25/11
to Project Lombok
On Aug 25, 4:31 pm, Marius Kruger <ama...@gmail.com> wrote:
> On 25 August 2011 16:26, Marius Kruger <ama...@gmail.com> wrote:

You LazySingleton uses double checked locking, which is broken. Using
volatile would help (under the "new" Java memory model, I think coming
with JDK5). Using something like http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
is the way I'd recommend (if I would recommend any use of a singleton
at all).

> that is a JNI library like JRI (java api to the R language) that freaks out
> if you try to have more than one instance.

Sure, there may be classes like this, but there are not many of them.

> Other resources also fall into that category, eg. a global cache,
> some other system resources like a managed directory,
> interfaces to other systems that are sensitive to multiple users like legacy
> systems,  modems, fax machines.

This is all wrong usage. Using singletons is no better than using
global variables. There's no way to find out the dependencies and no
way to test properly. How can you test what happens without the global
cache when you're using a singleton for this?

> But I do agree that it can be overused..http://en.wikipedia.org/wiki/Singleton_pattern

IMHO, any use of a singleton is a sign of a problem. Having more of
them is nearly always wrong. I'd recommend switching to dependency
injection.

Marius Kruger

unread,
Aug 25, 2011, 11:11:52 AM8/25/11
to project...@googlegroups.com
On 25 August 2011 16:47, Maaartin G <graj...@seznam.cz> wrote:
You LazySingleton uses double checked locking, which is broken. Using
volatile would help (under the "new" Java memory model, I think coming
with JDK5). Using something like http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
is the way I'd recommend (if I would recommend any use of a singleton
at all).

cool. Well exactly my point it is very error prone to try and do it manually.
So if you are going to do it anyway rather do it properly.

This is all wrong usage. Using singletons is no better than using
global variables.

yes it is like global variables but by using the getter you can later change what it does without changing all your code, mmm then it is better to only expose it's interface.
 
There's no way to find out the dependencies
 
Assuming you have dependencies. 

and no
way to test properly.

Well if you have to test that you can always change getInstance to be able to give you test objects while testing. A lot of tests might need the real one though.
 
IMHO, any use of a singleton is a sign of a problem. Having more of
them is nearly always wrong.

as I said if people are gonna use them in any case, rather do it properly..
 
I'd recommend switching to dependency
injection.

I agree, but I think lombok can be lighterweight than any dependency injection framework and less effort to set up initially.
 
--
<>< Marius ><>

Maaartin G

unread,
Aug 25, 2011, 2:17:26 PM8/25/11
to Project Lombok
On Aug 25, 5:11 pm, Marius Kruger <ama...@gmail.com> wrote:
> On 25 August 2011 16:47, Maaartin G <grajc...@seznam.cz> wrote:
> cool. Well exactly my point it is very error prone to try and do it
> manually.
> So if you are going to do it anyway rather do it properly.

IMHO you just shouldn't do it. And there's @Getter(lazy=true), which
can be used for this, if you really want to.

> yes it is like global variables but by using the getter you can later change
> what it does without changing all your code, mmm then it is better to only
> expose it's interface.

Yes. Later. So you need to change the code of your singletons in order
to get a different behavior. And change it back after the test and so
on.

> > There's no way to find out the dependencies
> Assuming you have dependencies.

In case you have no dependencies on your singletons, just throw them
away. :D

> and no way to test properly.
>
> Well if you have to test that you can always change getInstance to be able
> to give you test objects while testing. A lot of tests might need the real
> one though.

Yes, and changing the code back and forth is the only way how to test
the code, unless you introduce some more global variables.

> I agree, but I think lombok can be lighterweight than any dependency
> injection framework and less effort to set up initially.

But Lombok could only help you do something stupid more easily.
Starting with DI using Guice is not hard at all, just adding
@Singleton and @Inject annotations to classes which should be
singletons. Later the things may get more complicated, but only such
which go far beyond what you get get with singletons.

Robbert Jan Grootjans

unread,
Aug 25, 2011, 3:14:31 PM8/25/11
to project...@googlegroups.com
Singletons, and any other 'global' construct greatly increases
coupling between classes and makes things like modularization and
testabilty a pain in the ass. There are use cases for them, but I'd
vote for using a DI system like Guice or Weld to construct and deliver
your singletons for you.

So, no, not really a feature I'd vote for ;)

Marius Kruger

unread,
Aug 25, 2011, 5:06:33 PM8/25/11
to project...@googlegroups.com
On 25 August 2011 20:17, Maaartin G <graj...@seznam.cz> wrote:
But Lombok could only help you do something stupid more easily.

ok fine I can see that its a bad idea in general (so a very low priority at best),
Then I think these sort of decisions should go onto a FAQ
explaining why. Rather than having it discussed over and over again.
 
--
<>< Marius ><>

Alan Rodas

unread,
Aug 26, 2011, 11:51:04 AM8/26/11
to project...@googlegroups.com
Sorry guys, but I dont understand your point. 

Singleton classes are usually abused because people doesn't follow the two basic rules for singletons

1) A singleton should not ever, ever have state
2) A singleton should not ever be stored in an instance variable, SingletonClass.getInstance() should be used instead.

If you follow this guidelines and you build a singleton, then is probably because you needed a singleton. If you build singletons and break this guidelines, then probably that you needed something else, and you should reconsider your application design.

Of course, I agree that dependency injection is in many cases better. So I understand the low priority.

Thanks for the consideration.

Cheers

Reinier Zwitserloot

unread,
Aug 26, 2011, 5:59:30 PM8/26/11
to project...@googlegroups.com
Yup, building singletons for something like java.lang.Math makes some sense, but you could also just make all methods static (if there's no state, there's not usually any need for instances).

Reply all
Reply to author
Forward
0 new messages