Hi Guilhem,
I think i know what is going on, there is a regression due to the
JRebel integration.
On servlet initiation in the ServletContainer it is doing:
protected void initiate(ResourceConfig rc, WebApplication wa) {
wa.initiate(rc);
if (rc instanceof ReloadListener) {
List<ContainerNotifier> notifiers = new
ArrayList<ContainerNotifier>();
for (ContainerNotifier cn :
ServiceFinder.find(ContainerNotifier.class)) {
notifiers.add(cn);
}
rc.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_NOTIFIER,
notifiers);
}
}
and is overwriting the notifier you have registered at configuration.
The reason this occurs for your test is that you are using package
scanning configuration, PackagesResourceConfig, that implements
ReloadListener.
Pavel, can you look into this?
Paul.
On Sep 23, 2010, at 3:20 AM, Guilhem wrote:
> me again :)
>
> just to say that i tried the main below with 1.3 jars instead of 1.4
> and the test works fine.
>
> Guilhem legal
>
> On 23/09/2010 11:46, Guilhem wrote:
>> I modify your testcase in order to run it only with grizzly and i
>> see that here too, the list of containerListener is empty.
>> if you can execute this single class, you can see the log nb=0
>>
>> package test;
>>
>>
>> import javax.ws.rs.POST;
>> import javax.servlet.http.HttpServletRequest;
>> import javax.ws.rs.core.UriInfo;
>> import com.sun.jersey.api.core.ResourceConfig;
>> import com.sun.jersey.spi.container.WebApplication;
>> import com.sun.jersey.spi.container.servlet.ServletContainer;
>> import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
>> import javax.servlet.ServletConfig;
>> import javax.ws.rs.core.Context;
>> import test.ReloadResourceTest.Reloader;
>> import com.sun.jersey.api.client.ClientResponse;
>> import com.sun.grizzly.http.SelectorThread;
>> import com.sun.jersey.api.client.Client;
>> import com.sun.jersey.api.client.WebResource;
>> import javax.ws.rs.Path;
>> import
>> com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory;
>> import com.sun.jersey.spi.container.ContainerListener;
>> import com.sun.jersey.spi.container.ContainerNotifier;
>> import java.io.IOException;
>> import java.net.URI;
>> import java.util.ArrayList;
>> import java.util.HashMap;
>> import java.util.List;
>> import java.util.Map;
>> import javax.ws.rs.GET;
>> import javax.ws.rs.core.UriBuilder;
>> import static org.junit.Assert.*;
>>
>> public class ReloadResourceTest {
>>
>> @Path("/one")
>> public static class One {
>>
>> @GET
>> public String get() {
>> return "one";
>> }
>> }
>>
>> @Path("/two")
>> public static class Two {
>>
>> @GET
>> public String get() {
>> return "two";
>> }
>> }
>>
>> public static class Reloader implements ContainerNotifier {
>>
>> List<ContainerListener> ls;
>>
>> public Reloader() {
>> ls = new ArrayList<ContainerListener>();
>> }
>>
>> public void addListener(ContainerListener l) {
>> ls.add(l);
>> }
>>
>> public void reload() {
>> System.out.println("nb:" + ls.size());
>> for (ContainerListener l : ls) {
>> l.onReload();
>> }
>> }
>> }
>>
>> public static class ReloadServletContainer extends
>> ServletContainer {
>>
>> @Override
>> protected void configure(final ServletConfig sc,
>> ResourceConfig rc, WebApplication wa) {
>> super.configure(sc, rc, wa);
>>
>> Reloader r = new Reloader();
>> rc.getSingletons().add(new
>> SingletonTypeInjectableProvider<Context, Reloader>(
>> Reloader.class, r) {
>> });
>>
>> rc.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_NOTIFIER,
>> r);
>> }
>> }
>>
>>
>> @Path("reload")
>> public static class ReloaderResource {
>>
>> @Context
>> ResourceConfig rc;
>> @Context
>> UriInfo ui;
>> @Context
>> Reloader r;
>>
>> public ReloaderResource(@Context HttpServletRequest r) {
>> }
>>
>> @POST
>> public String postReload() {
>> if (rc.getClasses().contains(Two.class)) {
>> rc.getClasses().remove(Two.class);
>> } else {
>> rc.getClasses().add(Two.class);
>> }
>>
>> r.reload();
>> return ui.getPath();
>> }
>> }
>>
>>
>> public ReloadResourceTest(String testName) {
>> }
>>
>>
>> private static URI getBaseURI() {
>> return UriBuilder.fromUri("http://
>> localhost/").port(9999).build();
>> }
>> public static final URI BASE_URI = getBaseURI();
>>
>> protected static SelectorThread startServer() throws IOException {
>> final Map<String, String> initParams = new HashMap<String,
>> String>();
>>
>> initParams.put("com.sun.jersey.config.property.packages",
>> "test");
>>
>> System.out.println("Starting grizzly...");
>> SelectorThread threadSelector =
>> GrizzlyWebContainerFactory.create(BASE_URI,
>> ReloadServletContainer.class,initParams);
>> return threadSelector;
>> }
>>
>> public static void main(String[] args) throws IOException {
>> SelectorThread threadSelector = startServer();
>> System.out.println("Jersey started");
>>
>> WebResource r = Client.create().resource(getBaseURI());
>>
>> for (int i = 0; i < 2; i++) {
>> assertEquals("one", r.path("one").get(String.class));
>> assertEquals("two", r.path("two").get(String.class));
>>
>> assertEquals("reload",
>> r.path("reload").post(String.class));
>>
>> assertEquals("one", r.path("one").get(String.class));
>> assertEquals(404,
>> r.path("two").get(ClientResponse.class).getStatus());
>>
>> assertEquals("reload",
>> r.path("reload").post(String.class));
>> }
>>
>> System.in.read();
>> threadSelector.stopEndpoint();
>> System.exit(0);
>> }
>> }
>>
>> Guilhem Legal
>>
>> On 23/09/2010 11:08, Guilhem wrote:
>>> I don't succeed to run your test because i don't find the class
>>> AbstractGrizzlyWebContainerTester
>>>
>>> on my side all i see is that the size the ContainerListener in my
>>> ContainerNotifier is empty.
>>> so when i call reload it does nothing. i guess the method
>>> addListener is not called but why.
>>>
>>>
>>> public class ContainerNotifierImpl implements ContainerNotifier {
>>>
>>> private List<ContainerListener> cls;
>>>
>>> public ContainerNotifierImpl() {
>>>
>>> cls = new ArrayList<ContainerListener>();
>>>
>>> }
>>>
>>> public void addListener(ContainerListener arg0) {
>>> // this method is never called
>>> cls.add(arg0);
>>>
>>> }
>>>
>>> public void reload() {
>>> // here the size is always 0 that is my problem
>>> for ( ContainerListener cl : cls) {
>>> cl.onReload();
>>> }
>>> }
>>> }
>>>
>>> Guilhem Legal
>>>
>>> On 22/09/2010 23:41, Paul Sandoz wrote:
>>>> Hi Guilhem,
>>>>
>>>> Can you package up a reproducible test case and attach it to an
>>>> issue?
>>>>
>>>> We have a unit test that does virtually the same thing as you
>>>> have described and it does not fail.
>>>>
>>>> package com.sun.jersey.impl.container.grizzly.web;
>>>>
>>>> import com.sun.jersey.api.client.Client;
>>>> import com.sun.jersey.api.client.ClientResponse;
>>>> import javax.ws.rs.Path;
>>>> import com.sun.jersey.api.client.WebResource;
>>>> import com.sun.jersey.api.core.ResourceConfig;
>>>> import com.sun.jersey.spi.container.ContainerListener;
>>>> import com.sun.jersey.spi.container.ContainerNotifier;
>>>> import com.sun.jersey.spi.container.WebApplication;
>>>> import com.sun.jersey.spi.container.servlet.ServletContainer;
>>>> import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
>>>> import java.util.ArrayList;
>>>> import java.util.List;
>>>> import javax.servlet.ServletConfig;
>>>> import javax.servlet.http.HttpServletRequest;
>>>> import javax.ws.rs.GET;
>>>> import javax.ws.rs.POST;
>>>> import javax.ws.rs.core.Context;
>>>> import javax.ws.rs.core.UriInfo;
>>>>
>>>> /**
>>>> *
>>>> * @author Paul.Sandoz_at_Sun.Com
>>>> */
>>>> public class ReloadResourceTest extends
>>>> AbstractGrizzlyWebContainerTester {
>>>>
>>>> @Path("/one")
>>>> public static class One {
>>>>
>>>> @GET
>>>> public String get() {
>>>> return "one";
>>>> }
>>>> }
>>>>
>>>> @Path("/two")
>>>> public static class Two {
>>>>
>>>> @GET
>>>> public String get() {
>>>> return "two";
>>>> }
>>>> }
>>>>
>>>> private static class Reloader implements ContainerNotifier {
>>>>
>>>> List<ContainerListener> ls;
>>>>
>>>> public Reloader() {
>>>> ls = new ArrayList<ContainerListener>();
>>>> }
>>>>
>>>> public void addListener(ContainerListener l) {
>>>> ls.add(l);
>>>> }
>>>>
>>>> public void reload() {
>>>> for (ContainerListener l : ls) {
>>>> l.onReload();
>>>> }
>>>> }
>>>> }
>>>>
>>>> @Path("reload")
>>>> public static class ReloaderResource {
>>>>
>>>> @Context ResourceConfig rc;
>>>>
>>>> @Context UriInfo ui;
>>>>
>>>> @Context Reloader r;
>>>>
>>>> public ReloaderResource(@Context HttpServletRequest r) {
>>>> assertNotNull(r);
>>>> }
>>>>
>>>> @POST
>>>> public String postReload() {
>>>> if (rc.getClasses().contains(Two.class)) {
>>>> rc.getClasses().remove(Two.class);
>>>> } else {
>>>> rc.getClasses().add(Two.class);
>>>> }
>>>>
>>>> r.reload();
>>>> return ui.getPath();
>>>> }
>>>> }
>>>>
>>>> public static class ReloadServletContainer extends
>>>> ServletContainer {
>>>>
>>>> @Override
>>>> protected void configure(final ServletConfig sc,
>>>> ResourceConfig rc, WebApplication wa) {
>>>> super.configure(sc, rc, wa);
>>>>
>>>> Reloader r = new Reloader();
>>>> rc.getSingletons().add(new
>>>> SingletonTypeInjectableProvider<Context, Reloader>(
>>>> Reloader.class, r){});
>>>>
>>>> rc
>>>> .getProperties().put(ResourceConfig.PROPERTY_CONTAINER_NOTIFIER,
>>>> r);
>>>> }
>>>> }
>>>>
>>>> public ReloadResourceTest(String testName) {
>>>> super(testName);
>>>> }
>>>>
>>>> public void testReload() {
>>>> setServletClass(ReloadServletContainer.class);
>>>> startServer(One.class, ReloaderResource.class);
>>>>
>>>> WebResource r =
>>>> Client.create().resource(getUri().path("/").build());
>>>>
>>>> for (int i = 0; i < 2; i++) {
>>>> assertEquals("one", r.path("one").get(String.class));
>>>> assertEquals(404,
>>>> r.path("two").get(ClientResponse.class).getStatus());
>>>>
>>>> assertEquals("reload",
>>>> r.path("reload").post(String.class));
>>>>
>>>> assertEquals("one", r.path("one").get(String.class));
>>>> assertEquals("two", r.path("two").get(String.class));
>>>>
>>>> assertEquals("reload",
>>>> r.path("reload").post(String.class));
>>>> }
>>>> }
>>>> }
>>>>
>>>>
>>>>
>>>> On Sep 22, 2010, at 6:38 AM, Guilhem wrote:
>>>>
>>>>> Hello,
>>>>>
>>>>> Since a long time I use jersey for webservice. In my case i need
>>>>> to send a request to my WS for reload all the resource.
>>>>>
>>>>> here is the solution i was using (based on conversation on this
>>>>> list called [Jersey] restart a resource ) :
>>>>>
>>>>> I have overriden the servlet container :
>>>>>
>>>>> public class CstlServletContainer extends ServletContainer {
>>>>>
>>>>> public static boolean configured = false;
>>>>>
>>>>> @Override
>>>>>
>>>>> protected void configure(final ServletConfig sc,
>>>>> ResourceConfig rc, WebApplication wa) {
>>>>>
>>>>> super.configure(sc, rc, wa);
>>>>>
>>>>> if (!configured) {
>>>>>
>>>>> final ContainerNotifierImpl cnImpl = new
>>>>> ContainerNotifierImpl();
>>>>>
>>>>>
>>>>> rc
>>>>> .getProperties().put(ResourceConfig.PROPERTY_CONTAINER_NOTIFIER,
>>>>> cnImpl);
>>>>>
>>>>> rc.getSingletons().add(new
>>>>> ContextInjectableProvider
>>>>> <ContainerNotifierImpl>(ContainerNotifierImpl.class, cnImpl));
>>>>>
>>>>> configured = true;
>>>>>
>>>>> }
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>> private static class ContextInjectableProvider<T> extends
>>>>> SingletonTypeInjectableProvider<Context, T> {
>>>>>
>>>>> ContextInjectableProvider(Type type, T instance) {
>>>>>
>>>>> super(type, instance);
>>>>>
>>>>> }
>>>>>
>>>>> }
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> I have a container notifier :
>>>>>
>>>>> public class ContainerNotifierImpl implements ContainerNotifier {
>>>>>
>>>>> private List<ContainerListener> cls;
>>>>>
>>>>> public ContainerNotifierImpl() {
>>>>>
>>>>> cls = new ArrayList<ContainerListener>();
>>>>>
>>>>> }
>>>>>
>>>>> public void addListener(ContainerListener arg0) {
>>>>>
>>>>> cls.add(arg0);
>>>>>
>>>>> }
>>>>>
>>>>> public void reload() {
>>>>>
>>>>> for ( ContainerListener cl : cls) {
>>>>>
>>>>> cl.onReload();
>>>>>
>>>>> }
>>>>>
>>>>> }
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>> And i one of my resource i call the containerNotifier to restart
>>>>> all the singleton resource:
>>>>>
>>>>> @Path("configuration")
>>>>>
>>>>> @Singleton
>>>>>
>>>>> public final class ConfigurationService extends
>>>>> AbstractWebService {
>>>>>
>>>>> @Context
>>>>>
>>>>> private ContainerNotifierImpl cn;
>>>>>
>>>>> // this is simplified here
>>>>>
>>>>> private Response treatIncommingResponse() {
>>>>>
>>>>> cn.reload();
>>>>>
>>>>> }
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>> Now that i have upgraded to jersey 1.4, the call to cn.reload do
>>>>> absolutly nothing.
>>>>> Is this a bug or is there a new way to do so ?
>>>>>
>>>>> thanks
>>>>>
>>>>> Guilhem Legal (Geomatys)
>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> 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
>