I need a Java API (Re: XML-RPC interface)

Jack Greenbaum j.greenbaum@computer.org
Sun, 14 Oct 2001 12:29:15 -0700


I've been looking at gnucash for some time as an alternative to Quicken because
Quicken lacks two features. One is the ability to write custom QIF importers
which can modify existing transactions (like clearing an EPMT which has now been
posted to my checking account). The second is that I want to do budgeting in a
different way -- I want a "budget date" field on transactions in addition to the
transaction posted date. The subject of this email relates to the first need, to
write custom importers. The budget feature request is for another time.

The perl script at the bottom of the quoted email below shows driving the gnucash
engine from Perl.. I need Java. The current SWIG development version supports
Java.  So here's the point: I am volunteering to help develop a SWIG-derived Java
interface to gnucash, and examples. Not an XML-RPC driver, an engine driver. This
has nothing to do with network conectivity, web access, or multi-user. It has to
do with writing custom accounting procedures on the GNC engine with Java.

<rant>Java is the most efficient langauge I have found for writing general
purpose programs, and I've already built significant infrastructure for munging
QIF files in Java. Today I use that infrastructure to do most of what I need.
However my life would be much simpler if I could just drive my accounting package
from Java. Not to replace the GUI (BTW: the arguments that "Java GUIs are ugly"
is silly -- there are gtk bindings for Java now so phooey, and you could always
write a GTK look and feel for Sing if you REALLY like Motif), but to add to it.
I'm just not going to write Gnome code/GTK code for the minimal GUI my importer
needs. I don't want to learn yet another system. Furthermore I'm not going to
write in Scheme. I don't have time to use loosely typed languages without
compile-time checking. I don't even bother with C/C++ anymore, directly accessing
memory is an outdated programming model outside of embedded software or
high-perforance needs. What I'm bulding is bigger than glue code. What I want to
do is not reinvent the wheel of accounting data structures and semantic code just
to do some custom importation in Java.</rant>

Is there anyone working on this today? If not then I could use a little support
to get me going on this. From reading gnucash-devel for a couple of months it
seems that to build on the SWIG work already done for perl etc I need to be
building from CVS. My question is are all of the dependencies for gnucash in CVS?
I'm concerned about g-wrap, for example. Is there a "Building GNC from CVS"
How-To so I don't have to figure it all out? (I'm an advanced developer, it isn't
CVS that his the problem, it is all the "Oh yeah, you have to do this" stuff.) If
not I guess I'll be happy to write one, it is always easier to do that as a new
user.

Thanks in advance for the help.

-- Jack Greenbaum

Linas Vepstas wrote:

> On Tue, Sep 25, 2001 at 01:15:00PM -0700, Jeb Bateman was heard to remark:
> > On Tue, Sep 25, 2001 at 02:02:58PM -0500, Linas Vepstas wrote:
> > > The traditional gnucash 'theory' is that the 'correct' programming
> > > interface/API is the 'engine' programming interface.  Part of this
> > > theory is that there are supposed to be 'engine backends' that know how
> > > to communicate with persistent-storage backends.
> >
> > And from a client-side programming perspective, you shouldn't have to
> > worry about which data-store is being used by the backend, right?
>
> Right.  Yuo just nead to know the URI to connect to. The rest is handled
> automagically.
>
> > > There are currently four backends:
> > > -- the file format backend, can save/restore from file.  This is a
> > >    single-user, local-storage backend.
> > > -- the sql backend, can connect to local or remote database, supports
> > >    multiple simultaneous users.  Beta.  Works for me; might have
> > >    scalability or performance problems.
> > > -- the 'rpc' backend.  Uses rpc to talk to remote gnucash server.
> > >    Code exists, but its broken, not currently operational.
> > > -- the 'http' backend.  Uses http to manage connections.  Uses a
> > >    an enhanced version of the XML file format as the actual data
> > >    protocol.  Currently broken by recent file format changes, but it
> > >    used to kinda-work.  (The idea was that http would provide SSL,
> > >    authentication, socket management, state management, permissions,
> > >    etc ... all that communnications-level stuff that apache provides).
> >
> > It sounds like the last two could be combined into an XML-RPC backend,
> > since it inherently runs over HTTP.
>
> Hmmm. Well, that might be the right thing to do then.  I always thought
> that our xml code should have been autogenerated from some kind of
> idl description, instead of being hand-weinered.  However, there's
> no (open source) idl compiler that would do this.
>
> But maybe indeed it would be easier to use xml-rpc than to whack our xml
> code back into having a stream interface.
>
> > > Right.  You could put an XML-RPC interface in front of the engine.
> > > But I think it would suffer serious performance problems.  It would be
> > > nasty to make an rpc call to set the payee, a second one to set the
> > > date, a third one to set the amount... etc.
> >
> > You don't have to make an rpc call for each piece of data.  The client
> > program collects data from the user, and then submits it all at once
> > to the XML-RPC server for processing...
>
> Well, right.  That's what the gnucash 'backend' is (or is supposed to
> be).   You make a bunch of gnucash engine api calls to assemble a transaction.
> There's one very special engine api call called 'xaccTransCommitEdit()'.
> This call invokes the backend 'commit_edit()' routine that is supposed
> to 'marshall' all the data and ship it off to the server.
>
> > > Note also that one of the things that the 'engine' provides
> > > is a 'local cache' of the account data.
> >
> > You mean there is an "engine" for the client side too?
>
> 'too' is the wrong word.
>
> Yes.  What we call the 'engine' is supposed to sit in the client.
> Its 'libgnc_engine.so', and its supposed to be linked by the client.
>
> There's not really any clearly-defined gnucash server, and whether or
> not it would use any pre-existing gnucash code is 'implementation
> dependent'.   For example the 'gnucash sql server' is one and the
> same as the postgres sql server.  Its 100% pure postgres. There
> is 0% gnucash code in there.   None-the-less, its a 'real server',
> allowing multiple connections etc.
>
> In the case of the unfinished rpc and http gnucash servers, we
> were planning on linking to libgnc_engine.so as well, but that's
> an 'implementation issue'.
>
> > What language
> > is it written in?
>
> 100% pure C.
>
> > Is it easy for any language to use this local data
> > cache?
>
> Sort-of. I've used swig to generate perl bindings, and swig should be
> do python bindings as well.  Rob developed g-wrap to provide scheme
> bindings.   Since the engine has an OO-style interface, it should be
> straightforward to wrapper it in java.
>
> > > Note that the 'cache' is not a theory: it actually works with the sql
> > > backend. As far as I know, there are are no bugs or problems with
> > > the cache getting out of sync.
> >
> > Cool.  If it's written and working, that's great; but I suspect it's
> > limited to a single language implementation, which is okay.  (People
> > writing sophisticated clients might want to choose that language to
> > save the work of implementing a cache themselves...)
>
> Well, there are some swig issues, such as converting glib linked lists
> into perl arrays.  But this is a solvable problem.   If you just want to
> open a gnucash data-store and poke around, it works.
>
> #!/usr/bin/perl -w
>
> # gnucash perl demo:
> #
> # This file demonstrates how to open a gnucash file/url and print
> # the names and balances of the top-level accounts in the file.
> # Its a pretty basic demo.
> #
> # use lib '/usr/lib/gnucash/';
> use lib '..';
> use gnucash;
> package gnucash;
>
> die "Usage: $0 <gnucash filename or url>" if $#ARGV < 0;
> print "Will load $ARGV[0]\n";
>
> gnucash::gnc_engine_init(0, $ARGV);
> $session = gnucash::gnc_book_new ();
>
> $rc = gnucash::gnc_book_begin ($session, $ARGV[0], 1, 0);
> if ($rc != 1)
> {
>    $err = gnucash::gnc_book_get_error ($session);
>    print "Could not find $ARGV[0], errrocode=$err\n";
> }
>
> $rc = gnucash::gnc_book_load ($session);
> die "Could not load $ARGV[0]\n" if $rc != 1;
>
> $grp = gnucash::gnc_book_get_group ($session);
> $numacc = gnucash::xaccGroupGetNumAccounts ($grp);
> print "Loaded $numacc accounts\n\n";
>
> for ($i=0; $i<$numacc; $i++) {
>    $acct = gnucash::xaccGroupGetAccount ($grp, $i);
>    $acctname = gnucash::xaccAccountGetName ($acct);
>    $numeric_baln = gnucash::xaccAccountGetBalance ($acct);
>    $baln = gnucash::gnc_numeric_to_double ($numeric_baln);
>    print "\tAccount: $acctname \tBalance: $baln\n";
> }
>
> gnucash::gnc_book_end ($session);
>
> > > I was hopping that you were going to tell me that you had some
> > > explicit plans ....
> >
> > No time at the moment, but I might start taking a look at the backend
> > code and interfaces sometime later, especially after Bill has checked
> > in his initial XML-RPC implementation...
>
> Well,
>
> What I keep trying to say is that most people should *not* look at the
> backends at all.  Its clear that we still need to implement one or two
> more, so that we can really have a generic server.   But ordinary
> 'users' should be coding to the engine api.  The backends are supposed
> to be off-limits, and have a kind-of special relationship with the
> engine.
>
> --linas
>
> --
> pub  1024D/01045933 2001-02-01 Linas Vepstas (Labas!) <linas@linas.org>
>      Key fingerprint = 8305 2521 6000 0B5E 8984  3F54 64A9 9A82 0104 5933
> _______________________________________________
> gnucash-devel mailing list
> gnucash-devel@lists.gnumatic.com
> http://www.gnumatic.com/cgi-bin/mailman/listinfo/gnucash-devel