|
Jtux — Java-To-UNIX PackagePage Updated 5-Nov-2005
Goals and Non-GoalsJtux is a Java interface to most of the POSIX/SUS system calls. The goals of Jtux are to provide:
Jtux does not:
If you want an object-oriented approach to UNIX facilities that's more in the spirit of Java, you're better off using other Java packages. For example, java.net.Socket, instead of jtux.UNetwork. However, Jtux is the most complete UNIX package for Java or Jython, by a very wide margin. What's in JtuxAs of 23-April-2004, Jtux includes the following 186 calls:
Briefly what we have is all POSIX/SUS calls dealing with files, file systems, directories, sockets, pipes, processes, System V messages/semaphores/shared memory, POSIX messages/semaphores/shared memory, signals, environment, and more. I've tried very hard to be complete; for example, there's not only write, but also pwrite and writev; there's not only send, but also, sendmsg and sendto. Every argument of every function and every field of every structure is supported, except where technically impossible, as noted below under "Design Decisions." See the JavaDoc documentation for more details. Licensing and AvailabilityJtux is distributed as Open Source under the BSD license. Click here to download experimental source code. Building and Installing JtuxAs of 23-April-2003, Jtux has been tested only with Java 1.4.2 on SunOS x86 5.8 (Solaris 8) and on RedHat Linux 9, although it's intended to run on any reasonably up-to-date UNIX, Linux, FreeBSD, or Darwin system. Meanwhile, if you discover any porting problems, please send mail to Marc. On 5-Nov-2005, Jtux was for the first time compiled and tested on OS X 10.4 (Tiger) and with a newer version of gcc (4.0.0), which helped find a few errors in the Jtux C source. I've also included specific instructions for OS X, which appear below. I will prepare a new Jtux archive when I get a chance; meanwhile, you can read the errata here. All of the Java and C (JNI) code is included, but without any makefiles or other build instructions. Here's what you have to do (on Solaris, Linux, and OS X; other systems are different), assuming that the Jtux source tree is in a subdirectory of the current directory named "jtux":
On my Mac, my commands looked like this:
Other Similar WorkJtux is the most ambitious, but by no means the first, attempt to interface Java to POSIX/SUS. Some other packages are listed here. If I've said anything wrong about any of them and you know better, please email me. java-posixhttp://www.honeylocust.com/posix/ This is non-functioning early work on a project that doesn't seem to have been worked on since 1997. Easy Posix Toolkit for Javahttp://www.amug.org/~glguerin/sw/easyposix/overview.html Interfaces to about 40 POSIX calls; implemented for Mac OS X only. Posix for Javahttp://www.bmsi.com/java/posix/package.html Seems to be an attempt to build an object-oriented class hierarchy for POSIX. Difficult to say exactly how much of POSIX/SUS it covers, because it doesn't follow the POSIX/SUS API directly. jnioshttp://sourceforge.net/projects/jnios An interface specifically for Jython, intended to implement the Python modules os and posix. Posix in Java Packagehttp://jan.netcomp.monash.edu.au/java/posix/ Seems to implement about 20 POSIX/SUS calls. Design DecisionsThis section discusses some of the design decisions that were made for Jtux. What to IncludeSUS Version 3 includes 1123 system interfaces. The criteria used to winnow them down for Jtux were:
Also, some work (20 - 30 functions) was postponed until later:
When a function was included, an attempt, usually successful, was made to implement 100% of its functionality. Primitive TypesJava has only eight primitive types, whereas C has an unlimited number via the typedef facility. For a type like, say, pid_t in C, one can go two ways:
Jtux uses the former approach so that calling methods and dealing with fields in structures can be as much like C as possible. During start up, Jtux checks that each of the primitive types it uses as a typedef-type replacement is wide enough for the job. PointersIn most cases where the C API uses a pointer, the Java interface uses a reference, but there are a few places where literally a pointer must be used, such as shmat (which attaches a shared-memory segment). There's not a whole lot one can do with such a pointer in a Java program, but that's not Jtux's problem. So, it simply stores the C pointer in a long. Jtux supplies two non-standard functions, jaddr_to_seg and jaddr_from_seg to copy data between pointers represented as longs and Java byte arrays. StructuresAny C structure named "struct X" becomes a Java class s_X. Each field has the same name as in the C structure. The type of a field is either one of the Java primitive types (see "Primitive Types," above) or the name of a Jtux class. In a few cases POSIX/SUS uses a typedef (e.g., siginfo_t), so the word "struct" doesn't appear, and for these the Jtux class is just the same as the typedef name, without the "s_" in front.. Sometimes in C a field is a pointer to a structure and sometimes it's the structure itself. In Java, of course, it is always a reference to an object. Thus, in the structure addrinfo, the field ai_next, which is of type "struct addrinfo *" in C, becomes type s_addrinfo in Java. UnionsInstead of unions, which Java doesn't have, Jtux uses a base class with subclasses for each member of the union. These are used differently from the way a union would be used in C, but as unions aren't widely used, the differences shouldn't significantly reduce the educational value of Jtux. ConstantsIt isn't possible to initialize Java versions of constants like, say, ENOSYS or O_CREAT with literal numbers because POSIX/SUS doesn't specify actual numbers. Instead, the class UConstant contains 300+ variables that are initialized at start up by calling a Jtux native function that returns the correct value. Error HandlingPOSIX/SUS is all over the map in how it indicates an error (return value of -1, NULL, positive error value, special value, etc.) and how it indicates what the error was (errno, return value, special function call). All of the differences are smoothed out by Jtux and it universally throws a single exception, UErrorException, when an error occurs. All POSIX/SUS errors are considered to be Jtux exceptions, even if it's only access saying the permission doesn't exist or pause returning because it was interrupted. While this is a little cumbersome to program with, it does lead to a simple rule: If it's a POSIX/SUS error, it's always a Jtux exception. NamingIn all cases the name of the Jtux method is identical to the POSIX/SUS function. There are a few Jtux methods that are unique to Jtux (such as jaddr_to_seg, as mentioned above). ArgumentsIn all cases (unless a mistake's been made), the Jtux arguments are identical to the POSIX/SUS arguments, except that the type may be different, as discussed above. This means that all Jtux methods are static. While it would make a lot of sense, say, to define a class for an open file so that the file descriptor wouldn't have to be passed as an argument to each method, this would make the Jtux API different from that of POSIX/SUS, which goes against the goals of the project. Some arguments have no use in Jtux, such as the length of a socket address. These arguments were left in anyway. When a value of a primitive type has to be returned through an argument, the class IntHolder (defined in Jtux) is used. SignalsSignals are the only area where Jtux couldn't implement the POSIX/SUS semantics exactly, because a signal mask can affect only the thread, not the whole process, and the Jtux program may be running on a JVM that's doing multi-threading internally. In other words, you can mask out, say, SIGTERM, but if that signal arrives and another thread has it unmasked, it will be delivered to that thread, and the attempt to mask it will be ineffective. There's no way around this, so you should consider Jtux's implementation of signals to be defective and you should not use Jtux to learn about UNIX signals. The other area where Jtux falls down is in returning a siginfo_t object to a real-time signal handler. It isn't legal for the Jtux implementation to build the Java object in the signal handler (the functions are not async signal safe), so it doesn't. Unfortunately, you'll find that your real-time signal handlers will always get a null reference to the siginfo_t object. Aside from the above, signals do work, and sigaction is fully implemented. ExamplesSocket Communication with Datagrams (Jython) Recursively Descending the Directory Tree (Java) ©2003, 2005 by Marc J. Rochkind. All rights reserved. |