CellML Discussion List

Text archives Help


[cellml-discussion] Java bindings for CellML API: Discussion of design decisions


Chronological Thread 
  • From: ak.miller at auckland.ac.nz (Andrew Miller)
  • Subject: [cellml-discussion] Java bindings for CellML API: Discussion of design decisions
  • Date: Thu, 28 Dec 2006 16:52:33 +1300

Hi,

I am planning on starting work on the non-CORBA Java bindings for the
official CellML API implementation (http://www.cellml.org/tools/api/) at
some point within the next few weeks.

As I have not done any significant work on the Java binding, there is
still time for changes to the API to be made. I would be keen to get any
feedback from potential users of the API (especially those who currently
have their own CellML API implementation in Java, and would benefit from
being able to access the CellML API).

I have detailed a rough proposal as to how it should be done below.
Please let me know if you disagree with anything in the proposal (I
would also be interested for feedback if you think this would be useful
for you and you would use it). Please also forward this on if you know
of a group working with CellML from Java who isn't on the To: list.

Proposal:
1) The Java API bindings will simply forward calls between Java and the
existing implementation in C++, PCM (Physiome CellML Mapping) (i.e.
there is no plan to write a 100% pure Java implementation).
2) The interface will be defined using Java Native Interface (JNI). The
bindings will target JDK 1.2 (or 1.1?) and earlier. It will attempt to
avoid any non-portable C++ code, although binaries will need to be
recompiled on each platform.
3) The general structure of the API will follow the existing
specification described in the API document
https://svn.physiomeproject.org/svn/physiome/CellML_DOM_API/trunk/interfaces/CellML_APISPEC.idl
and the associated IDL files.
4) The bindings will be generated automatically from the IDL files. The
code that will be written to support this will therefore take an IDL
file as an input, and generate Java and C++ code to bridge between the
existing API implementation and Java. The only code hand-written for the
API will be the bootstrap code, used to get hold of the initial
CellMLBootstrap object.
5) The code generator will be written in Python, extending the existing
omniidl tool that comes with omniORB (http://omniorb.sourceforge.net).
6) The code generator will generate the following outputs:
a) A Java interface file. There will be one public Java interface for
each interface defined in the IDL files.
b) A Java class file (one per interface) 'implementing' the interface.
This class will define all methods as native.
c) A C++ file acting as a Java->C++ bridge. This implements the native
methods in b above, by calling the C++ API for them.
d) A C++ file acting as a C++->Java bridge. This implements the
interfaces defined in the IDL (in the form used by the existing API
implementation), and uses JNI to invoke Java methods on classes
implementing interfaces defined in a.
7) The base of all interfaces in the IDL definition, XPCOM::IObject,
will have a corresponding Java interface (which is distinct from
java.lang.Object), called XPCOM.IObject. This interface will expose
query_interface (which will be renamed to queryInterface in the Java
mapping) and the objid getter on the base object. However, as a special
case, add_ref and release_ref will not be exposed to Java code. The
rationale for this is that add_ref / release_ref are of no use to Java
code, because the bindings will automatically create Java references to
objects, allowing normal Java garbage collection to work as expected
(subject to the caveat that no reference loop involving CellML API
objects should be left around).
8) Because multiple inheritance of classes is not allowed in Java (and
it would cause an explosion in code size if we generated all bindings
for base interfaces on every implementation class). Therefore, where an
interface has multiple base interfaces, the first interface in the list
is selected, and all other base interfaces are not supported by the
binding class. However, a new binding class can be obtained for the same
underlying object using QueryInterface. For example,
MathMLContentContainer inherits both MathMLContentElement and
MathMLContainer. If you have a MathMLContentContainer called cc, and you
want to access getNArguments() on MathMLContainer, you would have to
write
((MathMLContainer)cc.queryInterface("mathml_dom.MathMLContainer")).getNArguments().
10) The concrete implementation of XPCOM::IObject (C++->Java) overrides
java.lang.Object.equals(java.lang.Object) for the the case that the
argument is an XPCOM::IObject. In this case, it performs the comparison
using getObjid() on XPCOM::IObject. Likewise, hashCode is implemented to
hash the objid, and toString to contain the objid. This ensures that
Java data-structures can be used together with CellML API objects.
11) The reference counting system used in the CellML API interacts with
the garbage collection used in Java as follows:
Every Java=>C++ wrapper has an associated strong reference (i.e.
reference count incremented) to the underlying C++ object. This is
stored in a private field. Upon finalisation of the C++
wrapper by the garbage collector, this reference is released.

Every C++=>Java wrapper holds a JNI global reference to the Java
object. This global reference is released from the destructor of the
wrapper. This means that as long as the API holds a reference
to a Java object, it will not be eligible to be garbage collected.
12) The API currently has thread-safety issues if used from multiple
threads (it doesn't use mutexes to protect data structures), so as an
interim solution, users will be advised not to call the API from more
than one thread in Java, unless green-threads are in use.
13) Interface packages will be as follows: module(.module)*. Interface
names will be taken directly from the IDL. For example, the FQN of model
interface will be cellml_api.Model.
14) Implementation classes will take the same name as the interface, but
the package will be prefixed with "impl.".
15) Attributes in the IDL will map to getters (and setters for
non-readonly attributes): The first letter of the name will be up-cased,
with the prefix 'get' or 'set' applied.
For example, the following attribute:
attribute CellMLAttributeString cmetaId;
maps to:
String getCmetaId()
void setCmetaId(String arg);
16) Both UTF16 and UTF8 strings map to java.lang.String, converted as
appropriate. Other basic types map as follows:
PCM IDL Java
uint32_t unsigned long int
uint16_t unsigned short short
uint8_t unsigned char byte
double double double
float float float
17) All sequences in IDL map to the array of the underlying type in Java.
18) Java objects map to wrappers of that object in PCM. PCM objects map
to wrappers of the object in Java.
19) As an exception to 18, Java objects which are wrappers of PCM
objects are unwrapped instead of double wrapped, and likewise for PCM
objects which are wrappers of Java objects.

More than likely, more similar types of rules will become necessary when
I actually start work. If you can think of any now, or see something
that is unclear, please let me know.

Best regards,
Andrew Miller




  • [cellml-discussion] Java bindings for CellML API: Discussion of design decisions, Andrew Miller, 12/28/2006

Archive powered by MHonArc 2.6.18.

Top of page