Hi!
In the company I work for we have some applications using grizzly framework
and recently I've tried to update them from grizzly-1.9.5 to 1.9.18-M2 and
unfortunately (and to say truth, unexpectedly) faced various issues. The
main cause of the problem is the incompatible and AFAIK undocumented
behavior change of the framework (Controller's readThreadCount) but I
wonder that may be we are also doing something in completely
wrong/suboptimal way. Unfortunately documentation is somewhat lacking :-(
So, the issues:
1. After upgrade code perfectly compiles and runs without any warnings.
Unfortunately, application just stops working. It listens to ports and
that's all, it does nothing else. The cause of the problem is
Controller.readThreadCount that is now by default > 0 and this opens a HUGE
can of worms as I'll try to explain below. Setting readThreadCount to 0
makes application work again.
2. This new default behavior with multiple SelectorHandler's and
ReadControllers heavily relies on implementation of Copyable.copyTo method
in SelectorHandler & SelectionKeyHandler. If application provides its own
handlers then in general (if they have instance variables) these handlers
MUST provide their own copyTo implementations. AFAIK this is not documented
anywhere. Apart from this, copyTo (actually Cloner.clone) imposes
additional restriction on implementations.
3. Classes implementing Copyable interface can't have final instance
variables (copyTo will not be able to copy them).
4. Classes implementing Copyable interface can't have default constructor
with the visibility different from public (this includes the case if the
whole class has, say, default visibility). Cloner.clone will fail with
IllegalAccessException because in case of default constructor it only checks
for InstantiationException.
5. Even after fixes to constructors, final variables and copyTo
implementations application will still not work because application's
SelectorHandler is just silently ignored. The main reason (if not the only)
to provide a custom SelectorHandler is to override onAcceptInterest method
to do processing of incoming connections. This is what is showed in all
code samples/tutorials on Grizzly I'm aware of and this is exactly that
doesn't work any more because now accept is done by (hardcoded in
Controller.start()) RoundRobinSelectorHandler and so custom
onAcceptInterest method in provided SelectorHandler is never ever called.
I'd like to here some suggestions about how this all is supposed to work,
what we should change in our apps and any comments & suggestions on this in
general. BTW, it is also not clear why Controller needs _copies_ of
SelectorHandler/SelectionKeyHandler and can't use _one_ instance shared
between threads.
Alexei