JavaFX8 - Thread task with Guice - java

I'm new (very new) to Guice and JavaFX. I'm building an application that have a thread listening for socket connection and, after an event is received, the thread store value on ObservableArrayList() and the application will notify them to the user.
My problem is how to structure all this behaviour, and how to "share" the ObservableList from the thread and the JavaFX Controller.
I'm reading about Guice that could help to decouple the new creation of an object.
I've tried to setup something, but the #Inject property is null on my runnable task:
Guice Module:
public class AppGuiceModule extends AbstractModule{
#Override
protected void configure() {
bind(EventsDAO.class).toInstance(new EventsDAO());
}
}
EventsDAO (that have the ObservableArrayList )
#Singleton
public class EventsDAO {
private ObservableList<ScheduledEvent> localCache = FXCollections.observableArrayList();
public void addEvent(ScheduledEvent event) {
localCache.add(event);
}
public void removeEvent(ScheduledEvent event) {
this.localCache.remove(event);
}
}
With two this, i in my main i go to create the injector:
#Override
public void start(Stage stage) throws Exception {
Injector injector = Guice.createInjector(new AppGuiceModule());
Platform.setImplicitExit(false);
Thread t = new Thread(new EventsReceiverTask());
t.start();
.....
Now, in the Runnable object, i would to #Inject EventsDAO (to save new events) and #Inject this too in my Controller, adding to localCache a listener (yes localCache is private, i will provide a getter).
The runnable object:
public class EventsReceiverTask implements Runnable {
private static final int port = 4020;
#Inject
EventsDAO eventsDao; // This is null, why not injected ?
private ServerSocket serverSocket;
private Stage notificationStage;
public EventsReceiverTask() {
try {
this.serverSocket = new ServerSocket(port);
this.notificationStage = new Stage();
eventsDao.addEvent(new ScheduledEvent());
} catch (IOException ex) {
Logger.getLogger(EventsReceiverTask.class.getName()).log(Level.SEVERE, null, ex);
}
}
I dont know if this is the correct way to implement a "producer-consumer" in JavaFX, but i have no idea how to share that components, witthout creating tedious getter and setter, with all statics methods.

Your problem shows exactly why it is preferred not to use new in a dependency injected system, when possible.
Injections can only occur when the injection framework is the one creating the objects. When you call new, you are creating them, not the framework.
There are two ways to have Guice create an object for you:
Use injector.getInstance(Foo.class);
You want to use this as little as possible; generally speaking the only place you would use this method is inside your main method. Using this line elsewhere, makes it difficult to track down injections and understand the object graph. From Wikipedia:
With inversion of control, the flow depends on the object graph that is built up during program execution. Such a dynamic flow is made possible by object interactions being defined through abstractions.
Have Guice create your objects for you as injections.
This is exactly what the #Inject annotation does; instruct Guice to create the object for you in your bound classes.
Generally speaking, a class with a name like EventsReceiverTask is not the sort of top level class that you want to be creating in your main method. They have names more like EventService, to which you would inject a Provider<EventsReceiverTask> that is capable of creating new tasks for you, all of which will be injected with your EventsDAO properly.
Side note: you didn't ask about this, but when you do this, in your module:
bind(EventsDAO.class).toInstance(new EventsDAO());
You are overriding the scope of the binding that you attempted to specify with the #Singleton annotation in your class definition. If you want this object to actually be a singleton, you **must also specify the #Singleton binding in your module, e.g.
bind(EventsDAO.class).toInstance(new EventsDAO()).in(Singleton.class);
From the documentation:
If there's conflicting scopes on a type and in a bind() statement, the bind() statement's scope will be used. If a type is annotated with a scope that you don't want, bind it to Scopes.NO_SCOPE.

You never inject the member fields to the task object, so the value is null.
You need something like the inject part below so that Guice actually injects the field value. You might want further refactoring to make this better, but at the most basic level, Guice won't inject the field until you tell it to.
public void start(Stage stage) throws Exception {
Injector injector = Guice.createInjector(new AppGuiceModule());
Platform.setImplicitExit(false);
EventsReceiverTask task = new EventsReceiverTask();
// You need something like this so that Guice injects the members into the object.
injector.injectMembers(task);
Thread t = new Thread(task);
t.start();
....

Related

CDI on Socket Wildfly or SE

I need to make a Server socket in a web application that listen for Asterisk AGI requests but i need to enable CDI injection in the socket, don't know how to do that.
Today i already have this socket working very well, the problem is i can't inject a CDI bean with the socket.
Ex:
class RequestProcessor implements Runnable
{
private Socket socket;
#Inject
private PhoneService phoneService;
#Override
public void run()
{
// Do the logic here
}
}
Method that receives the request and send to a pool.
ExecutorService pool = Executors.newCachedThreadPool();
ServerSocket server = new ServerSocket(25000);
Socket client = server.accept();
pool.execute(new RequestProcessor(client));
It's not the production code, it's just a illustrated example!
I can't make the #Inject PhoneService phoneService works.
As we've already established, newing the RequestProcessor won't populate the #Inject-annotated field since new completely cuts out the DI system. So you need a way to bring it in.
Your goal looks particularly non-trivial because RequestProcessor wants a DI-provided dependency (phoneService) and one that you provide programmatically (socket). As a general rule I would advise against mixing the two where possible – once you're using DI, it wants to spread like a virus. Let that happen. If you can design your system so that (almost) everything is injected for you, that's fanstastic!
That said, your situation is completely workable.
It looks like you have some method in some class which is a potential injection site. Assuming that this unknown class is in fact created by CDI you could #Inject the PhoneService into that class, and then pass it to the RequestProcessor constructor:
public class SomeClass {
#Inject
private PhoneService phoneService;
private void someMethod() {
ExecutorService pool = Executors.newCachedThreadPool();
ServerSocket server = new ServerSocket(25000);
Socket client = server.accept();
pool.execute(new RequestProcessor(client, phoneService));
}
}
Or you could use a factory to create RequestProcessor instances, which will basically have the same effect in the end. You can write this factory by hand, which will look pretty familiar:
public class RequestProcessorFactory {
#Inject
private PhoneService phoneService;
public RequestProcessor createNewProcessor(Socket socket) {
return new RequestProcessor(socket, phoneService);
}
}
then inject an instance of that factory into your class:
public class SomeClass {
#Inject
private RequestProcessorFactory requestProcessorFactory;
private void someMethod() {
ExecutorService pool = Executors.newCachedThreadPool();
ServerSocket server = new ServerSocket(25000);
Socket client = server.accept();
pool.execute(requestProcessorFactory.createNewProcessor(client));
}
}
There's a third way that you can do it, which is similar to Guice's assisted injection. Effectively it just generates that factory implementation for you, if you provide the interface. To my knowledge, CDI does not support this, but there is at least one CDI extension which does.
Happy DI-ing!

How to handle the situation where a bean requires a server call as part of its initialiation

I have the folowing constructor...
#Inject
public EditorPresenter(final EventBus eventBus, final MyView view, final Provider<DataProvider> provider) {
DataProvider provider = provider.get();
provider.getInitData().fire(new Receiver<List<DataElement>>() {
#Override
public void onSuccess(List<DataElement> response) {
LOG.info("seting feed types to {}", response);
EditorPresenter.this.data = response;
}
});
}
This constructor sets the class field data to the values returned in the request factory call.
The problem is this data requires a call to the server and is thus asynchronous.
And this field needs to be set when the constructor returns as other objects/beans depend on it (I'm having subsequent errors that depend on data being initalised).
What is the most efficient and light weight way of handling this scenario with Gin?
I'm hoping that there is something built into GIN that handles this scenario gracefully.
GQuery Promise solves this kind of situations:
Something like:
public void yourMethod(....) {
....
getDataFromServer(provider).then(processData)
.done(new Function() { public void f(){
continueYourFlow();
}})
.fail(new Function() { public void f(){
handleError();
}});
}
protected Promise getDataFromServer(final Provider<DataProvider> provider) {
return new PromiseRF(provider.getInitData());
}
Function proccessData = new Function() { public void f() {
List<DataElement> data = arguments(0);
//do something with your data
}};
should work. If not, just ask!
There is something wrong in your approach. You shouldn't hold all your application waiting for server.
If I understand, some data from server is required before client is initialized. Maybe you should put them in your host page? Or move initialization of presenters to other methods and execute these methods by events.
It might be best to not initialize the rest of your app yet. I'm not sure how your initialization is laid out, but I would not initialize anymore after you inject the instance of your EditorPresenter class.
When your onSuccess call gets triggered, fire an event or call a method that picks up where you would have left off. If you think it will be a while you could throw up a wait screen or some such.

Breaking a local dependency to unit test a void method

I am practicing with mockito, but I am a bit stuck on how to test a method that depends on a call to method in a local object.
See the following example:
public class Worker {
public void work() {
Vodka vodka = new Vodka();
vodka.drink();
}
}
This worker, instead of doing his job, he likes drinking. But I want to add a test to prove that he drinks while he works. But there is no way of doing so, because I must verify that the method drink() is called when the method work is called. I think you agree with me, that this is impossible to test, so I need to break the dependency before starting to test.
Here is my first doubt, what do you think is the best way of breaking such dependency?
If I just change the scope of the vodka object to global, I think would not be good(I don't want to expose it to other parts of the class). I thought about creating a factory, something like this:
public class Worker {
private VodkaFactory vodkaFactory = new VodkaFactory();
public void work() {
Vodka vodka = vodkaFactory.getVodka();
vodka.drink();
}
}
I am not sure if I did break the dependency correctly, but what I want to do now, is test that the method drink() is called when work() is executed.
I tried this with no luck:
#Test
public void
does_the_worker_drink_while_working
() {
VodkaFactory vodkaFactory = mock(VodkaFactory.class);
Vodka vodka = mock(Vodka.class);
Worker worker = new Worker();
worker.work();
when(vodkaFactory.getVodka()).thenReturn(vodka);
verify(vodka,times(1)).drink();
}
I mock the factory and the when will detect that a new Vodka object is created by the factory. But then when I wan to verify that that method calls 1 time the method drink(), mockito tells me:
Wanted but not invoked:
vodka.drink();
-> at testing_void_methods_from_local_objects.WorkerSpecification.does_the_worker_drink_while_working(WorkerSpecification.java:22)
Actually, there were zero interactions with this mock.
I am not stubbing correctly or I am doing something wrong. Could you give me a hand completing this test and also clarify me what would be the best way of testing such untesteable methods?
I know mockito has a method called, doAnswer() which is used to mock a method call,do you think it can be useful in this case?
How should I use it?
UPDATE:
I am following the suggestions to get the when() called before the work() and also I am trying to allow the factory to be set from outside of the class:
#Test
public void
does_the_worker_drink_while_working
() {
VodkaFactory vodkaFactory = mock(VodkaFactory.class);
Vodka vodka = mock(Vodka.class);
Worker worker = new Worker();
when(vodkaFactory.getVodka()).thenReturn(vodka);
worker.work();
verify(vodka,times(1)).drink();
}
This is now the production code now:
public class Worker {
private VodkaFactory vodkaFactory;
public void work() {
Vodka vodka = vodkaFactory.getVodka();
vodka.drink();
}
public void setVodkaFactory(VodkaFactory vodkaFactory) {
this.vodkaFactory = vodkaFactory;
}
The exception that I get is the following:
java.lang.NullPointerException
at testing_void_methods_called_from_local_objects.Worker.work(Worker.java:9)
This is the line that says vodka.drink()
Sorry by I still confused on what is the problem.
Your worker creates his own factory class here:
private VodkaFactory vodkaFactory = new VodkaFactory();
The mock you are creating is completely detached from the worker instance and thus the lack of interaction. To make it work, factory has to be injected to worker from "the outside", say via constructor injection.
If this is legacy code, you could use reflection to replace private factory instance with mocked one.
As noted by JB Nizet in comment, your mock setup comes after work is already called. In order to make things right, inject mock and set it up before you call any code utilizing it.
You need to set your vodkaFactory:
#Test
public void
does_the_worker_drink_while_working() {
VodkaFactory vodkaFactory = mock(VodkaFactory.class);
Vodka vodka = mock(Vodka.class);
Worker worker = new Worker();
when(vodkaFactory.getVodka()).thenReturn(vodka);
//call your setter
worker.setVodkaFactory(vodkaFactory);
worker.work();
verify(vodka,times(1)).drink();
}
It is more comment than an answer. In addition to make factory an injectable dependency, you can also make sure to train your mock when(vodkaFactory.getVodka()).thenReturn(vodka); before interacting with it worker.work();
There is a logical error in the code you are trying to test. Because you have created VodkaFactory instance inside of the Worker class and moreover you have made that field private.
The best solution would be to pass a reference to VodkaFactory from outside of the class.
public class Worker {
private VodkaFactory vodkaFactory;
public void work() {
Vodka vodka = vodkaFactory.getVodka();
vodka.drink();
}
public void setVodkaFactory(VodkaFactory vf) {
vodkaFactory = vf;
}
}
Now, in your #Test you can pass your mocked VodkaFactory instance using setVodkaFactory setter.
The following is a complete JMockit unit test which exercises the Worker#work() method in isolation from the implementation of its Vodka dependency:
#Test
public void workTest(#Mocked final Vodka mockBeverage)
{
new Worker().work();
new Verifications() {{ mockBeverage.drink(); times = 1; }};
}

Passing Multiple objects To Each other

This is a little weird question, I have a GUI class that in the constructor initiates a Logic class that takes care of the processing of the Processing or Logistics in the App then their is a Handler class that contains a bunch of ActionListners KeyListeners that are attached to UI components in the GUI class
In Constructor of both the Logic and Handler class I take in as parameter the GUI class to be able to manipulate the GUI components created in the GUI class from both the Logic and Handler classes
My problem is that The Handler makes use of the Logic class and vise versa (the Logic class uses the Handler class) and thats not really possible with the method I described above, one is instance before the other, one will be null when attempting to use the other.
Example:
public class GUI()
{
this.handler = new Handler(this);
this.logic = new Logic(this);
}
If handler tries to use something in logic then null would be returned.
One way to fix this is to a setter for the handler to take the logic and vise versa but that doesn't seem like the answer to this.
simple:
public class GUI()
{
this.handler = new Handler(this);
this.logic = new Logic(this);
handler.setLogic(logic);
logic.setHandler(handler);
}
I think it is possible just to expose the Handler and Logic in GUI, and let the public access it. By doing so, as your Handler and Logic already have reference to GUI, they can indirectly get access to each other:
class Gui {
private Handler handler;
private Logic logic;
public Handler getHandler() {
return this.handler;
}
public Logic getLogic() {
return this.logic;
}
}
class Handler {
private Gui gui;
public Handler(Gui gui) {
this.gui = gui;
}
public void doSomething() {
// access logic
this.gui.getLogic().doSomeLogic();
}
}
Regarding to "elegance", I don't think the original design of (imho) messy dependencies between component is elegant at all :) So, instead of focusing making such things look "elegant", do some rethinking and possibly you will find everything become much more elegant automatically. :)
Right before your first usage of handler and logic you could put this code snippet
if(handler == null)
this.handler = new Handler(this);
if(logic == null)
this.logic = new Logic(this);

How to have a shared context per top-level process/thread without using InheritableThreadLocal?

I'd like to see if there's a good pattern for sharing a context across all classes and subthreads of a top-level thread without using InheritableThreadLocal.
I've got several top-level processes that each run in their own thread. These top-level processes often spawn temporary subthreads.
I want each top level process to have and manage it's own database connection.
I do not want to pass around the database connection from class to class and from thread to subthread (my associate calls this the "community bicycle" pattern). These are big top-level processes and it would mean editing probably hundreds of method signatures to pass around this database connection.
Right now I call a singleton to get the database connection manager. The singleton uses InheritableThreadLocal so that each top-level process has it's own version of it. While I know some people have problems with singletons, it means I can just say DBConnector.getDBConnection(args) (to paraphrase) whenever I need the correctly managed connection. I am not tied to this method if I can find a better and yet still-clean solution.
For various reasons InheritableThreadLocal is proving to be tricky. (See this question.)
Does anyone have a suggestion to handle this kind of thing that doesn't require either InheritableThreadLocal or passing around some context object all over the place?
Thanks for any help!
Update: I've managed to solve the immediate problem (see the linked question) but I'd still like to hear about other possible approaches. forty-two's suggestion below is good and does work (thanks!), but see the comments for why it's problematic. If people vote for jtahlborn's answer and tell me that I'm being obsessive for wanting to avoid passing around my database connection then I will relent, select that as my answer, and revise my world-view.
I haven't tested this, but the idea is to create a customized ThreadPoolExecutor that knows how to get the context object and use #beforeExecute() to transfer the context object to the thread that is going to execute the task. To be a nice citizen, you should also clear the context object in #afterEXecute(), but I leave that as an exercise.
public class XyzThreadPoolExecutor extends ThreadPoolExecutor {
public XyzThreadPoolExecutor() {
super(3, 3, 100, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new MyThreadFactory());
}
#Override
public void execute(Runnable command) {
/*
* get the context object from the calling thread
*/
Object context = null;
super.execute(new MyRunnable(context, command));
}
#Override
protected void beforeExecute(Thread t, Runnable r) {
((MyRunnable)r).updateThreadLocal((MyThread) t);
super.beforeExecute(t, r);
}
private static class MyThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
return new MyThread(r);
}
}
private class MyRunnable implements Runnable {
private final Object context;
private final Runnable delegate;
public MyRunnable(Object context, Runnable delegate) {
super();
this.context = context;
this.delegate = delegate;
}
void updateThreadLocal(MyThread thread) {
thread.setContext(context);
}
#Override
public void run() {
delegate.run();
}
}
private static class MyThread extends Thread {
public MyThread(Runnable target) {
super(target);
}
public void setContext(Object context) {
// set the context object here using thread local
}
}
}
the "community bicycle" solution (as you call it) is actually much better than the global (or pseudo global) singleton that you are currently using. it makes the code testable and it makes it very easy to choose which classes use which context. if done well, you don't need to add the context object to every method signature. you generally ensure that all the "major" classes have a reference to the current context, and that any "minor" classes have access to the relevant "major" class. one-off methods which may need access to the context will need their method signatures updated, but most classes should have the context available through a member variable.
As a ThreadLocal is essentially a Map keyed on your thread, couldn't you implement a Map keyed on your thread name? All you then need is an effective naming strategy that meets your requirements.
As a Lisper, I very much agree with your worldview and would consider it a shame if you were to revise it. :-)
If it were me, I would simply use a ThreadGroup for each top-level process, and associate each connection with the group the caller is running in. If using in conjunction with thread pools, just ensure the pools use threads in the correct thread group (for instance, by having a pool per thread group).
Example implementation:
public class CachedConnection {
/* Whatever */
}
public class ProcessContext extends ThreadGroup {
private static final Map<ProcessContext, Map<Class, Object>> contexts = new WeakHashMap<ProcessContext, Map<Class, Object>>();
public static T getContext(Class<T> cls) {
ProcessContext tg = currentContext();
Map<Class, Object> ctx;
synchronized(contexts) {
if((ctx = contexts.get(tg)) == null)
contexts.put(tg, ctx = new HashMap<Class, Object>());
}
synchronized(ctx) {
Object cur = ctx.get(cls);
if(cur != null)
return(cls.cast(cur));
T new_t;
try {
new_t = cls.newInstance();
} catch(Exception e) {
throw(new RuntimeException(e));
}
ctx.put(cls, new_t);
return(new_t);
}
}
public static ProcessContext currentContext() {
ThreadGroup tg = Thread.currentThread().getThreadGroup();
while(true) {
if(tg instanceof ProcessContext)
return((ProcessContext)tg);
tg = tg.getParent();
if(tg == null)
throw(new IllegalStateException("Not running in a ProcessContext"));
}
}
}
If you then simply make sure to run all your threads in a proper ProcessContext, you can get a CachedConnection anywhere by calling ProcessContext.getContext(CachedConnection.class).
Of course, as mentioned above, you would have to make sure that any other threads you may delegate work to also run in the correct ProcessContext, but I'm pretty sure that problem is inherent in your description -- you would obviously need to specify somehow which one of multiple contexts your delegation workers run in. If anything, it could be conceivable to modify ProcessContext as follows:
public class ProcessContext extends ThreadGroup {
/* getContext() as above */
private static final ThreadLocal<ProcessContext> tempctx = new ThreadLocal<ProcessContext>();
public static ProcessContext currentContext() {
if(tempctx.get() != null)
return(tempctx.get());
ThreadGroup tg = Thread.currentThread().getThreadGroup();
while(true) {
if(tg instanceof ProcessContext)
return((ProcessContext)tg);
tg = tg.getParent();
if(tg == null)
throw(new IllegalStateException("Not running in a ProcessContext"));
}
}
public class RunnableInContext implements Runnable {
private final Runnable delegate;
public RunnableInContext(Runnable delegate) {this.delegate = delegate;}
public void run() {
ProcessContext old = tempctx.get();
tempctx.set(ProcessContext.this);
try {
delegate.run();
} finally {
tempctx.set(old);
}
}
}
public static Runnable wrapInContext(Runnable delegate) {
return(currentContext().new RunnableInContext(delegate));
}
}
That way, you could use ProcessContext.wrapInContext() to pass a Runnable which, when run, inherits its context from where it was created.
(Note that I haven't actually tried the above code, so it may well be full of typos.)
I would not support your world-view and jthalborn's idea on the count that its more testable even.
Though paraphrasing first what I have understood from your problme statement is like this.
There are 3 or 4 top-level processes (and they are basically having a thread of their own). And connection object is what is diffrenet in them.
You need some basic characteristic of Connection to be set up and done once.
The child threads in no way change the Connection object passe to them from top-level threads.
Here is what I propose, you do need the one tim,e set-up of you Connection but then in each of your top-level process, you do 1) further processing of that Connection 2) keep a InheriatbleThreadLocal (and the child process of your top-level thread will have the modified connection object. 3) Pass these threasd implementing classes. MyThread1, MyThread2, MyThread3, ... MyThread4 in the Executor. (This is different from the other linked question of yours that if you need some gating, Semaphore is a better approach)
Why I said that its not less testable than jthalborn's view is that in that case also you anyway again needs to provide mocked Connection object. Here too. Plus conecptually passing the object and keeping the object in ThreadLocal is one and the same (InheritableThreadLocal is a map which gets passed by java inbuilt way, nothing bad here I believe).
EDIT: I did keep in account that its a closed system and we are not having "free" threads tempring with connection

Categories