[OpenAFS-devel] Q's Java API (JAFS) in the 1.4.x build branch

Marcus Watts mdw@umich.edu
Fri, 11 Jul 2008 13:42:59 -0400


> Date:    Tue, 08 Jul 2008 23:33:48 PDT
> To:      openafs-devel@openafs.org
> From:    Jim Doyle <rockymtnmagic@yahoo.com>
> Subject: [OpenAFS-devel] Q's Java API (JAFS) in the 1.4.x build branch
> 
> I recently discovered that libjafs.so builds out with the default build 
> from the head of the 1.4.x branch. It appears if you got JAVA_HOME in your env 
> path, that configure chases after it and adds it as a build target.
> 
> I was PLEASANTLY suprised to see that not only does it build, but it 
> works (!) with just a few minor bug fixes nonetheless. I was able to 
> traverse my cell and have it dump all the servers, partitions and volume
> information.
> 
> Who is using JAFS?   Who is relying on it?   Who, if anyone, has put time
> into it to maintain it?
> 
> There are a number of design and architectural issues with JAFS that I see
> immediately that I could fix ; provided it isnt being already done by others:
> 
> 1.  hashCode()/equals() is improperly implemented in the current codebase.
> In particular, the signature equals(Object o) must be implemented properly
> and further, hashCode() must ALSO be overriden at the same time to reflect  the
>  object identity rule, as opposed to the default reference identity behavior.  
> I've already fixed this, I'd just need cvs commit privs.
> 
> 2.  The architecture is not suitable for most Java environments because
> attribute values have been too closed coupled to the behavior specific to nativ
> e methods.  Architecturally, the entity classes (Cell, Volume, etc), need to be
>  Serializable POJOs with no behavioural methods - they are just value objects. 
> The "behavioral" methods should be moved to pure Interfaces (i.e. releaseVolume
> (...), createVolume(...)).  A number of concrete classes can then realize these
>  interfaces ; NAMELY:  Proxies for remoting access
> to JAFS via RMI-IIOP, RMI-JRMP, even web methods.   Adapters that implement but
>  hide the specifics of the Java Native Methods glue.   Interceptors that can sh
> im ontop the service interfaces to implement auditing, access control etc. This
>  is classis SOA (service oriented architecture) stuff...
> 
> 3.  If these minor but significant architectural enhancements can be pulled off
>  (at the cost of breaking the "current" JAFS API signatures!), JAFS
> should not only be alot easier to maintain, BUT, should be eminently usable
> by both JFC/Swing UI developers, web developers as well as work with the framew
> orks (EJB3, Spring).  Further, using the classic SOA architecture
> I proposed, it'd not be hard to wrap the JAFS API with a Webservice to
> permit other language bindings (Perl, Ruby, etc).
> 
> 4.  Dump the checked exceptions and use runtime exceptions.
> 
> 5.  Because we dont know how multiple Java threads hitting multiple methods
> on the same _impl object and spawning multiple Pthreads for RX is going
> to behave, it also makes sense to change the JNI methods to use a master
> lock to avoid psychotic thread-mapping/thread safety issues. The master lock ap
> proach is a hack, but its correct at the expense of performance. 
> 
> That said, I'd like to know who out there is already on JAFS and also
> who is depending on the current API for production work.... The proposed
> refactoring will substantially alter the API. 

I looked into jafs -- it had some fairly serious problems
that made it a particularly bad choice for us.  Substantially
altering the API would be a very very good thing.  That having
been said, I'd be very tempted to go almost in the opposite
direction from what you propose.

My problem with the API was with several things:
 * it was way too fond of fetching much more data than
	it needed.
 * it was very picky about the data it fetched being "right"
 * the user management thing welds ka & pt together as "one thing"
 * the security / authentication parts don't work well with
	keytabs, or with future security mechanisms.

In our production environment, we have 100,000's of users, and volumes.
Doing a "pts listentries" or "pts listvldb" even once is painful.
It looked to me like jafs was designed with some sort of small scale
web management tool in mind -- something that could presumably present
drop-down lists of users and volumes, that would change "on the fly"
as volumes or users appeared.  The design choices jafs made to make
that possible were bad choices for our environment.

In more detail, regarding

1. hashCode / equals.  Could you please post a diff?
Do you have test code ?

2. pojo etc.  More on that in just a bit.

3. This is sort of 2.

4. checked/runtime exceptions.  There seems to be a growing belief in
the java world that checked exceptions were a mistake.  Are you just
talking about that, or is there some more specific reason (web services
or whatever) where you think checked exceptions are bad?  Checked or
unchecked, the important part of the exception logic is that it should
permit runtime logic to intelligently distinguish between and separately
handle "out of flow" logic.  How do you propose to do all that?

5. actually, we do know.  Well, mostly.  The underlying afs code has
been designed to work with threads for a *long* time.  The folks who
did the jafs implementation put considerable thought into which methods
were "thread safe".  That having been said, if you dig into the cache
manager part, you'll find there is a global lock for its bits, & there
is certainly plenty of opportunity for there to be weird thread safety
issues.  A global lock is a particularly bad solution for a system which
relies on rpc's to remote services which might not be up.  Do you know
of some more specific case where things screw up?  Can we not just fix
the problems?

Ok, onto pojo etc.  I think it's useful to talk about 3 layers
of service here:
/1/ the actual afs architecture.
/2/ "pojo" java objects
/3/ web services.
The actual afs architecture is very straight-forward; there is a
relatively elegant rpc architecture, and a fairly clean layered notion
of how bits fit together locally.  One of the properties I would like to
see for the JNI interface is that it ought to permit a nearly 1-1 mapping
between JNI calls and the underlying native rpc calls.  The current afs
native code is extremely extensible - that's one of its greatest features.
The JAFS code, because it has wired in notions of how things works,
manages to get in the way of this in almost every way possible.

For "pojo", here we start to get into java philosophy, in a big way.
Some of what what you're talking about here (value objects) is probably
actually highly compatible with my notion of sticking closer to the
native API.  You may also be asking for additional structure, in terms
of getter/setters & so forth, for those value objects.  This is where my
java knowledge runs thin.  Certainly, if you have any code or expertise to
offer here, I and I think others would find this very useful.  I think
it should be possible to layer things about JNI to present a fairly
"pure" friendly java interface to the world, whatever that means.
It may be possible to make that a very thin layer with JNI, or there
may be advantages to making it a distinct separate phase of processing.

Then you go on about RMI, web services, etc.  I don't want to spend too
much time on this, because I think more than anything these shouldn't be
part of openafs/jafs.  Some of the problems that RMI/web services solve
are even the very same problems that openafs handles - the problems
of remote access to services, authorization, etc., those problems are
all common.  The interesting problem for openafs, is that it should be
possible to operate these 2 things: a secure "administration" client
that accepts your credentials, then performs operations on your behalf
using its own superuser credentials, and a "proxy" client that accepts
your credentials, then performs operations "as you".  The former case
can be used for user creation/deletion, etc., the latter could be used
for implementing webdav, file acl management, etc.  I don't think merely
layering RMI or webservices directly on top of openafs is a good idea,
indeed, I can think of a lot of reasons why this is probably a bad thing.
Being able to use RMI or webservices with openafs would be a very good
thing however.

I definitely look forward to seeing more work happen here.

					-Marcus Watts