Status Report: jini (20-2-2001)
- Got POP3 server up and running
- Helped integrate storage and POP3 server with Sherif and Boris' components
- Began work on SMTP server
- Fixed a few bugs in the POP3 Client.
- Finished working on Setup/Administration.
- Integration Test1 passed successfully :)
- Router now handles events set by lookup services.
- Activation is almost ready.
- We successfully tested integration.
- SMTP server working
- Make TSpaces store things persistently (it's only storing stuff in memory right now)
- Begin work on Fridge
- Still not sure, but we want to make sure our system is stable
coherent before we start working on the fridge.
- Further testing. Preliminary Fridge Implementation
- Finish working on activation for the router.
- Add activation to other components.
- More Testing.
- Add animator to the router.
Deliverables for next tuesdaySummary:
- SMTP server working
- TSpaces storing persistently
- Fridge beginnings
- Initial Fridge Implementation
- Further testing and debugging
- Activatable components that handle events (from lookup services.
- Optimized router.
IanPlease go to my time tracker, click on
"Universal Inbox", and log in as "guest" (no password). (I'll work put
this page on this site in the future.)
SherifIan's time tracker contains my information as well.
BorisIan's time tracker contains my information as
- Running out of memory has been a problem. We get a OutOfMemoryError from the JVM every once in a while. I think this is because of a documented bug where remote objects always have strong references. This bug is fixed in the latest release
- Well this week I don't have a lot to say. Saturday night we were able to
integrate the POP3 Client. Router, Storage and POP3 server and everything
worked just fine. We first had a few difficulties while trying to connect
from MS Outlook
to our POP3 Server and it come out to be a very stupid
bug in my Client but still it took us some time to figure.
- I worked on allowing the user to register to the network, add, delete or
update email accounts from anywhere in the world. My implementation works
correctly but I have decided not to implement it as a Jini service after
reading a few reviews about it being VERY difficult to ensure that the GUI
behaves the same way on different hardware, or even have the same
- I think the memory problem we've been encountering has been fixed in the
JDK 1.3.1 Beta release. According to the SUN website they have fixed the
problem of "Unexported remote objects not getting
- I'm satisfied with the group's performance and think that until now we haven't
failed ourselves once. Whenever we decide to do something we finish it on
time. Good Work Ian and Boris. It's a pleasure working with you guys :)
- OK, I'd like to write a quick java rant and I'm going to do it today
(Wednesday 2/14/2001) while it's still fresh in my mind. <RANT>
Java developers have gone to great lengths to implement many complex features,
yet sometimes the most frequently used objects lack the most basic and obvious
methods or have methods that have inconvenient and unnecessary
limitations. The first time this bugged me was when I was writing some
applet in 143 and I needed to use a function that would take several flags as
its parameters and set them according to what happened inside the
function. Naturally I thought of booleans. Of course I couldn't
use "boolean" since it's a primitive and its value would not persist once I've
left the scope of my function. So I thought I'd use a "Boolean".
To my surprise I've discovered that Boolean does not have mutator functions --
the only time it sets the value is when it's created. And of course I
couldn't set the pointer from outside the function to the newly created
Boolean (inside the function) with the desired value since Java hides
pointers. So, because Java failed to provide such a basic function as
setValue() to such a frequently used class as Boolean (oh and Integer too), I
had to write my own class just for that reason. Why am I bringing this
up now? Weeeeell, while writing the Router, I needed to do something as
common as find a service based on its service ID (given to me in the form of
the String). The 128-bit universally unique service ID -- something so
crucial that it must've taken several meetings by Jini's developers agree on
its format -- had no functions that would permit a developer to set or
instantiate the service ID from a string. The method I thought most
useful for my purposes was constructor that took two longs -- a long
containing 16 most significant digits and a long containing the remaining 16
least significant digits. Determined not to write any redundant code, I
decided to find the needed conversion function in the Long class. The
function parseLong() accepted a string and radix. However, as I found
out the hard way, it would not determine if the value you provided was
positive or negative -- instead it expected the user to pass the value in the
form of -|value|. If you didn't, it threw an invalid number format
exception (or something similar). And the moral of the story is that a
little bit of extra effort in these rather obvious situation and the world
would not have to endure this rant. </RANT>
- I've been encountering a lot of out of memory errors while running Jini
lately. I think part of the reason for that is running browser. It
seems to me like whenever I open a registrar with the browser, it downloads
the classes of all the services running on that registrar and actually creates
VMs for all of them. Since we're typically running browsers every single
time we start anything (and have often have 3 registrars running at the same
time), that's quite a bit of overhead. I could be wrong about
this. In fact I can think of some objections right now -- why would the
browser download remote objects? (perhaps just interfaces) why would it
stick them into separate virtual machines? (don't have a clue) However,
I at a loss to explain why, given that clients of services create multiple
threads, not multiple VMs, we have such a large number of VMs running and run
out of memory so quickly. Though the former is, of course, explains the
- Interesting discovery: two of the miscellaneous classes, described
as useful in the Jini in the Nutshell, appear to have vanished. We
intended to use TaskManager (an animator) and ReliableLog (just what the name
suggests), but when I went looking for their descriptions, I could not find
any mention of them in either Jini 1.1 or Jini 1.0.1. In fact there were
no articles about them or their disappearance on Sun's website. Nor did
they appear on the deprecated list of classes in the documentation. In
my humble opinion this sucks.
- Regarding the above mentioned memory problems... as reason would suggest,
the browser (or the lack thereof) does not seem to impact memory consumption
significantly. Ian believes that Java SDK 1.3's problem with strong
references to remote objects (which creates problems for memory collection) is
to blame. I can see how that would be a problem, but I can't see how
that would be responsible for a case where one user starts the lookup service,
the storage and the router. In this case there can't be any old
references that are wasting memory. Perhaps this is just a heavier load
then we realized... and/or perhaps the memory available to instructional
machine users is more limited then we thought.
- I've spent some time studying activation and, while I don't understand
everything yet, here's what one has to do to a Jini service (according to Jini
in a Nutshell) to make it activatable:
Create activation group description using the properties that include classpath,
codebase, and security policy. Create an instance of ActivationGroupID
using the above mentioned
description. Using the id and group description, create an activation
group (this creates an entry for the group in some rmid registry). Create
an instance of ActivationDesc using the name of the class, codebase, and an
instance of MarshalledObject. Register the service as activatable using
the activation description. Then call getInstance(0) on the created or the
reference to service registration. Exit. *Note: Why we need to
use group stuff (as in ActivationGroupID versus ActivationID) is something I'm
not yet sure of.
Since this is
taking a while, I will cover the rest in far lesser detail.
It seems that a big
part of this activation feature is that the services can deactivate themselves
when they are not used. This has several major consequences in
implementation. First, JoinManager is no longer sufficient because we need
to be able to reactivate and process a discovery of a new lookup service.
So we need to use something like Lookup Discovery Service (fiddler, I think)
provided with Jini. It's an entire service and proper communication with
it can involve some new problems (such as re-synchronizing service hash tables
after a potential missed event). Also, our service of course can't keep
track of leases that need be renewed if it's deactivated. So instead of
lease manager, we have to use Lease Renewal Service (such as sun's norm).
We also have to write some additional support to handle that (although it's a
fairly good deal -- we only have to register with it once a day and even then it
gives us the wake up call. In return the service renews all our leases for
us). Finally, there is some tricky code involved with deactivating oneself
because that should be done only when you're not needed by anyone.
There need to be some work done
with logs. Most important thing to remember is that a definition of a
class we wish to log has become known to us dynamically, we must marshall these
objects (save their codebase).
- One of the main reasons I described all of the above is to justify the
following statement: I don't think we'll need most of it. Most our
services (components of one.box), under typical conditions, will not remain
inactive for more then a few minutes. Given that, I think deactivation
is unjustified. Also, I'm not thrilled about the idea of running
additional heavy services (such as fiddler and norm) under our (possible)
memory constraints. Though what really concerns me about these services
is that recovery of our services would depend on them. So I think that
instead we should simply instantiate JoinManager and LeaseRenewalManager in
the constructor of our activatable class and do a normal discovery procedure
along with registering a ServiceFinderListener (a class we adopted from Jini
in a Nutshell) with the lookup services. I believe that this would
guarantee a good recovery without the unnecessary overhead.
- Final note: when I have more time I'll post some thoughts on Jini
pros and cons in the next report. That should give us additional
material when writing the final report.