Search code examples
springdependency-injectioncometjerseybayeux

Problems injecting a BayeuxService into another class with annotations


I have a web app that is using Bayeux to handle Comet connections. I initialize a BayeuxServer and tie it into Spring annotations and it all works fine, listening on selected channels and responding.

I have a Jersey annotated class and an annotated Bayeux service as shown below. The idea is I wanted to be able to control resources via Rest from an individual web app, and then right after the resource is changed, do a server push via Comet to all other applicable clients to tell them to update their information.

Here is the problem: A Bayeux Service is created when the webapp is deployed, setting up proper channels to listen on and monitoring clients. There should only be one instance of this. When Jersey attempts to use the Bayeux service it creates a whole new service, when it should be using the original one. This new service doesn't have the BayeuxServer properly injected so I can't access client information through it.

It makes since that this should be doable, but I don't seem to understand how to inject these things properly via annotations. Can anyone point me in the right direction?

Jersey Annotated Class:

@Path("JsonTest")
public class JsonTest {

@Context
Request request;
@Context
UriInfo uriInfo;

@Context
ResourceContext resourceContext;

protected final Logger log = Logger.getLogger(getClass());

public JsonTest() {

}

@DELETE
@Path("{id}")
public void deleteJson(@PathParam("id") String id) {
    JsonTestDao.instance.getModel().remove(id);
    log.info("Deleted Json..." + id);
    log.info("New json: " + JsonTestDao.instance.getModel().toString());


    JsonTestService jsonTestService = resourceContext.getResource(JsonTestService.class);
    jsonTestService.sendUpdate();
}
}

BayeuxService:

@Named
// Singleton here didn't seem to make a difference
@Service
public class JsonTestService {

protected final Logger log = Logger.getLogger(getClass());

@Inject
private BayeuxServer bayeux;
@Session
private ServerSession serverSession;

@PostConstruct
public void init() {
    log.info("Initializing JsonTest Bayeux HelloService...");
    log.info("Current sessions are: " + bayeux.getSessions().toString());
}

@Listener("/cometd/JsonTest")
public void jsonTestHandler(ServerSession remote, ServerMessage.Mutable message) {

}

public void sendUpdate() {
    //bayeux.newMessage(); // Need a method that the Jersey class can call to notify changes
    log.info("Bayeux server should be sending an update now...");
}

@PreDestroy
public void destroy() {
    log.info("Destroying JsonTest Bayeux HelloService...");
}

}

Solution

  • See Jersey and spring integration - bean Injections are null at runtime.

    Another question I asked. Both of these stem from the same problem involving properly setting the Jersey dependency and integrating it with spring.