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
>