I am working on a JavaFX Application that starts an embedded Jetty server to listen for network requests. I have a use case where I need to respond to normal HTTP request as well as WebSockets. As the stage is controlled by these requests, I have a manager class that takes over control of the stage from the base Application class. To illustrate, here is the Application class:
public class ServerApplication extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
Log.InitLogger("subject server", Level.ALL);
DBServer.StartServer();
final LoginManager manager = new LoginManager(primaryStage);
final ResourceConfig rc = new ResourceConfig().register(
new AbstractBinder() {
@Override
protected void configure() {
bind(manager).to(SService.class);
bind(manager).to(DCS.class);
}
});
Server server = new Server(rc);
server.start();
manager.showLoginScreen();
}
}
Here's the server class's constructor:
public Server(final ResourceConfig rc) throws ServletException, DeploymentException, IOException {
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
jettyServer = new Server(65534 );
jettyServer.setHandler(context);
ServerConnector connector = new ServerConnector(jettyServer);
ServerContainer serverContainer = WebSocketServerContainerInitializer.configureContext(context);
serverContainer.addEndpoint(Socket.class);
jettyServer.addConnector(connector);
final ServletHolder jerseyServlet;
if(rc == null) {
jerseyServlet = context.addServlet(ServletContainer.class, "/*");
jerseyServlet.setInitParameter("jersey.config.server.provider.packages", SUBJECT_REST_PACKAGES);
}
else {
rc.packages(REST_PACKAGES);
jerseyServlet = new ServletHolder(new ServletContainer(rc));
context.addServlet(jerseyServlet, "/*");
}
jerseyServlet.setInitOrder(0);
// Tells the Jersey Servlet which REST service/class to load.
jmDNS = JmDNS.create(InetAddress.getLocalHost());
serviceInfo = ServiceInfo.create("_http._tcp.local.", "Service", 65534, "Ready");
}
For the classes defined in my REST_PACKAGES, HK2 works successfully and resolves the bindings. However, I'm running into issues with the websocket class and dependency injection. I found this post: EnityManager Injection via HK2 in WebSockets, which almost works, but when the WebSocket is instantiated, I get an error int that HK2 can't resolve the DCSService class, which is what the socket needs. So my question is if there is a way to assemble all these technologies, JavaFX, Websockets, Jetty, and HK2 to work together? I know there may be other ways to achieve this, but things like events and pub/sub models don't seem to fit. This seems to be a corner case.
Update, as per request, here's the code for the configurator:
public class MyConfigurator extends Configurator { private ServiceLocator serviceLocator;
public MyConfigurator() {
serviceLocator = ServiceLocatorUtilities.createAndPopulateServiceLocator();
ServiceLocatorUtilities.enableImmediateScope(serviceLocator);
ServiceLocatorUtilities.bind(serviceLocator, new AbstractBinder() {
@Override
protected void configure() {
bind(MySocket.class).to(MySocket.class);
bind(LManager.class).to(DCService.class);
}
});
}
@Override
public <T> T getEndpointInstance(Class<T> endpointClass) {
return serviceLocator.getService(endpointClass);
}
}