Are there any cases where java "platform agnosticism" may fail? - java

I have been using java for long time but this question came to my mind recently and has been troubling me since.
I am aware about some conditions where platform agnosticism may be affected in java world via.
code for interaction with file system
using platform dependent libraries in the code.
Also floating point numbers
Are there any more cases where java platform agnosticism may fail?
Say a case where my file compiled on Solaris may fail to run on RedHat Linux.
Any help on the topic is appreciated.

Platform specific methods such as
Runtime.exec() is platform specific.
Anything under sun.* or com.sun.* may or may not be there, or do the same thing.
Some system properties are supposed to differ based on the system. e.g. There was one application which expected certain vendors which failed when the VM Vendor changed to Oracle. ;)
Anything which depends on System.getenv()
using native libraries

You need to be careful with paths, e.g. using \ and / between Windows and UNIX is asking for trouble. Also, newline may be tricky: Windows is CR+LF, UNIX just CR (if I recall correctly). Java does provide mechanisms to handle such issues, but naive/new developers may miss them.
Also, I believe OS file locking is different, e.g. on Windows you may be blocked/denied access for something which on UNIX you wouldn't be.

Some libraries, which are not platform dependent, use JVM defaults. For example JVM may choose a different cryptography algorithm if you request AES on two machines. In this case you should be more specific when choosing the algorithm, for instance AES/ECB/PKCS5Padding. See Java default Crypto/AES behavior.
So in general, be careful when docs says that there is some default and don't use defaults.

Related

Is it a good idea to always set file.encoding system property in Java?

I think it is a good idea to always set file.encoding system property in Java application.
Suppose I do not set file.encoding. It means that Java will use a platform-dependent default charset (e.g. in String.getBytes), which makes the whole application platform-dependent.
If we set -Dfile.encoding=UTF-8, for example, we guarantee that such calls as String.getBytes work the same in any platform.
Does it make sense?
No, it doesn't necessarily make sense. If you want to read files that have not been created by your own application, on any platform, you'd better leave the file encoding as it is by default, because that's what you'll need to be able to read these files.
And if you read files created by your own applications, or by applications which use a well-known and specified file encoding, then you should simply use this encoding when instantiating your IO readers and writers.
For methods such as String.getBytes() just don't use them, and use String.getBytes(Charset) instead if you want to use a specific encoding instead of the platform's default one.
Conditionally yes. As JB mentioned, using the "platform default" may occasionally help when reading files generated by other local applications (or other remote ones on the same platform if you have a homogeneous server farm).
So, take the choice with care, but in general I'd say do it. The advice to always create your own readers isn't always possible. I believe in general that most things generating files that use extended characters end up using UTF-8 for it.
In the end, because many files are dependent on the choices made outside your control, it's going to come down to testing and customization, but I feel far more comfortable suggesting that you start with UTF-8 and downgrade as necessary than the inverse.
It is not generally a good idea to set the file.encoding System-Property, because this is not a supported configuration option in Java.
That means it may or may not work. Not working can mean Exceptions. To be precise problems of the sort "It works on Java 1.6, it works on Java 1.7 on Windows, BUT it does not work on Java 1.7 on Linux anymore."
The reason behind that is given here:
The "file.encoding" property is not required by the J2SE
platform specification; it's an internal detail of Sun's implementations and
should not be examined or modified by user code. It's also intended to be
read-only; it's technically impossible to support the setting of this property
to arbitrary values on the command line or at any other time during program
execution.
The preferred way to change the default encoding used by the VM and
the runtime system is to change the locale of the underlying platform
before starting your Java program.

Is Java 6's Desktop.browse() likely to be unsupported on any system I'll encounter?

I see the new Desktop class (which I'd like to use for its browse(uri) method) includes checks to verify that it's supported. If I'm distributing my application for multiple operating systems, should I expect that it will sometimes be unsupported, and stick in code like this "Bare Bones Browser Launch" as a fallback method, or would that be extremely rare? Any particular OSes for which I might expect problems?
(I'm distributing for Mac/Win/Solaris/Linux, but feel free to answer about any exceptional OSes if you know something about them.)
You should program defensively.
From How to Integrate with the Desktop Class:
Use the isDesktopSupported() method to determine whether the Desktop
API is available. On the Solaris Operating System and the Linux
platform, this API is dependent on Gnome libraries. If those libraries
are unavailable, this method will return false
(emphasis mine)
I think the point is the reverse, what does Java require an OS to support? They are giving an OS an out, by allowing the JVM implementer to just return false, say it is not supported, and move on, and still be 100% Java compliant (whether or not that is "write once run anywhere" I'll leave to your own evaluation).
Techniques like the Bare Bones Browser Launch or more complicated libraries like BrowserLauncher, will always only work on a limited set of OSs and browsers than what generic code that is made for the general Java standard is going to give you.
So the upshot is, use a technique like the Bare Bones launcher if an OS you are specifically targeting doesn't support Desktop.openURL, but then you will have to write it to specifically work on that OS - there is no reason to think that the technique works for a given OS and a given JVM on that OS, it just represents what we used to have to do to launch a browser prior to Java 6.

Why is Java platform independent in theory and platform dependent in practice?

I know that one of the big things about Java is that it is platform independent in the sense that you can make a Java application and have it run in Windows, Linux, Mac, and so forth, as long as you don't use libraries specific to one OS, and as long as you have a JVM installed for the appropriate OS to interpret things correctly...
However, why can't a normal computer Java program (as in a simple Hello World in Java, for Windows or Linux for example) run just the same in a mobile phone, when mobile phones also have their specific JVM installed to interpret things correctly?
Why is it necessary to change the architecture of the program in some cases, such as Android development, or use Java ME to make applications specific for some general mobile phones?
I know that there are some functions that are related to certain functionalities of the OS, that might not apply in the mobile platforms for example, such as some things related with console, input methods, and so forth, but is this really the only reason that makes things not compatible? If so, why won't a simple application that just declares and initializes an integer variable be able to run across all non-mobile and mobile platforms that have a JVM available?
I am aware of other questions that have been posted before, such as this, but that do not focus the exact point I am aiming for here.
The unit of portability to look at is a class rather than an application. A class that declares and initialises an integer variable will run on all the platforms you describe, and many others too. They understand the same bytecode, even if they do execute it using different mechanisms ranging from bytecode interpreters, to JIT compilation, to Android's Dalvik (which translates JVM bytecode into its own instruction set).
Even if we look beyond a single integer variable, Java that uses "core" functionality will work on most of these devices. There's a great deal of common ground between J2ME, Android and J2SE (and particularly the latter two - J2ME was intended as a cut-down version of the standard Java APIs for devices with limited resources, so less of the standard API is available).
On a Windows/Mac/Linux system, an application is usually something that you explicitly start, use, and - when you're done - tell it to exit. Compare this with, say, an Android phone: the application might be started in response to an event occurring (perhaps an incoming SMS, or a specific type of file downloaded from the web) in which case it needs to know how and why it was started - a simple public static main(String[] args) just doesn't cut it. Once started, the app needs to be aware of events such as "low battery" or "entering standby mode" in order to free up resources or disable CPU-intensive features (such as GPS) that might otherwise drain the battery.
These aren't obscure functions - they're essential to a phone being useful as a phone - so all native applications must handle them.
When Java Code is compiled a byte code(class file) is generated which is independent of the system. This byte code is fed to the JVM (Java Virtual Machine) which resides in the system. Since every system has its own JVM, it doesn't matter where you compile the source code. The byte code generated by the compiler can be interpreted by any JVM of any machine. Hence it is called Platform independent Language.
thanks
Why is Java platform independent in theory and platform dependent in practice?
Remember and clear one thing that only the Java language is platform independent and try to understand the meaning of the sentence. Java is platform independent means the code you have developed using Java can be run on any machine.
When you compile the .java file it generates .class file and it contains bytecode and this bytecode is platform independent you can run it on any machine this is what about platform independency of Java language.
Now you said that it is not in practice so the reason is only Java language is platform independent, but its runtime enviroment, or JVM, is platform dependent, it is written separately for each OS. So we can say the Java language is platform independent, but its runtime environment is platform dependent.
The java language is just one thing but then many other devices such as mobile phones run their own version which is usually a trimmed down version to fit on the device. THese can also occasionally have other proprietary classes to help access the hardware (ie touchscreen). By making separate platforms based off a main one you get much support and a tighter more efficient programming language.
Sun micro systems has released different versions of jdk. one for windows based and another for linux/unix based. When we installed jdk with that we get jvm,jre and javac. Suppose if we write a java program in windows with intel processor which is installed with windows jdk, then the java compiler of that jdk will convert .java file to .class file which contains byte code instructions similar to assembly language code these byte code instructions can be understandable only by jvm. If we take the .class file which is generated in windows o.s and if we run in linux then the jvm of that linux machine internally rewrites your java program by using the approximate 200+ instruction sets which are developed by javasoft people and placed as part of jvm. and the .class file gets executed. So here the point is to concentrate that jdk is platform dependent but .class is not platform dependent it is platform independent because jvm only responsible for running any .class files. Every jdk's jvm internally has predefined instructions sets i.e., approx. 200+.

Is Java completely Platform Independent?

Is Java completely Platform Independent ?
if not then, what care needs to be taken to see that your code written in Java can run on Multi Platforms. Basically it should work on Targeted Platforms like Windows (Various versions), Linux (all flavors), Mac and Solaris.
While in practice, most compiled byte code is platform independent, my experience in my 12 years of developing on the Java platform has taught me that there are still idiosyncrasies from platform to platform.
For example, while developing a Java 1.4 Swing application for PC and MacOSX the behavior of dialogs was different if the parent frame is null.
Another example might be with working with the file system and files in general. The Java API has methods to help shield the developer from differences in path separators (/ vs \). When writing to a file, it important to use the FileWriter API as intended so that return characters and such are generated properly for the platform that it is being written on.
So while the motto is "write once, run anywhere" my experience has been for production envs it is write once, test, everywhere.
As a result, having strong unit and integration tests can help with this, as you can execute those tests on the various platforms you want to distribute your software.
Despite some minor issues here and there, it is cool to see your code running on Linux, Unix, Windows and MacOSX (BSD Unix) using the same JARs.
As djacobson pointed out, the answer is a qualified "yes". For the most part, Java developers don't have to worry about platform dependencies. However, you may run into problems when you're dealing with APIs that handle traditional OS and platform functions.
When dealing with File I/O, for example, it's easy to make your code platform dependent by ignoring the differences between file/path separators across platforms (i.e. using '\' rather than File.separator).
For the most part, yes. Because Java compiles to bytecode that's executed by its virtual machine, it can generally be expected to behave the same way regardless of the system sitting under the virtual machine.
However. Not even virtual machines are immune to bugs. A quick Google search turns up the following, for example:
http://www.ibm.com/developerworks/java/library/j-diag0521.html
Differences in behavior can vary from JVM to JVM. Hopefully you won't end up with code that depends on any of these cases... but careful research is worthwhile to know what the limitations of your infrastructure are.
You problem will not be executing your code, but more likely the assumptions you have to make about file paths, available external commands (if you need them), necessary file permissions and other external factors that don't really fall under the "Java" problem domain. Unless you're planning on using native code (via JNI) extensively, Java will not be your problem, your environment will.
Which brings us back to the old adage: "write once, test everywhere".
Threading priorities is one thing to consider. Other OS like Solaris for example has more thread priorities than windows. So if you are working heavily on multi-threading, OS is something that may affect the program's behavior.
The main thing to be concerned with is UI code, to make sure that it is represented properly on all the platforms you will be running on.
Another source of possible issues is deploying to different app servers. There might be incompatibility issues between them.
Java other than that is platform independent, This is also one of its weaknesses, since you are coding to a common denominator and many features of each individual OS are not available.
There are very few and they should be pretty obvious. like System.getProperty("os.name") is clearly OS dependant or it wouldn't work. The most common one is System.exec() as it calls another application which is on your system, again you should know if the application you are calling works the same on every system or not (unlikely).
Along with the above concerns, the main problem I had was actually building on different platforms, which may not be what your asking, but may be something to watch out for.
OS X is especially guilty of this when using the Apple Distribution of Java (why anyone would want to put out their own packaging of Java I don't know but that is a separate argument, and on OSX i dont think you have a choice but to use their java). The Libraries that you may or may not be relying on are in completely different directories, eg libraries instead of lib if my memory serves me correctly. And the IBM java I think packages Classes in different Jars in some cases. Ridiculous!!
Hope that helps.

Methodology for upgrading OS Kernel

I am looking to get into operating system kernel development and figured my contribution would be to extend the SANOS operating system in order to support JDK 1.6 and 1.7. I have been reading books on operating systems (Tannenbaum) as well as studying how BSD and Linux have tackled this challenge but still am stuck on several concepts.
What is the fastest way to tell what additional system calls I would need to support as SANOS starts more from the bottoms up?
If I have a list of system calls that need to be supported, what is the best way to roll them up if they are similar in nature?
The minimum number of system calls any reasonable *nix style OS should have are (IMHO):
open
close
read
write
fork
exec
waitpid
the first 4 allow you to both provide input to a program and get its output. (Remember on *nix like operating systems stdout is just another file handle as far as the OS is concerned).
The other 3 are the bare minimum needed to start another program and wait for its result. However, it is certain that SanOS already has these since it is already a very functional operating system.
It is entirely possible that the additions you need to make won't need to be done at a kernel level.
EDIT:
As far as what is needed to support a newer JVM, this paragraph from the SanOS site gives a great hint:
You can run the Windows version of Sun
HotSpot JVM under sanos. This is
possible because sanos supports the
standard PE executable format (.EXE
and .DLL files). Wrappers are provided
for the Win32 DLLs like kernel32.dll,
user32.dll, wsock32.dll, etc., as well
as the C runtime library msvcrt.dll. I
have tested sanos with the following
JVMs:
Basically, the JVMs are the standard windows exe files. So you would just need to find out which system calls the referenced dlls make and ensure that they exist and are implemented correctly.

Categories