Regsitering singletons

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Regsitering singletons

ax487
Hello all,

I am wondering about the correct way to register singletons in a
ResourceConfig. I have a class which has no trivial constructor so any
attempt to create a new instance using reflection will fail.

I did like the idea of using `registerInstance(new
SingletonExample(args))`. I tried this out with a singleton subclassing
`ApplicationEventListener`. In this case the singleton was used and
received events. However, as soon as I tried to `@Inject` the
`SingletonExample` into some resource I immediately got an exception.

I saw a related thread here:

https://stackoverflow.com/questions/23304404/trouble-creating-a-simple-singleton-class-in-jersey-2-using-built-in-jersey-depe

The solution seems to be to use a factory like this:

  register(new AbstractBinder() {
    @Override
    protected void configure() {
      bindFactory(new SingletonFactory(new SingeltonExample(args)))
        .to(SingletonExample.class)
        .in(Singleton.class);
    }
  });

Where the `SingletonFactory` implements `Factory<SingletonExample>` and
always yields the same instance. This way I can inject the singleton and
everything works as it should. However, this approach introduces a lot
of overhead and I would really rather keep things simple.

I noticed that it is not possible to bind instances like this:

  registerInstance(new SingletonExample(args))
    .to(SingletonExample.class)

Am I missing something or is there really no easy way to register
singletons?

ax487
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Regsitering singletons

Maarten Boekhold
Is something like this what you are looking for?

http://stackoverflow.com/a/28018490/1023458

Maarten


On 9 March 2016 17:27:17 ax487 <[hidden email]> wrote:

> Hello all,
>
> I am wondering about the correct way to register singletons in a
> ResourceConfig. I have a class which has no trivial constructor so any
> attempt to create a new instance using reflection will fail.
>
> I did like the idea of using `registerInstance(new
> SingletonExample(args))`. I tried this out with a singleton subclassing
> `ApplicationEventListener`. In this case the singleton was used and
> received events. However, as soon as I tried to `@Inject` the
> `SingletonExample` into some resource I immediately got an exception.
>
> I saw a related thread here:
>
> https://stackoverflow.com/questions/23304404/trouble-creating-a-simple-singleton-class-in-jersey-2-using-built-in-jersey-depe
>
> The solution seems to be to use a factory like this:
>
>   register(new AbstractBinder() {
>     @Override
>     protected void configure() {
>       bindFactory(new SingletonFactory(new SingeltonExample(args)))
>         .to(SingletonExample.class)
>         .in(Singleton.class);
>     }
>   });
>
> Where the `SingletonFactory` implements `Factory<SingletonExample>` and
> always yields the same instance. This way I can inject the singleton and
> everything works as it should. However, this approach introduces a lot
> of overhead and I would really rather keep things simple.
>
> I noticed that it is not possible to bind instances like this:
>
>   registerInstance(new SingletonExample(args))
>     .to(SingletonExample.class)
>
> Am I missing something or is there really no easy way to register
> singletons?
>
> ax487


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Regsitering singletons

ax487
No, not exactly, unfortunately. Simply calling "register" does not seem
to "bind" the registered instance to be usable for injection.

On 09.03.2016 15:56, Maarten Boekhold wrote:

> Is something like this what you are looking for?
>
> http://stackoverflow.com/a/28018490/1023458
>
> Maarten
>
>
> On 9 March 2016 17:27:17 ax487 <[hidden email]> wrote:
>
>> Hello all,
>>
>> I am wondering about the correct way to register singletons in a
>> ResourceConfig. I have a class which has no trivial constructor so any
>> attempt to create a new instance using reflection will fail.
>>
>> I did like the idea of using `registerInstance(new
>> SingletonExample(args))`. I tried this out with a singleton subclassing
>> `ApplicationEventListener`. In this case the singleton was used and
>> received events. However, as soon as I tried to `@Inject` the
>> `SingletonExample` into some resource I immediately got an exception.
>>
>> I saw a related thread here:
>>
>> https://stackoverflow.com/questions/23304404/trouble-creating-a-simple-singleton-class-in-jersey-2-using-built-in-jersey-depe
>>
>>
>> The solution seems to be to use a factory like this:
>>
>>   register(new AbstractBinder() {
>>     @Override
>>     protected void configure() {
>>       bindFactory(new SingletonFactory(new SingeltonExample(args)))
>>         .to(SingletonExample.class)
>>         .in(Singleton.class);
>>     }
>>   });
>>
>> Where the `SingletonFactory` implements `Factory<SingletonExample>` and
>> always yields the same instance. This way I can inject the singleton and
>> everything works as it should. However, this approach introduces a lot
>> of overhead and I would really rather keep things simple.
>>
>> I noticed that it is not possible to bind instances like this:
>>
>>   registerInstance(new SingletonExample(args))
>>     .to(SingletonExample.class)
>>
>> Am I missing something or is there really no easy way to register
>> singletons?
>>
>> ax487
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Regsitering singletons

ljnelson
On Wed, Mar 9, 2016 at 7:04 AM ax487 <[hidden email]> wrote:
No, not exactly, unfortunately. Simply calling "register" does not seem
to "bind" the registered instance to be usable for injection.

Making a bit of a leap here, but perhaps what you are saying is that your singleton implements some interface that you want to use as the type for various injection slots, and injection at those points is failing.  Further, I'm going to guess that the interfaces in question are not annotated with HK2's Contract annotation.  

If that's what's going on, you probably want this variant of the register() method: https://jersey.java.net/apidocs/latest/jersey/org/glassfish/jersey/server/ResourceConfig.html#register(java.lang.Object,%20java.lang.Class...)  Then you can specify exactly what contract types should be used.  Good luck.

Best,
Laird
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Regsitering singletons

ax487


On 09.03.2016 21:53, Laird Nelson wrote:

> On Wed, Mar 9, 2016 at 7:04 AM ax487 <[hidden email]> wrote:
>
>> No, not exactly, unfortunately. Simply calling "register" does not seem
>> to "bind" the registered instance to be usable for injection.
>>
>
> Making a bit of a leap here, but perhaps what you are saying is that your
> singleton implements some interface that you want to use as the type for
> various injection slots, and injection at those points is failing.
> Further, I'm going to guess that the interfaces in question are not
> annotated with HK2's Contract annotation.
>
> If that's what's going on, you probably want this variant of the register()
> method:
> https://jersey.java.net/apidocs/latest/jersey/org/glassfish/jersey/server/ResourceConfig.html#register(java.lang.Object,%20java.lang.Class...)
>  Then you can specify exactly what contract types should be used.  Good
> luck.
>
> Best,
> Laird
>

Well, I tried that. I don't really have contracts (interfaces) though.
So I tried using `register(new SingletonExample(args),
SingletonExample.class)`. But I just get an exception when I try to
instanciated a resource:

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no
object available for injection at
SystemInjecteeImpl(requiredType=SingletonExample,parent=ResourceExample,qualifiers={},position=0,optional=false,self=false,unqualified=null,555676986)


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Regsitering singletons

ljnelson
On Wed, Mar 9, 2016 at 1:26 PM ax487 <[hidden email]> wrote:
Well, I tried that. I don't really have contracts (interfaces) though.

Then register(Object) is the one you want.  I have no idea why it's not working.  It works for me!

What does your injection point look like?  I'm assuming it's utterly trivial and looks like this:

public class ResourceExample {
  @Inject
  private SingletonExample singleton;
 /* ... */
}

Best,
Laird
Loading...