Skip to content

Instantly share code, notes, and snippets.

@jopek
Created May 10, 2013 22:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jopek/5557960 to your computer and use it in GitHub Desktop.
Save jopek/5557960 to your computer and use it in GitHub Desktop.
[11:36pm] ChanServ:
[##gwt] Welcome to the unofficial Google Web Toolkit channel on freenode. This is a starting (and growing) community, and we need your help. Stick around!
[11:37pm] keex:
hello
[11:37pm] keex:
is there a way of injecting a Scheduler ?
[11:38pm] keex:
I now get Rebind result 'com.google.gwt.core.client.Scheduler' cannot be abstract after injecting the scheduler through the contractor...
[11:38pm] keex:
constructor
[11:39pm] keex:
of course, it IS abstract.. but how else do i inject it for internal use?
[11:39pm] keex:
i want to avoid using a GWTTestCase while unit testing
[11:42pm] Obsitos left the chat room. (Ping timeout: 256 seconds)
[11:42pm] niloc132:
what would your scheduler do, exactly?
[11:42pm] niloc132:
how would you implement the end of an event loop, or the next one?
[11:43pm] niloc132:
(also, isn't that "Rebind result xxx cannot be abstract" error something you only get when using GWTTestCases, not real ones?)
[11:44pm] keex:
the scheduler is only used for deferred execution
[11:44pm] keex:
Binder TextBox focus="true" broken: https://code.google.com/p/google-web-toolkit/issues/detail?id=6477
[11:44pm] atomatom:
I'm not sure if this is useful, but I created a mock for Scheduler once when using gwt-test utils https://groups.google.com/forum/?fromgroups=#!searchin/gwt-test-utils-users/scheduler/gwt-test-utils-users/ueCbvdiUaRE/YJIUFLVa594J
[11:44pm] keex:
the exact same case
[11:45pm] keex:
giving a text box focus
[11:45pm] niloc132:
keex: how could TextBox work at all in a non-GWTTestCase, since it needs JSOs anyway
[11:45pm] niloc132:
Element, etc
[11:46pm] niloc132:
it'd make sense if it was already jvm compatible code, but widget is stuck in the non-jvm world thanks to Element and jsni methods
[11:46pm] keex:
in the test cases i would use the StubScheduler
[11:47pm] keex:
niloc132: unfortunately i am not that experienced yet to understand what you are talking about
[11:47pm] niloc132:
the purpose of GWTTestCase is to give the classes a 'browser-like' env to run in
[11:47pm] keex:
yes
[11:47pm] niloc132:
either by compiling to js and running in a browser, or using dev mode
[11:48pm] niloc132:
TextBox can't be used without dev or prod mode - you can't use TextBox in a standard TestCase, since it needs Element, etc to work
[11:48pm] niloc132:
and those need a browser to talk to
[11:48pm] niloc132:
i understand (and agree with) trying to avoid using GWTTestCase in some unit tests, but those tests must exclude all widgets and elements
[11:48pm] niloc132:
there are some mock tools that let you talk *about* a widget, but not actually test the widget itself
[11:49pm] niloc132:
but in those cases things like focus dont actually do anything
[11:49pm] keex:
…which is just what i want
[11:49pm] niloc132:
so you want a mocked TextBox, but insist on having a non-mocked Scheduler inside that TextBox?
[11:49pm] keex:
nonono
[11:49pm] keex:
let me explain
[11:49pm] niloc132:
ok, good :) i was very confused
[11:50pm] keex:
i use gwtp
[11:50pm] keex:
so there is a clear separation of each part: MVP ;)
[11:50pm] keex:
the view holds the textbox
[11:51pm] keex:
and the implementation itself isn't that important
[11:51pm] niloc132:
so far, so good
[11:51pm] keex:
i want the views to be as duuuumb as possible
[11:51pm] keex:
therefore i implement most controlling login inside the presenter
[11:52pm] keex:
the view has a method setFocus()
[11:53pm] keex:
the presenter runs through the lifecycle
[11:53pm] keex:
and when using the scheduler, i want the focus to be set AFTER rendering the textbox
[11:53pm] keex:
that's the basic idea
[11:54pm] keex:
therefore the deferred command is getView().setFocus()
[11:54pm] niloc132:
and the view can't be in charge of those tasks? or the presenter can't say "hey view, render, okay now focus" and the view do nothing?
[11:54pm] keex:
inside the presenter
[11:54pm] niloc132:
or your same mock tool can't mock the scheduler?
[11:54pm] keex:
preferrably not
[11:54pm] keex:
the scheduler CAN be mocked
[11:55pm] keex:
but the Scheduler is abstract
[11:55pm] niloc132:
just as you call @Inject instead of GWT.create to get the gwt out of your presenter code, you can inject the scheduler too
[11:55pm] keex:
thats what i tried
[11:55pm] keex:
crap
[11:55pm] keex:
BRB
[11:55pm] keex:
security is throwing me out the office
[11:55pm] keex:
i'm in very late
[11:55pm] keex:
brb
[11:55pm] niloc132:
haha, ok
[11:59pm] You left the chat by being disconnected from the server.
[12:00am] You reconnected to the server.
[12:00am] You rejoined the room.
[12:00am] ChanServ:
[##gwt] Welcome to the unofficial Google Web Toolkit channel on freenode. This is a starting (and growing) community, and we need your help. Stick around!
[12:02am] niloc132:
welcome back - as i understand reading back on your error, the issue is not in the test, but in getting the gwt stuff to use the real thing - hooking into Scheduler.get() with a provider should help there i think...
[12:04am] keex:
:)
[12:04am] keex:
back
[12:04am] niloc132:
when i say 'real' module, i mean the gin module that the compiled or dev mode app uses
[12:04am] niloc132:
bind(Scheduler.class).toProvider(MySchedulerSingletonProvider.class)
[12:04am] niloc132:
where that provider just returns Scheduler.get()
[12:04am] keex:
ok
[12:05am] niloc132:
i use gin a lot, but i dont use gwtp enough, so i might not be clear on where those boundaries lie
[12:05am] keex:
gwtp is not much different to gwt
[12:05am] keex:
so when it comes to gin it is the same
[12:05am] niloc132:
right, mostly convinient scaffolding around your app
[12:06am] keex:
right
[12:06am] niloc132:
i usually build my own mvp stuff off of just interfaces
[12:06am] keex:
i was thinking of using a SchedulerFactory interface
[12:06am] niloc132:
its lighter when i'm building small apps, but gets too adhoc for big ones, so i should do more with gwtp...
[12:06am] keex:
and binding it in gin "somehow"
[12:06am] niloc132:
that is what the Provider<Scheduler> would do
[12:06am] keex:
oh
[12:06am] keex:
ok
[12:06am] niloc132:
it *must* return the existing gwt scheduler instance
[12:07am] niloc132:
or else the running app will misbehave
[12:07am] niloc132:
by not running finally statements correctly, etc
[12:08am] keex:
so… do i simply inject a Provider<Scheduler> and thats it ?
[12:08am] niloc132:
no, you need the bind.toprovider to wire it up
[12:08am] keex:
yes, that's what i was afraid of ;)
[12:08am] niloc132:
then you can say @Inject Scheduler scheduler; and gin will call on your factory (aka provider) to see about getting the real instance
[12:08am] niloc132:
its the same as your original problem
[12:09am] niloc132:
we need to teach gin how to do @Inject Scheduler
[12:09am] niloc132:
i'll make a quick gist
[12:09am] keex:
yes, i suppose THAT is the essence of my problem
[12:11am] niloc132:
very roughly: https://gist.github.com/niloc132/5557812
[12:11am] niloc132:
not tested in an ide, so it makes sense, but may or may not actually compile
[12:12am] niloc132:
no need to declare as a singleton (unless you want to) since Schduler.get() already returns a singleton
[12:13am] niloc132:
aaand updated https://gist.github.com/niloc132/5557812
[12:13am] niloc132:
two different options, mutually exclusive, should behave the same
[12:13am] niloc132:
depends on your preferences for your gin wiring
[12:14am] keex:
is it necessary to use Provider / Proviedes?
[12:14am] niloc132:
one or the other, yeah, to tell gin that this isn't a typical binding
[12:14am] niloc132:
otherwise you can't point it at Scheduler.get() which has the One True Schduler
[12:14am] keex:
instead of using public class A { public interface A.Factory{ A create(); } }
[12:14am] niloc132:
its kinda like saying on the server "I can just make a new servlet instance and expect it to be init'd correctly"
[12:15am] niloc132:
erm, its the same thing - Provider is essentially the same idea as factory
[12:15am] keex:
i get confused with factories, providers and whatnot...
[12:15am] niloc132:
i think it is a more broad concept, at least thats how i see it
[12:15am] keex:
yes, but why are there solo many names for it?
[12:15am] keex:
ok
[12:16am] niloc132:
you can create a provider<T> and say @Inject T, or you can bind(T).to(...) and say @Inject Provider<T>
[12:16am] niloc132:
or you can do both, or you can do neither
[12:16am] niloc132:
i see assisted inject as closer to 'factory'
[12:19am] keex:
I'll try it out now
[12:19am] niloc132:
reading wikipedia's def of factory pattern, i think a @Provides methods is an abstract factory pattern, same as bind.toProvider - its all about how you create the objects on that side
[12:20am] niloc132:
on the consuming side, *every* 'give me something' call in guice/gin is either @Inject T or @Inject Provider<T> (or assisted inject), and the tool manages the rest of the dependencies
[12:25am] keex:
i like the brevity of option 2
[12:25am] keex:
i'm trying that first ;)
[12:26am] tdebat left the chat room. (Quit: tdebat)
[12:26am] niloc132:
i like brevity, but i also like it when the class is reusable for later projects, and not cluttering up the module
[12:26am] niloc132:
i think i'd go option 2 though too
[12:27am] keex:
the provideScheduler is used INSIDE the module ?
[12:27am] niloc132:
interestingly, yes
[12:27am] keex:
so, how is it used in the using class ?
[12:27am] niloc132:
the @Provides methods are the only one of the module that actually get invoked when the app is running
[12:27am] Essington:
The thing about providers is they help with code splitting ....
[12:28am] niloc132:
if I say @Inject Scheduler s;, gin looks for a scheduler binding, and it finds this rule, so it calls that method to get the instance
[12:28am] niloc132:
AsyncProviders can help with splitting, if used well, but Providers do nothing for splitting (unless inside a splitpoint already i guess)
[12:28am] Essington:
well ...
[12:29am] Essington:
true
[12:29am] Essington:
but if you are already in the mindset of using that pattern, ...
[12:29am] niloc132:
right, that's true
[12:29am] niloc132:
but a scheduler is never something you'd need/want to split
[12:30am] Essington:
right
[12:30am] niloc132:
and the crux of this issue is 'how to i expose core gwt classes as if they were owned by gin/guice'
[12:30am] Essington:
did I mention that I can't be arsed to use my scrollback?
[12:30am] niloc132:
hahaha
[12:30am] keex:
niloc132: I LOVE YOU !
[12:30am] niloc132:
you might've, i didn't scroll back to check
[12:30am] keex:
it works!
[12:30am] niloc132:
glad it worked out keex, go home and sleep ;)
[12:30am] keex:
:D
[12:30am] keex:
i am solo happy right now
[12:31am] Essington:
wait, why would you want to ginject scheduler anyway?
[12:31am] keex:
jenkins will run without a build failure again :)
[12:31am] niloc132:
allow your presenter (which uses it) to be tested in a jvm testcase, not gwttestcase
[12:31am] niloc132:
his use case, not mine
[12:31am] keex:
exactly
[12:31am] Essington:
scheduler does GWT.create()
[12:31am] Essington:
?
[12:31am] niloc132:
jvm test case then can mock it i guess or provide a realish imp
[12:31am] Essington:
huh
[12:32am] niloc132:
impl
[12:32am] niloc132:
Schedule.get() uses GWT.create(SchedulerImpl.class) to get the one true instance
[12:32am] Essington:
already then
[12:33am] niloc132:
the goal is to avoid Scheduler.get() in the presenter (i.e. jvm-able) code, and just use @Inject instead
[12:33am] • Essington
nods
[12:33am] keex:
to recap: the module looks up the methods annotated with @Provides with a certain return value/type and uses THAT first to instantiate the injected classes, right ?
[12:33am] keex:
…inside the module
[12:33am] niloc132:
it builds a bind.toprovider rule out of that method implicitly
[12:33am] niloc132:
right
[12:34am] keex:
haaa :)
[12:34am] niloc132:
so its a matter of style in some cases (and state in others...) whether you bind.toprovider or @Provides
[12:34am] cbrock_ joined the chat room.
[12:35am] cbrock_ left the chat room. (Remote host closed the connection)
[12:35am] keex:
next i will try the bind.toProvider() - some other tme
[12:35am] keex:
time
[12:35am] keex:
are you leavingg the gist up for eternity ?
[12:35am] keex:
or removing it some day?
[12:36am] niloc132:
i'll leave it up forever
[12:36am] keex:
:)
[12:36am] keex:
thank you once again !
[12:37am] niloc132:
np
[12:38am] cbrock left the chat room. (Ping timeout: 276 seconds)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment