On Oct 17, 2008, at 10:14 AM, Guilhem wrote:
> hi paul,
>
> first I'm not using spring but yes all my resources are singletons.
>
Ah! I reproduced the same issue in a different context. I just
reproduced what you observe using singleton instances explicitly
added. The problem is the singleton instance is retaining the old
reference on the field. When reloading the old instance of
ConfigurationService needs to be removed from the singleton and a new
one added.
But i just noticed another issue, the reload application is doing:
WebApplication _application = create();
configure(config, resourceConfig, _application);
initiate(resourceConfig, _application);
application = _application;
which is wrong, i think reload should just do:
WebApplication _application = create();
initiate(resourceConfig, _application);
application = _application;
which is why you require the boolean variable (but still see the issue
with the old reference). Also i think configure should no longer have
WebApplication passed in as a parameter to the method.
Perhaps i was being too smart proposing the use of a singleton
resource and instead it may be more appropriate to inject a
ContainerNotifier implementation as follows in the Servlet configure
method:
rc.getSingletons().add(new
ContextInjectableProvider<ContainerNotifierImpl>(
ContainerNotifierImpl.class, cnImpl));
and in your ConfigurationService do:
@Path("reload")
public class ConfigurationService {
@Context ContainerNotifierImpl cn;
@Context UriInfo u;
@POST public void reload() {
cn.reload();
}
}
Then you will not get any old reference issues.
> 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.
>
OK.
> 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 ?
>
Yes.
Paul.
> 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
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>