source: trunk/bindings/java/index.html @ 1822

Revision 843, 14.8 KB checked in by Mark Koennecke, 5 years ago (diff)
  • Renamed package to org.nexusformat, refs #2
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1<HTML>
2<HEAD>
3<TITLE>The NeXus API for Java</TITLE>
4</HEAD>
5<BODY bgcolor=#FFFFFF>
6<p align="center">
7<IMG src="NeXus.gif" WIDTH=597 HEIGHT=90>
8</p>
9<H1>The NeXus API for Java</H1>
10<P>
11<h2>Contents</h2>
12<ul>
13<li>Introduction
14<li><a href="#ack">Acknowledgement</a>
15<li><a href="#install">Installation</a>
16<li><a href="#run">Running Programs</a> with the  NeXus API for Java.
17<li><a href="jnexustut.html">NeXus for Java Programming Tutorial</a>
18<li><a href="#prog">Programming</a> with the NeXus API for Java (for
19 experienced NeXus API Programmers). 
20<li><a href="#lim">Known Limitations</a>.
21<li><a href="#comp">Compiling</a> the NeXus API for Java
22<li><a href="#sup">Support</a>
23</ul>
24</P>
25
26<h2>Introduction</h2>
27<p>
28<a href="http://lns00.psi.ch/Nexus">NeXus</a> is a proposal for a
29common file format for neutron and X-ray scattering. NeXus uses <a 
30 href="http://hdf.ncsa.uiuc.edu/">HDF</a> as its physical file format.
31Since October 2000 a Java NeXus API has been available which supports
32HDF version 4. Since then, the HDF team at NCSA has released a new
33incompatible version of HDF, HDF version 5. This now is version 2 of
34the Java NeXus API which supports both HDF versions.
35As recoding the HDF library in Java was no option the Java
36 API for NeXus (jnexus) was implemented through the Java Native
37 Methods Interface (JNI). This has the consequence that the Java API
38 for NeXus cannot be used in applets as the security restrictions for
39 applets prohibit downloading of shared libraries   and local file
40 access. Applets can use a NeXus Data Server in order to access NeXus
41 files in readonly mode. 
42</p>
43
44<h2><a name="ack">Acknowledgement</a></h2>
45<p>
46This implementation uses classes and native methods from NCSA's Java
47HDF Interface project. Basically all conversions from native types to
48Java types is done through code from the NCSA HDF group. Without this
49code the implementation of this API would have taken much longer. See <a 
50 href="COPYING.NCSA">NCSA's copyright</a> for more information.     
51</p>
52<h2><a name="install">Installation</a></h2>
53<h3>Requirements</h3>
54<p>
55For the binary distribution only a JDK1.1 compatible Java runtime is
56required. Suitable runtime environments for Solaris, Linux and
57Windows32 can be downloaded from <a
58href="http://www.javasoft.com">Sun's Java</a> homepage. This website
59also holds pointers to Java runtime systems for other
60platforms.
61
62</p>
63<p>
64In order to compile the Java API for NeXus the following components
65are required:
66<ul>
67<li>A Java Development Kit 1.1 or better. For downloads see above.
68<li>A C compiler for your platform.
69<li>The HDF libraries version 4.1r3 or better and the HDF-5 libraries,
70newest version available. Both can be downloaded from <a
71href="http://hdf.ncsa.uiuc.edu/">NCSA's HDF</a> homepage.
72<li>A complete copy of the latest
73 <a href="http://sutekh.nd.rl.ac.uk/NAPI"> NAPI sources</a> (including jnexus
74sources).
75</ul>
76</p>
77<h3>Installation under Windows32 (Windows NT, Windows 95, 98, ME)</h3>
78<p>
79<ol>
80<li>Copy the HDF DLL's (*413m.dll) and the file jnexus.dll to a
81directory in your path. For instance C:\Windows\system32.
82<li>Copy the jnexus.jar to the place where you usually keep library
83jar files.
84</ol>
85</p>
86<h3>Installation under Unix</h3>
87<p>
88Two files are needed: the jnexus.so shared library and the jnexus.jar
89file holding the required Java class. Copy them wherever you like and
90see below for instructions how to run programs using jnexus.
91</p>
92
93<h2><a name="#run">Running Programs with the NeXus API for Java</a></h2>
94<p>
95In order to successfully run a program with jnexus the Java runtime
96systems needs to locate two items:
97<ul>
98<li>The shared library implementing the native methods.
99<li>The nexus.jar file in order to find the Java classes.
100</ul> 
101</p>
102<h3>Locating the shared library</h3>
103<p>
104Of course the method for locating a shared library differ between
105systems. Under Windows32 systems the best method is to copy the
106jnexus.dll and the HDF-libarary DLL's into a directory in your
107path. The HDF DLL's have to go there anyway.
108</p>
109<p>
110On a unix system the problem can be solved in three different ways:
111<ul>
112<li>Make your system administrator copy the jnexus.so file into the
113systems default shared library directory (usually /usr/sbin).
114<li>Put the jnexus.so file wherever you see fit and set the
115LD_LIBRARY_PATH environment variable to point to the directory of your
116choice.
117<li>Specify the full pathname of the jnexus shared library on the
118java command line with the
119-Dorg.nexusformat.JNEXUSLIB=full-path-2-shared-library option.
120</ul>
121</p>
122<h3>Locating jnexus.jar</h3>
123<p>
124This is easier: just add the the full pathname to jnexus.jar to the
125classpath when starting java.
126</p>
127<h3>Examples</h3>
128<p>
129A unix example shell script:
130<pre>
131#!/sbin/sh
132java -classpath /usr/lib/classes.zip:../jnexus.jar:. \
133 -Dorg.nexusformat.JNEXUSLIB=../bin/du40/libjnexus.so TestJapi
134 </pre>
135A Windows 32 example batch file:
136<pre>
137set JL=-Dorg.nexusformat.JNEXUSLIB=..\jnexus\bin\win32\jnexus.dll
138java -classpath C:\jdk1.1.5\lib\classes.zip;..\jnexus.jar;. %JL% TestJapi
139</pre>
140</p>
141
142<h2><a name="prog">Programming</a> with the NeXus API for Java.</h2>
143<p>
144The NeXus C-API is good enough but for Java a few adaptions of the API
145have been made in order to match the API better to the idioms used by
146Java programmers. In order to understand the Java -API it is useful to
147study the NeXus C-API because many methods work in the same way as
148their C equivalents. A full API documentation is available in Java
149documentation format. For full reference look especially at:
150<ul>
151<li>The interface <a
152href="apidoc/org.nexusformat.NeXusFileInterface.html">NeXusFileInterface
153</a> first. It gives an uncluttered view of the API.
154<li>The implementation <a
155href="apidoc/org.nexusformat.NexusFile.html">NexusFile</a> which gives more
156details about constructors and constants. However this documentation
157is interspersed with information about native methods which should not
158be called by an application programmer as they are not part of the
159standard and might change in future.
160</ul> 
161Some more general explanation will be given below.
162</p>
163<h3>General Things</h3>
164<p>
165See the following code example for opening a file, opening a vGroup
166and closing the file again in order to get a feeling for the API.
167<pre>
168     try{
169           NexusFile nf = new NexusFile(filename,
170                    NexusFile.NXACC_READ);
171           nf.opengroup("entry1","NXentry");
172           nf.finalize();
173     }catch(NexusException ne) {
174         // oh shit! something was wrong!
175     }
176</pre>
177Some notes on this little example:
178<ul>
179<li>Each NeXus file is represented by a NexusFile object which is
180created through the constructor.
181<li>The NexusFile object takes care of all file handles for you. So
182there is no need to pass in a handle anymore to each method as in
183the C language API.
184<li>All error handling is done through the Java exception handling
185mechanism. This saves all the code checking return values in the C
186language API. Most API functions return void.
187<li>Closing files is tricky. The Java garbage collector is supposed to
188call the finalize method for each object it decides to delete. In
189order to enable this mechanism, the NXclose function was replaced by
190the finalize method. In practice it seems not to be guranteed that the
191garbage collector calls the finalize method. It is safer to call
192finalize yourself in order to properly close a file. Multiple calls to
193the finalize method for the same object are safe and do no harm. 
194</ul>
195</p>
196<h3>Data Writing and Reading</h3>
197<p>
198Again a code sample which shows how this looks like:
199<pre>
200       int idata[][] = new idata[10][20];
201       int iDim[] = new int[2];
202
203        // put some data into iData.......
204
205        // write iData
206        iDim[0] = 10;
207        iDim[1] = 20;
208        nf.makedata("idata",NexusFile.NX_INT32,2,iDim);
209        nf.opendata("idata");
210        nf.putdata(idata);
211
212        // read idata
213        nf.getdata(idata);
214</pre>
215The dataset is created as usual with makedata and opened with
216putdata. The trick is in putdata. Java is meant to be type safe. One
217would think then that a putdata method would be required for each Java
218data type. In order to avoid this the data to write is passed into
219putdata as type Object. Then the API proceeds to analyze this object
220through the Java introspection API and convert the data to a byte
221stream for writing through the native method call. This is an elegant
222solution with one drawback: An array is needed at all times. Even if
223only a single data value is written (or read) an array of length one
224and an appropriate type is the required argument.   
225</p>
226<p>
227Another issue are strings. Strings are first class objects in
228Java. HDF (and NeXus) sees them as dumb arrays of bytes. Thus strings
229have to be converted to and from bytes when reading string data. See a
230writing example:
231<pre>
232        String ame = "Alle meine Entchen";
233        nf.makedata("string_data",NexusFile.NX_CHAR,1,
234                           ame.length()+2);
235        nf.opendata("string_data");
236        nf.putdata(ame.getBytes());
237</pre> 
238And reading:
239<pre>
240        byte bData[] = new byte[132];
241        nf.opendata("string_data");
242        nf.getdata(bData);
243        String string_data = new String(bData);
244</pre>
245The aforementioned holds for all strings written as SDS content or as
246an attribute. SDS or vGroup names do not need this treatment.
247</p>
248<h3>Inquiry Routines</h3>
249<p>
250Let us compare the C-API and Java-API signatures of the getinfo
251routine or method:
252<pre>
253      /* C -API */
254      NXstatus NXgetinfo(NXhandle handle, int *rank, int iDim[],
255                         int *datatype);
256      // Java
257      void getinfo(int iDim[], int args[]);
258</pre>
259The problem is that Java passes arguments only by value, which means
260they cannot be modified by the method. Only array arguments can be
261modified. Thus args in the getinfo method holds the rank and datatype
262information passed in separate items in the C-API version. For
263resolving which one is which consult a debugger or the API-reference. 
264</p>
265<p>
266The attribute and vGroup search routines have been simplified using
267Hashtables. The Hastable returned by <b>groupdir()</b> holds the name
268of the item as a key and the classname or the string SDS as ths stored
269object for the key. Thus the code for a vGroup search looks like this:
270<pre>
271         nf.opengroup(group,nxclass);
272         h = nf.groupdir();
273         e = h.keys();
274         System.out.println("Found in vGroup entry:");
275         while(e.hasMoreElements())
276         {
277            vname = (String)e.nextElement();
278            vclass = (String)h.get(vname);
279            System.out.println("     Item: " + vname + " class: " + vclass);
280         }
281</pre>
282For an attribute search both at global or SDS level the returned
283Hashtable will hold the name as the key and a little class holding the
284type and size information as value. Thus an attribute search looks
285like this in the Java-API:
286<pre>
287         Hashtable h = nf.attrdir();
288         Enumeration e = h.keys();
289         while(e.hasMoreElements())
290         {
291           attname = (String)e.nextElement();
292           atten = (AttributeEntry)h.get(attname);
293           System.out.println("Found global attribute: " + attname +
294             " type: "+ atten.type + " ,length: " + atten.length);
295         }
296</pre>   
297</p>
298<p>
299For more information about the usage of the API routines see the
300reference or the NeXus C-API reference pages. Another good source of
301information is the source code of the  <a href="test/TestJapi.java">test
302program </a> which exercises each API routine.
303</p>
304
305<h2><a name="lim">Limitations</a></h2>
306<p>
307These are a couple of known problems which you might run into:
308<dl>
309<DT>Memory
310<DD>As the Java API for NeXus has to convert between native and Java
311number types a copy of the data must be made in the process. This
312means that if you want to read or write 20MB of data your memory requirement
313will be 40MB! This can be reduced by using getslab/putslab for data
314transfers.
315<DT>Java.lang.OutOfMemoryException
316<DD>By default the Java runtime has a ceiling of 16MB of memory
317use. This ceiling can be increased through the -mxXXm option to the
318Java runtime. An example: java -mx32m ..... starts the Java runtime
319with a memory ceiling of 32MB.
320<dT>Trouble with compressed dataset on True64Unix with jdk118
321<DD>True64Unix's JDK-1.1.8 from HP, Compaq, DEC or however the company
322is called these days is built with a version of zlib incompatible with
323the version used by the HDF libraries. This causes failures to write or read
324compressed datasets when classes are loaded from jar-files. They
325promised to fix this a long time ago but SIGHHHHHHH!  The newer
326JDK-1.3.1 does not exhibit this problem.
327<DT>Maximum 8192 files open.
328<DD>The NeXus API for Java has a fixed buffer for file handles which
329allows only 8192 NeXus files to be open at the same time.  If you ever
330hit this limit, increase the MAXHANDLE define in native/handle.h and
331recompile everything.
332</dl>
333</p>
334<h2><a name="comp">Compiling</a> the Java API for NeXus</h2> 
335<p>
336You will need <li>a complete copy of the latest
337 <a href="http://sutekh.nd.rl.ac.uk/NAPI"> NAPI sources</a> (including jnexus
338sources). See other <a href="#install">requirements</a> under
339 installation above.
340</p>
341<p>
342For Windows32 the free <a href="http://www.borland.com/jbuilder">Borland bcc55
343</a> command line compiler is used. Just run make -fmake.win32 and
344everything will be built. If not, adapt the directory settings in the
345make.win32 file to match your systems configuration. A hint: The import
346libraries for bcc where created from the HDF DLL's with the impdef, implib
347utilities using the -a option. There was a problem with dplicate symbols for
348Hopen, Hclose. This was solved by removing the HOPEN, HCLOSE entries in the
349definition file. This is case sensitivity problem.
350</p>
351<p>
352For DigitalUnix4.0D and Redhat Linux 6.2 Makefiles are provided
353(Makefile and Make.tux repectively). For these systems everything can
354be build with make du40 of make -f make.tux respectively. 
355If the Makefiles do not work edit the
356directory paths in the configuration section to match your
357installation. If you wish to compile on another unix system, create a
358copy of one of the above mentioned Makefiles and edit the
359configuration section in your copy to match your installation of java
360and the HDF libraries. If you succeed in building the NeXus API for
361Java on a new system, please put back modified sources into the CVS
362repository and make your Makefile and the compiled shared library
363available to the NAPI team in order to provide a new binary
364distribution.   
365</p>
366<h2><a name="sup">Support</a></h2>
367<p>
368I'am sure this software contains swarms of bugs. If you manage to find
369one you may send requests either to the <a
370href="mailto:napi@isis.rl.ac.uk">NAPI developer mailing list </a> or
371to <a href="mailto:Mark.Koennecke@psi.ch">Mark K&ouml;nnecke</a> who
372 wrote the Java API for NeXus.   
373</p>
374<hr>
375<p>
376Author:<br>
377Mark K&ouml;nnecke<br>
378Laboratory for Neutron Scattering<br>
379Paul Scherrer Institut<br>
380CH-5232-Villigen-PSI<br>
381Switzerland<br>
382and the NeXus Design team.<br>
383Last Update: November, 22, 2002
384<p>
385</BODY>
386</HTML>
Note: See TracBrowser for help on using the repository browser.