Java Forum / General / July 2007
Write once, run anywhere?
JT - 23 Jun 2007 16:46 GMT Here's what I'm pondering today, and I could be totally off track; it wouldn't be the first time.
The JVM is what processes byte-code which is compiled Java code (classes)? Let's say we have two operating systems, x and y. OS x has a way to oh say... open the CD tray. OS y does not. So would a JVM running on x include an implementation of the openCDTray and y would not, or would it be excluded on both since it's not a common function? This would mean that the JVM is an implementation of the base operating system level calls... with me so far...I'm probably off in left field somewhere... but...
Now lets say "Peter Programmer" has been given the assignment of writing a Java GUI that will let the user press a button, and the CD tray will open. How would Peter write this code once and have it run on an OS that does not have an implementation for opening the CD tray, whether by design (ie. a dumb terminal) or not.
Joshua Cranmer - 23 Jun 2007 17:06 GMT > The JVM is what processes byte-code which is compiled Java code > (classes)? Let's say we have two operating systems, x and y. OS x has a [quoted text clipped - 4 lines] > system level calls... with me so far...I'm probably off in left field > somewhere... but... Look in the Java API. Do you see any method named "openCDTray" or anything similar? No. One would have to find a library with the appropriate JNI bindings to run "openCDTray" because it will be assumed that no JVM will have the proper implementation.
> Now lets say "Peter Programmer" has been given the assignment of writing > a Java GUI that will let the user press a button, and the CD tray will > open. How would Peter write this code once and have it run on an OS > that does not have an implementation for opening the CD tray, whether by > design (ie. a dumb terminal) or not. Graceful failure when loading JNI bindings.
howa - 23 Jun 2007 17:14 GMT > Here's what I'm pondering today, and I could be totally off track; it > wouldn't be the first time. i prefer
write once, compiled anywhere
is enough for developers and is performance wise
Jeff Higgins - 23 Jun 2007 18:16 GMT > open. How would Peter write this code once and have it run on an OS that > does not have an implementation for opening the CD tray, whether by design > (ie. a dumb terminal) or not. import CD; public class CDTest { public static void Main(String[] args) { if(CD.supports(MOS)) { CD.openTray(); } } }
Mark Space - 23 Jun 2007 18:57 GMT > (classes)? Let's say we have two operating systems, x and y. > OS x has a way to oh say... open the CD tray. OS y does not. So would > a JVM running on x include an implementation of the openCDTray and y > would not, or would it be excluded on both since it's not a common I'll repeat what Jeff and Josh said. If there's no way to open a CD tray, then there's no way to do it. You might be able locate a utility or library function that does it for you. The java.lang.Runtime object allows you to exec( String ) for the OS to execute. That's a simple way to call an OS dependent feature. If the call fails, you can try a different one that may work on OS y, or just give up and return an error.
If you really have to get down and dirty, there's JNI, which will let you call native code. Break out the C compiler and do it yourself, or locate a library (DLL, SO, etc.) that does what you want.
Then there's "creative laziness." Use Swing. Put up a dialog box telling the user to press the CD eject button and insert the correct disk now. Click ok when done. This works for any OS. ;)
JT - 23 Jun 2007 19:47 GMT >> (classes)? Let's say we have two operating systems, x and y. >> OS x has a way to oh say... open the CD tray. OS y does not. So [quoted text clipped - 15 lines] > telling the user to press the CD eject button and insert the correct > disk now. Click ok when done. This works for any OS. ;) But none of you have really answered my question. Without using the specific case of the CD drawer (which I was only intending as a for-instance), my question boils down to this:
Isn't it true that the JVM has a limited amount of what it can do based on the commonality of all the different platforms. If someone is writing a program, don't they have to know all the places it's going to be running so that they can avoid coding things that just won't work? And if this is true, doesn't it break the mantra of "write once, run anywhere"?
bencoe@gmail.com - 23 Jun 2007 20:09 GMT > >> (classes)? Let's say we have two operating systems, x and y. > >> OS x has a way to oh say... open the CD tray. OS y does not. So [quoted text clipped - 26 lines] > And if this is true, doesn't it break the mantra of "write once, run > anywhere"? This isn't too limiting, noting that most primary features are going to be be common between OS: threading, file IO, sockets, etc. Sure you might not be able to open a CD tray... but you'll be able to do most things you take for granted. And sure, you might be missing certain features depending on the OS this is, however, why Java has libraries such as Swing which provide their own standardized functionality across platforms - Swing isn't OS dependent (although some of its skins do look horrible, but I'm sure this will continue to improve)
Ben.
Karl Uppiano - 23 Jun 2007 20:20 GMT [...]
> But none of you have really answered my question. Without using the > specific case of the CD drawer (which I was only intending as a [quoted text clipped - 5 lines] > so that they can avoid coding things that just won't work? And if this is > true, doesn't it break the mantra of "write once, run anywhere"? Write once, run anywhere refers to writing a Java program, which if it runs on a standard Java VM on Windows, it can be expected to run on a standard Java VM on Solaris, or Macintosh. Certainly if you start using platform-specific extensions, it won't run just anywhere anymore.
With more complex programs, the reality is more like "write once, debug everywhere". But the Java VM does insulate the Java developer from the more capricious variations between operating systems than, say, a C++ developer.
With Java, you can run the same object code (classes or jars) without recompiling, whereas C++ portability (without a VM) requires at least a recompile.
Mark Space - 23 Jun 2007 23:58 GMT > Isn't it true that the JVM has a limited amount of what it can do based > on the commonality of all the different platforms. If someone is > writing a program, don't they have to know all the places it's going to > be running so that they can avoid coding things that just won't work? But this is true of any programming language or machine language. What do you want, magic? Writing a C program for BSD on both Macintosh and FreeBSD, you have to take into account the different drivers and .so libraries which run on each system. There ain't no other way.
The JVM is a finite machine with finite resources. At some point, you are going to go beyond it's capabilities, whether that's opening a CD bay door or opening the space shuttle bay door. Some things are just specific to their environment.
JT - 24 Jun 2007 02:55 GMT >> Isn't it true that the JVM has a limited amount of what it can do >> based on the commonality of all the different platforms. If someone [quoted text clipped - 11 lines] > bay door or opening the space shuttle bay door. Some things are just > specific to their environment. Yes, and I agree with you 100%. When I installed the Sun jdk1.6, it installed both the SDK and JRE. It's the JRE which allows Java programs to run, so this would be the JVM. As such, a JRE for Windows or Mac OS won't work on Linux. The JRE (or JVM) is platform specific. Is this correct? If so, how does a developer know all the platforms that his or her code will one day be running on? It almost seems to me that you have to avoid anything that might be remotely platform (or even PC) specific or else your code could break. But here's another idea. What if your code was written in such a way that before it actually makes a call to an OS level system or command that isn't there, that it would check first? Do Java (and this is a Java forum so I am asking a question specifically to Java programmers) programmers do this as a matter of principle? And if so, how do they accomplish it.
public boolean isCDDriveOpen { if ( can_the_CD_drive_be_opened ) { if ( CD_drive_is_open ) { return true; } else return false; }
or would it be better handled using a try...catch construct?
Jeff Higgins - 24 Jun 2007 03:31 GMT > correct? If so, how does a developer know all the platforms that his or > her code will one day be running on? Who cares? My phone, my toaster, your Solaris. Who's going to write code to answer the toaster?
<http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html> <http://java.sun.com/javase/6/docs/api/>
Jeff Higgins - 24 Jun 2007 03:53 GMT >> correct? If so, how does a developer know all the platforms that his or >> her code will one day be running on? > > Who cares? My phone, my toaster, your Solaris. > Who's going to write code to answer the toaster? On second thought. That sounded kinda nasty. Sorry.
> <http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html> <http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html>
> <http://java.sun.com/javase/6/docs/api/> JT - 24 Jun 2007 04:18 GMT >>> correct? If so, how does a developer know all the platforms that his or >>> her code will one day be running on? [quoted text clipped - 8 lines] > >> <http://java.sun.com/javase/6/docs/api/> Hey, no biggie, although I was wondering why you were pointing me to the API since I do consult it often... In fact, I have the thing bookmarked.
Jeff Higgins - 24 Jun 2007 04:40 GMT > Hey, no biggie, although I was wondering why you were pointing me to the > API since I do consult it often... In fact, I have the thing bookmarked. I guess I was attempting to make the point that if you write to the Application Programming \Interface\ that the Java \Virtual\ Machine will take care of the platform specifics for you.
Except for answering the toaster :} I reckon I'm on my own there :-)
Karl Uppiano - 24 Jun 2007 03:54 GMT >>> Isn't it true that the JVM has a limited amount of what it can do based >>> on the commonality of all the different platforms. If someone is [quoted text clipped - 15 lines] > won't work on Linux. The JRE (or JVM) is platform specific. Is this > correct? Yes. When you install Java on a particular platform, you get the JVM that was designed for it. Sun (or other JVM provider) does the platform-specific adaptations for you (actually for all Java developers in one fell swoop), so you don't have to.
> If so, how does a developer know all the platforms that his or her code > will one day be running on? Sun publishes a list of supported platforms. You don't know which platforms it will run on. It shouldn't matter (very much) as long as you stick to the standard language features and libraries.
> It almost seems to me that you have to avoid anything that might be > remotely platform (or even PC) specific or else your code could break. Yup. I've written complex commercial client and server applications in Java for over 10 years, and with very few notable application-specific exceptions, this has been a very minor problem in practice.
> But here's another idea. What if your code was written in such a way that > before it actually makes a call to an OS level system or command that > isn't there, that it would check first? You have to go outside the standard JVM and Java class libraries to do this. You usually invoke JNI, which calls routines that you write yourself, or that you buy from third-party vendors. Done right, these components would support a variety of platforms, but you (or they) assume the responsibility of continued compatibility with all supported platforms and versions.
> Do Java (and this is a Java forum so I am asking a question specifically > to Java programmers) programmers do this as a matter of principle? And if [quoted text clipped - 9 lines] > > or would it be better handled using a try...catch construct? I think the latter is more common. And as one responder suggested, the default behavior might be to pop up a dialog asking the user to open the CD drive door and click OK if there is no platform support. The application would be none the wiser. Abstraction is where it's at, man. ;-)
Jeff Higgins - 24 Jun 2007 04:07 GMT > check first? Do Java (and this is a Java forum so I am asking a > question specifically to Java programmers) programmers do this as a matter > of principle? And if so, how do they accomplish it. also see src.zip in your JDK home directory
Andrew Thompson - 24 Jun 2007 05:21 GMT ...
>public boolean isCDDriveOpen { I find your constant reference to made up methods/classes to be quite unhelpful in discussing x-plat isssues. As such, I will ignore that for the moment to talk about J2SE and javax methods.
The AppletContext attached to each Applet has a method showDocument(URL) that hopefully changes the web page. I say 'hopefully' because it may or may not work (AppletViewer does not implement it, and some browsers or browser plug-ins block it), and worse is that it returns nothing to indicate success/failure, and does not throw any exceptions when it fails. It is not of any use for data/pages that *must* be displayed.
By contrast, the web start based JNLP API also has a BasicService.showDocument(URL) method. The BasicService is only available to web start applications and applets - attempts to obtain a BasicService instance will *throw* *an* *exception* in code not launched using web start.
Even more handy is that the BS.showDocument() method will *return* *a* *boolean* indicating success or failure to find the local 'default' browser and launch it with the URL.
So, lets come back to your 'isCDDriveOpen' method and presume that the API that provides that functionality is available for Win and *nix flavors, but not Mac (so it is not distributed with the Mac. deployment), and that it is reliable on Windows, but may or may not work on *nix systems.
A try/catch on loading one of the classes of that API at startup should establish if the API is present, further attempts to call classes or methods of the API might check that first, then the isCDDriveOpen() method itself might throw an exception if it is unable to act.
If the API had a method openCDDrive(), you might also throw an exception, but another alternative is to return a boolean, like BS.showDocument().
That being said, there are any number of simple and silly traps programmers can fall into, that make code break on other platforms. E.G.s
// use of platform specific file separators File f = new File(".\\the\\directory\\thefile.txt");
// use of platform specific newline chars. outputStream.write( "The next line\n" );
 Signature Andrew Thompson http://www.athompson.info/andrew/
Mark Space - 24 Jun 2007 06:36 GMT > matter of principle? And if so, how do they accomplish it. > [quoted text clipped - 7 lines] > > or would it be better handled using a try...catch construct? I think to answer this succinctly, "no." Java programmers don't do this. At least, I've seen little evidence of it.
Normally, what happens is one calls OpenCdDrive() and it either succeeds or fails, or throws an exception, according to it's API. That's the normal route.
Occasionally, one does run into API that are a bit different. Java's AudioSystem is like this. It returns a lot of Info objects that you have to sort through to find the correct one you want, which ends up being a lot like your code above. It's pretty much a pain to use too. It does have methods though to by-pass these checks, if you are not particular about the exact object you get back. You can get default audio input and output pretty easily.
Roedy Green - 24 Jun 2007 07:17 GMT >public boolean isCDDriveOpen { > if ( can_the_CD_drive_be_opened ) { [quoted text clipped - 3 lines] > return false; > } The ifs are unbalanced. You would normally write that as:
public boolean isCDDriveOpen { return can_the_CD_drive_be_opened && CD_drive_is_open; }
IntelliJ often offers to "simplify" code like yours into code like mine. See http://mindprod.com/jgloss/intellij.html -- Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Jag - 24 Jun 2007 09:02 GMT How about this (dumb) example?
class AAA { AAA() { System.out.println("AAA"); } }
class Aaa { Aaa() { System.out.println("Aaa"); } }
And in main() AAA a1; Aaa s1;
On Windows, one might give a ClassNotFoundException. On Linux, it would run normally.
UNT, Jag
Lars Enderin - 24 Jun 2007 18:27 GMT JT skrev:
> public boolean isCDDriveOpen { > if ( can_the_CD_drive_be_opened ) { [quoted text clipped - 3 lines] > return false; > } What's wrong with public boolean isCDDriveOpen() { return CD_drive_is_open; } ?
> or would it be better handled using a try...catch construct? Lars Enderin - 24 Jun 2007 18:53 GMT Lars Enderin skrev:
> JT skrev: >> public boolean isCDDriveOpen { [quoted text clipped - 7 lines] > What's wrong with > public boolean isCDDriveOpen() { I was careless. Obviously this is correct: return can_the_CD_drive_be_opened && CD_drive_is_open;
> } > ? > >> or would it be better handled using a try...catch construct? Stefan Ram - 24 Jun 2007 19:30 GMT > return can_the_CD_drive_be_opened && CD_drive_is_open; The Java Code Conventions do not endorse such readable naming.
According to them, names should be written like
»canTheCdDriveBeOpenend«
Now, a human can not read it anymore, but still javac will happily compile it.
I wrote a preprocessor for Java source code, so now - in my precode - I might write this as
»'can the cd drive be opened'«
And the preprocessor will convert it to the above.
The preprocessor is written in Perl 5 and the code actually is
while( $text =~ s{^([^"'\r\n]*(?:(?:"(?:[^"\r\n]|\\")*"|'(?:[^'\r\n]|\\')*')[^"'\r\n]*)*)'([^'\\\r\n][^'\r\n]+)'}{ $1 . camel( $path, $2 ) }gem ){}
with the sub camel defined as follows.
sub camel($$) { my( $path, $text )= @_; $text =~ s{^\043([a-zA-Z])}{uc($1)}ge; { my $sp = chr( 160 ); $text =~ s{,${sp}}{_${sp}}g; $text =~ s{${sp}([a-zA-Z0-9_])}{uc($1)}ge; } { my $sp = chr( 32 ); $text =~ s{,${sp}}{_${sp}}g; $text =~ s{${sp}([a-zA-Z0-9_])}{uc($1)}ge; } if( $text eq 'class' ){ $text = 'class_'; } return $text; }
This is intended to replace
»'abc def'« by »abcDef« and »'#abc def'« or »'Abc def'« by »AbcDef« and »'class'« by »class_« (as a special rule that might be extended to all keywords).
It allows for ' ' to be either the normal space (32) or the non-breaking space (160).
But it will not replace 'a' (because this is only a single character within the single quotes) nor "...'a'..." (because this is used in double quotes), so one can still use the single quote as intended in Java most of the time.
I might even admit for a question mark as in
»'can the cd drive be opened?'«
which could be converted to
»canTheCdDriveBeOpenend$F3$« or so.
Roedy Green - 24 Jun 2007 03:12 GMT >Isn't it true that the JVM has a limited amount of what it can do based >on the commonality of all the different platforms. If someone is >writing a program, don't they have to know all the places it's going to >be running so that they can avoid coding things that just won't work? Yes they are limited by what in commonly supported, but they CAN'T write code that will work one place but not another, unless they use native code/JNI.
This also ensures your code will continue to run on new MS OSes. MS likes to screw up legacy programs. Java run time deals with those challenges for you. You write to the multiplatform standard, and Sun does battle with MS for you to keep your code working on their latest offering. -- Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Arne Vajhøj - 04 Jul 2007 05:04 GMT > But none of you have really answered my question. Without using the > specific case of the CD drawer (which I was only intending as a [quoted text clipped - 6 lines] > And if this is true, doesn't it break the mantra of "write once, run > anywhere"? Java is a very good language for writing stuff that are platform independent so that is truly write once run anywhere.
But Java is not a very good language for writing platform specific stuff including hardware interfacing.
You can obvious not access a feature that does not exist.
The Java API as a consequence of that mostly covers things that are present on all systems.
Arne
Roedy Green - 24 Jun 2007 03:08 GMT >Now lets say "Peter Programmer" has been given the assignment of writing >a Java GUI that will let the user press a button, and the CD tray will >open. How would Peter write this code once and have it run on an OS >that does not have an implementation for opening the CD tray, whether by >design (ie. a dumb terminal) or not. Byte code does not handle that sort of thing, native code does. Native code is prepared only for services that exist in some form everywhere or that can be faked.
For everything else, you the programmer have to write native code. For tips on how, see http://mindprod.com/jgloss/jni.html
I have written some examples:
http://mindprod.com/products1.html#SETCLOCK http://mindprod.com/products1.html#FILETIMES http://mindprod.com/products1.html#MOUSE http://mindprod.com/products1.html#PENTIUM -- Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|