This is the mail archive of the
mailing list for the Cygwin project.
announcing 'Using Win32Java w/ cygwin shell'
- From: Soren A <soren_andersen at fastmail dot fm>
- To: cygwin at cygwin dot com
- Date: Wed, 21 Aug 2002 14:00:17 +0000 (UTC)
- Subject: announcing 'Using Win32Java w/ cygwin shell'
- Newsgroups: gmane.os.cygwin
- Organization: Occasionally Sporadically
A little announcement about some work I've done. It involved a lot of
research and slow plodding progress (subjectively) because I'd not done
any Java until a month ago.
I'll supplement the text below (which is just pasted in from my Web page
) with a couple of additional observations about aspects that I consider
important facts for people to know to let any similar work they may
attempt to not get hung-up.
Java (at least Sun Java 2) has a mechanism called JNI (Java Native
Interface) for including C/C++ functions existing in code written to the
native architecture the JVM is running on. Dong so involves creating
wrappers for each C/C++ function call. These wrapped functions end up in
a compiled DLL.
Underdocumented Fact 1:
Java uses the stdcall calling convention. Therefore the appropriate
gcc/ld switch must be used when building the DLL (mine was written in C)
that is your collection of one or more "wrapped" native function calls.
By default, gcc on Win32 doesn't use stdcall. Most of those who might
try JNI might already be familiar with this issue (more C++ background
than I have?), but I wasn't, so who knows.
Using `info ld' suggests two relevant switches exist:
as well as possibly
I got away with using "--add-stdcall-alias" in my project build. I didn't
use any markup in my code to specify which symbols to export; others will
be familiar with idiomata such as __attribute__((__stdcall__)) to decorate
functions. Advice solicited on this. So anyway I just used
Underdocumented Fact 2:
Is more of a question. I got the impression that Java should be looking in
the directory where the class files it's executing were found for the DLL
to link in at run-time, as well as in all the system PATH locations; but
that doesn't seem to work. The DLL has to go somewhere in the PATH. YMMV.
Finally, this contribution I am attempting to make is just the foundation
for some possible future development. As is the presentation of the
information on my Web site: just a start. Petty criticisms will be
cheerfully >/dev/null. I am primarily posting in order to get my findings
into the archive for the possible future benefit of others who might try
walking down the same path.
Using Sun's Win32 Java executable (java.exe) to run applications invoked
in the Cygwin bash console (like `PNGls' on this site) is problematical.
The trouble is that java.exe, which parses the argument list passed to
it by the system before handing it on to the JVM, is programmed for
native Windows shells but not for the Cygwin shell. It not only doesn't
understand posix path syntax or filesystems, but it also knows nothing
about the Cygwin mount points. And on top of all that, it will regard
any file path names with spaces in them as separate arguments. About the
only thing compatible (with Cygwin) about java.exe is that it doesn't
choke on normal slashes ('/') as the file path separator.
In order to start doing some Java application programming on my system,
I have created a fix for this situation that at least allows me to
invoke a Java program with a list of file name arguments that are
"absolute" or "fully qualified" relative to the top of the Cygwin
filesystem. For the Win32- style letter drive volumes ("A:", "C:", etc.)
cygwin normally mounts them as ‘</someprefix>/DRIVELETTER/’ where
DRIVELETTER is the single volume letter ("a", "b", etc.) and
</someprefix> is by default the string ‘/cygdrive’. Translating such a
path spec by simple Regular Expression (Regex) manipulation is easy to
do, so getting the proper "cygdrive prefix" is the only real trick to
adding in some rudimentary support for Win32Java to learn about Cygwin
As an aside:
Personally I prefer a much shorter string than ‘/cygdrive’ so I use the
string ‘/cdv’ (mnemonically correct: cYGdRIVEvOLUME). It is easy for me
to remember and to type.
Assessment of my results:
Obviously (to those who know ... and have now looked at my code closely
at all...), a far more complete and robust solution would be to create
glue to access all data about the current Cygwin system mount points and
make all necessary translations regardless of what kind of argument is
passed to Java by the bash shell. The functionality to do this with a
single function call is already part of the Cygwin API. Perhaps in the
future this project will be rewritten using that API and linking (using,
again, the JNI mechanism) to cygwin1.dll. The likelihood of that
happening by my hand is probably directly proportional to the level of
interest and support expressed by my fellow hackers.
For the time being, the CygwinShellInterface package I have written
assists my application (j)PNGls in understanding filepathnames passed to
it by Cygwin's bash, so that I don't have to endure the grating
annoyances of using the native Windows shell for this. The usual Java
import mechanism is used to bring the classes of CygwinShellInterface
into the application at compile time, and then more code in the
application uses the data returned by the JNI method at run-time. Due to
quirks in the evolution of this project there is Java code in the PNGls
class that does manipulation of the path specs, that should probably be
moved into CygwinShellInterface thus treating CygwinShellInterface like
the library of broadly applicable re-usable code it is intended to be;
but for now I am done with this little project (famous last words,eh?).
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Bug reporting: http://cygwin.com/bugs.html