users@jersey.java.net

Re: [Jersey] restart a resource

From: Guilhem <guilhem.legal_at_geomatys.fr>
Date: Fri, 17 Oct 2008 10:14:53 +0200

hi paul,

first I'm not using spring but yes all my resources are singletons.

i'm using the :
@Context
protected UriInfo context;

MultivaluedMap parameters = context.getQueryParameters();

to get a GET parameters like: request=restart or whatever in all my
singletons.


the weird thing is that all the other resources restarted does not throw
the illegalStateException by getting parameters, only the reloadResource
launch this.

for 2), It seems that the resources are well destroyed and
re-instanciated (They all pass in constructor).

when you say fields for injection you means that : @Context Protected
UriInfo context ?

Guilhem



Paul Sandoz a écrit :
> Hi Guilhem,
>
> This was a bit of a head scratcher. I am guessing you are using a
> Singleton resource with Spring?
>
> The problem is the reference held by the field on the singleton
> resource is longer valid after the reloading. This is because
> reloading will cause the web application to create new references for
> injection, which invalidates any previously help references. This is a
> general problem for singletons whose instances are controlled outside
> of Jersey and for which injection is performed. When Jersey performs
> injection it will not overwrite anything with a non-null value.
>
> Three possible ways to directly resolve this:
>
> 1) Don't use fields for injection;
>
> 2) The reload functionality you have implemented needs to destroy the
> singletons so that they are re-
> instantiated; or
>
> 3) Jersey is modified inject on non-null values.
>
> I am not comfortable supporting 3) or doing something more complicated
> around sharing state or detecting reloads and working around the
> issues. In this case i think 2) is required.
>
> Of course the better approach is to support richer notification events
> on changes to resource classes: removal, addition and class
> modification. Changes to provider classes may be more problematic...
>
> Paul.
>
> On Oct 16, 2008, at 6:20 PM, Guilhem wrote:
>
>> Hi,
>>
>> i put in place the mecanism described previously, everything working
>> well until i realized that i can restart my WS only one time before
>> getting a IllegalStateException:
>>
>> i just change some pieces of code to get this working :
>>
>> - my resource ReloadResource (ConfigurationService) implementing
>> ContainerNotifier is not in the same class that the servletContainer.
>>
>> - i had to put a boolean flag to add the reload resource only one
>> time (i got an exception else) :
>>
>>
>> public class CstlServletContainer extends ServletContainer {
>>
>> public static boolean reload = false;
>> @Override
>> protected void configure(final ServletConfig sc, ResourceConfig rc,
>> WebApplication wa) {
>> super.configure(sc, rc, wa);
>> ConfigurationService configService = new ConfigurationService();
>> if (!reload) {
>> rc.getSingletons().add(configService);
>> }
>> reload = true;
>>
>> rc.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_NOTIFIER,
>> configService);
>> }
>> }
>>
>>
>> so the first time the restart works well when i do this (you can see
>> that i don't want to restart my reloadResource in order to send a xml
>> result when the operation is ended):
>>
>> ...................
>>
>> for ( ContainerListener cl : cls) {
>> if (!cl.equals(this))
>> cl.onReload();
>> }
>>
>> .....................
>>
>>
>> and the second time i call this method i get an illegalstateException
>> when i trying to get a parameter in this line :
>>
>> .....................
>>
>> @Context
>> protected UriInfo context;
>>
>> ......................
>>
>>
>> line 352: final MultivaluedMap parameters =
>> context.getQueryParameters();
>>
>>
>> ................
>>
>> exception:
>>
>> java.lang.IllegalStateException
>> com.sun.jersey.impl.ThreadLocalHttpContext.getUriInfo(ThreadLocalHttpContext.java:67)
>>
>> com.sun.jersey.impl.application.WebApplicationImpl$2.invoke(WebApplicationImpl.java:184)
>>
>> $Proxy7.getQueryParameters(Unknown Source)
>> org.constellation.ws.rs.WebService.getParameter(WebService.java:352)
>>
>>
>>
>> Is someone know you know why i'm getting this exception?
>>
>> Guilhem Legal
>>
>> Paul Sandoz a écrit :
>>>
>>> On Oct 3, 2008, at 2:23 PM, Guilhem wrote:
>>>
>>>> hi,
>>>>
>>>> i follow the tutorial i 've found at
>>>> http://blogs.sun.com/sandoz/entry/javarebel_and_jersey_take_2
>>>> this works well, but I don't see how to use this with tomcat
>>>> instead of a lightWebContainer.
>>>>
>>>
>>> You can extend the ServletContainer to register a container
>>> notifier. You need to add an instance of ContainerNotifier to to the
>>> resource config properties
>>> (ResourceConfig.PROPERTY_CONTAINER_NOTIFIER).
>>>
>>> Override the configure methods to do something like this:
>>>
>>> protected void configure(final ServletConfig sc, ResourceConfig
>>> rc, WebApplication wa) {
>>> super.configure(sc, rc, wa);
>>>
>>> ContainerNotifier cn = ....
>>>
>>> rc.getProperties().put(esourceConfig.PROPERTY_CONTAINER_NOTIFIER, cn);
>>> }
>>>
>>>
>>>> more, the resource are reloaded only when the classes are changed.
>>>>
>>>> For my application I want to make a JSF interface with a button
>>>> "reload" which restart all the resources (i had prefer only
>>>> selected resource but it seems to be unpossible).
>>>>
>>>
>>> Yes, currently it is not possible reload a single resource. Do you
>>> want to log an issue?
>>>
>>> It sounds like you want to have a another resource that triggers a
>>> reload.
>>>
>>> You could have a singleton resource instance you add to the
>>> singletons of ResourceConfig at configuration time that has the
>>> instance of the ContainerNotifier, then when a POST method is sent
>>> to that resource it can perform a reload.
>>>
>>> protected void configure(final ServletConfig sc, ResourceConfig
>>> rc, WebApplication wa) {
>>> super.configure(sc, rc, wa);
>>>
>>> ReloadResource rr = new ReloadResource(cn);
>>> rc.getSingletons().add(rr);
>>>
>>> rc.getProperties().put(esourceConfig.PROPERTY_CONTAINER_NOTIFIER, rr);
>>> }
>>>
>>> ....
>>>
>>> @Path("reload")
>>> public class ReloadResource implements ContainerNotifier {
>>> List<ContainerListener> cls;
>>> ...
>>>
>>> @POST void reload() {
>>> for (ContainerListener cl : cls) cl.onReload();
>>> }
>>> }
>>>
>>>
>>> Alternatively you could create an injectable provider to inject the
>>> registered container notifier.
>>>
>>>
>>>> is there any tutorial which help me to do this?
>>>>
>>>
>>> Unfortunately not :-(
>>>
>>> Paul.
>>>
>>>
>>>> Guilhem Legal
>>>>
>>>>
>>>> Paul Sandoz a écrit :
>>>>>
>>>>> On Sep 24, 2008, at 4:42 PM, Guilhem wrote:
>>>>>
>>>>>> hi,
>>>>>>
>>>>>> I would know if its possible to dynamically restart a resource
>>>>>> without having to undeploy/deploy or restart the container?
>>>>>>
>>>>>
>>>>> It is currently only possible to reload all resources. What
>>>>> happens is a new web application is created, configured and
>>>>> initiated.
>>>>>
>>>>> See the JavaDoc of the class:
>>>>>
>>>>> com.sun.jersey.spi.container.ContainerNotifier
>>>>>
>>>>> to register a notifier that may reload the container.
>>>>>
>>>>> I have used this in conjunction with JavaRebel. When JavaRebel
>>>>> detects changes to class files i have a hook in that to
>>>>> dynamically reload things using a ContainerNotifier without having
>>>>> to undeploy/deploy the web application.
>>>>>
>>>>> Does that work for you?
>>>>>
>>>>> Paul.
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>>
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>
>