What Java Still Can’t Do
It’s hard to believe that more than a decade after Java was released, there are still so many tasks it can’t do. I’m not just talking about things it can’t do well, but about things that you just can’t do without shelling out to native code. Here is a list of tasks that still need native code:
- Firewire
- Raw IP
- ICMP
- Raw Ethernet
- In fact, any networking besides TCP or UDP
- Burn a CD/DVD
- Rip a CD/DVD
- Raw console access; e.g. curses, clear screen, etc. (To be honest this one is so old-fashioned, it shouldn’t be added.)
- Copy or move a file (with all metadata intact)
Isn’t it about time we filled some of these holes? Why has it taken 12 years to add something as basic as copying a file?
What else can you think of?
March 23rd, 2007 at 5:54 pm
Well, I suppose a bare copy or move could be implemented, though in practice you could do it yourself using Process class (you just need to check if you are on Windows or not). For the network stuff, what’s needed is a full implementation of the sockets API.
March 23rd, 2007 at 6:05 pm
I agree all of these would be nice to have. Firewire would be great, and how about USB while we’re at it.
Can you elaborate on what you mean by “raw console access”? java.io.Console is in Java 6, but I haven’t played with it; I’m not sure if it supports character-at-a-time reads, but it handles the common use case of passwords. I doubt it’s up to rendering histograms for Lame.
I don’t expect to see any ripping/burning capability. It seems too complicated to wrap up in a WORA API. But it would be cool.
I’m pretty satisfied with rename and transferTo for copying and moving, but then the last time I confronted a resource fork was around 1989. Is the lowest-common denominator for file meta-data truly “canRead” and “canWrite”? How about “Map> getPermissions()” or something? I guess I shouldn’t complain too much since even my operating system doesn’t allow me to set file permissions correctly (XP Home).
March 23rd, 2007 at 6:07 pm
That was supposed to be “Map<Principal, Set<FilePermission>> getPermissions()”
March 23rd, 2007 at 6:14 pm
There is a Java USB API. I wrote about it in Java I/O. However last I checked it only really worked on Linux.
March 23rd, 2007 at 6:37 pm
One thing Java Still Can’t Do is:
Be all things to all people (i.e. a complete platform).
It’s a parasitic Virtual Machine… for marketing-based benefits.
Gosling and crew made that decision early on… use Native Code for accessing the hardware but define a common (cross platform) API for Java access to hardware.
That way an API for Media could be standardized that might be implemented across Solaris, Windows, OS X and Linux… potentially. It was funded and spec’ed but… had limited take-up.
But “write-once, run anywhere” was problematic at best. Go figure… the only way to come close is to run on a layer of abstractions
and then you get hit with the hardware corner cases. What get connected by Firewire? Video Cameras… which often have proprietary
software to access them or platofmr support via iMovie, example.
Sun made a half-hearted attempt at a Java OS with the JavaStation(s)… but they tried to write one from scratch and ended up with
a lot of peripheral device support headaches and a poor virtual memory manager and scheduler. Go figure. OS’es take a bit of effort to get right… not just a management dictate. And the user always have choice. So, new OS-based devices failure rates is incredibly high.
The fact that Java is still with us and relevant for a variety of computing problems speaks well to Sun’s “stewardship” of the “write-once, run anywhere” dream.
JRuby might get me back into writing something that runs in a JVM… since the GUI choices for Ruby are so limited and poorly documented.
March 23rd, 2007 at 6:55 pm
[...] March 23rd, 2007 One thing Java Still Can’t Do is: [...]
March 24th, 2007 at 7:17 pm
[...] Extending Elliotte’s list, you cannot create a popup window shaped like this: [...]
March 24th, 2007 at 8:56 pm
Those thisng better off from JDK (maybe witht the exception of USB). You are teling as if other language or platforms actually can perform those tasks out of the box, independent from OS..
March 25th, 2007 at 12:13 am
The problem is Java can’t call OS functions directly. Other non-VM languages can. Java doesn’t just replace the language. It replaces the OS, and when Java is missing functionality like USB support, it’s as if the OS can’t handle it.
March 25th, 2007 at 5:48 am
The trouble with all the things you list is that they are all “low down the value stack”. Now, I don’t necessarily agree with that analysis but the trouble is you and I are in the minority. The majority care about better tools, big chunky “do it all for me” frameworks, _not_ having to wade around in the kind of features you list etc.
I wouldn’t say whether this direction is good or bad but it makes it clear why the low-level API’s in the JVM are considerably fewer than one finds in the average OS.
March 25th, 2007 at 12:29 pm
I was waiting for raw sockets for a loooong time. I am guessing that there may be some alternative (non-jdk) libraries, but not sure how they are -
March 25th, 2007 at 3:40 pm
ERH said, “The problem is Java can’t call OS functions directly.”
This is not entirely true. You can call native OS functions using Java Native Interface (JNI). Java classes that access native system resources use JNI interfaces to the native libraries that provide access to the OS system calls. Anyone can access low level system calls if they develop the JNI interfaces. It is true that currently there is no general system call access package in Java, and I believe this is the point ERH was making, but, one could be written. I think the reason that no one has written such a package is that there are few JavaSE or JavaEE-based system level projects/developers. Dan Creswell is right, most Java SE/EE applications do not need access to low level system call interfaces. This may change now that Sun has open-sourced Java. FOSS developers familiar with and desiring low level access may add features that historically have been “down the value stack” and not a priority for the traditional Java platform vendors.
March 25th, 2007 at 7:56 pm
What about video and sound? JMF become out fo date. And Is there another solution ?
March 25th, 2007 at 8:43 pm
It still doesn’t taste any better either.
March 26th, 2007 at 6:59 am
Firewire and usb is supported, there is one API for each one, it’s true that is using JNI , but in fact that capabilities are implemented, and as Chuck Simpson said, you can implement yourself using JNI.
March 26th, 2007 at 7:12 am
so, I suppose you hate the browser as well
because any layer of abstraction will reduce the power of its applications. And the browser (for God sake) is the most terrible abstraction layer I can imagine out there :), ever…..
March 26th, 2007 at 8:14 am
Java can do ICMP to some extent in version 6:
http://java.sun.com/javase/6/docs/api/java/net/InetAddress.html
March 26th, 2007 at 8:41 am
Alex Soto says that FireWire and USB are supported because there’s an API for each one. Wrong on two points: 1, there’s no FireWire JSR. 2, the USB API (JSR-80) is largely unsupported; as Elliotte says, there’s a kind-of-working Linux version, I think there’s a Windows version in some unknown state, and that’s it. No version for Mac, BSD, etc., and it’s not core, so you can’t count on it being present on a user’s machine. Plus, if the answer to any tough problem is “implement it yourself using JNI”, then given the cost of JNI (times however many platforms I care to support), I may be better off dropping Java altogether and doing everything natively. Meaning, it’s not much of an answer at all.
March 26th, 2007 at 9:08 am
what about chmod and chgrp
March 26th, 2007 at 10:03 am
I am just curious–how do you rip a CD in Ruby? C#? C++?
March 26th, 2007 at 11:00 am
I’m a little confused. Once a USB block device is “mounted” and accessible via an OS-supported file path, what more does Java need to support?
Low level hardware access isn’t the point of Java - note that Java doesn’t even support direct memory access, and no one is worse off for that.
Common OS abstractions are as well supported as one might expect. One may complain about the obtuse printing API. But there are other ways to print a document than by directly using the Java print API - PDF anyone?
As for burning a CD, most OSs don’t support that natively - CD burning is typically provided by third party libraries/utilities/applications bundled on top of the OS. So what is the point of this comparison? Those same utilities can be integrated via JNI and provided in Java, if needed.
Raw I/O? Raw ethernet access? Why? If you want that, don’t you want to use C?
More to the point, does ANY interpreted language provide these features - which I suppose is the point you’re trying to make when you say Java, being interpreted, replaces the OS and is more than a language? Why then single out Java?
The whole point of Java is WORA - and it does that exceptionally well, thank you.
March 26th, 2007 at 11:10 am
Not all USB devices are disks. For example, in the latest edition of Java I/O I demonstrated a program that communicates with a USB connected temperature sensor that speaks a custom protocol. While a lot of USB devices are disks, mice, microphones, and other things we don’t need to talk to directly, there are others that aren’t: GPS receivers, laboratory equipment, cable boxes, auto diagnostic tools, etc.
March 26th, 2007 at 11:17 am
Cay,
I don’t know how you rip a CD in C# or C++, but I know you can do it because I’ve seen CD ripping programs written in those languages. No, you can’t do it in standard C, but C#, C++, and C have access to the native APIs and devices in a way Java doesn’t.
JNI doesn’t count. JNI is just a way of talking to C/C++/assembly. A Java programmer who doesn’t know C can’t make use of JNI. The real work is still done in C.
As long as critical tasks like receiving data from laboratory equipment still have to be written in C, Java will be a second-class language. There’s very little if anything you can’t write in C. It’s not the best language for many tasks (maybe not for any) but it’s a good enough language for pretty much all of them. Java still isn’t adequate for a lot of jobs, and twelve years in that surprises me.
March 26th, 2007 at 11:52 am
I think the ncurses support is actually important enough that it should be done. Just because Windows doesn’t have a real terminal doesn’t mean all of the other terminals don’t exist anymore.
I think all you Java-as-OS people are starting to feel the pinch Lispers have dealt with for a few decades: without good integration for the OS, some things Just Can’t Be Done very well.
March 26th, 2007 at 3:20 pm
Well, even though you don’t really want it there is http://sourceforge.net/projects/javacurses/, and it or similar API’s have been around for quite a while.
March 26th, 2007 at 3:22 pm
From your list one can see that you come from the networking/IO corner. Here are some things that a guy who tried to program a text editor really would love to see:
- backwards regex search (do you know why you cannot select the search direction in jEdit when regex search is selected?)
- ability to display the native settings dialog for a printer (there is an API, but it’s not implemented)
- non-rectangular windows
I guess we can agree that there is still plenty to do. Let’s hope people will use the open sourcing of Java to implement the missing features.
March 26th, 2007 at 3:53 pm
“As long as critical tasks like receiving data from laboratory equipment still have to be written in C, Java will be a second-class language.”
Two questions:
1 - If JNI isn’t a good solution, what do you suggest for Java to support “receiving data from laboratory equipment”? And, more important: is there any restriction on the laboratory equipments and OS mix supported by your solution?
2 - What is a second-class language?
March 26th, 2007 at 6:17 pm
I completely agree. If I can’t write what I need in Java, then it doesn’t help me to be able to do it in C/C++/etc. via JNI. I don’t want to learn C/C++ and the special JNI APIs.
And how about printer support, especially on Linux? I can’t believe that people aren’t screaming more loudly about that.
March 26th, 2007 at 6:40 pm
Cay Horstmann:
I have frameworks on the Mac to handle DVD burning and ripping from C++ (Well, Objective-C and Objective-C++) just fine….
March 26th, 2007 at 8:44 pm
Charles,
What I suggest for Java to support receiving data from laboratory equipment is full support for all the plugs on a typical PC as standard parts of the JDK. That means BlueTooth, USB, Firewire, serial, and parallel ports at a minimum. Java doesn’t need to talk these custom protocols of laboratory devices (some of them are pretty weird) but I need to be able to write Java code that does talk to these things over the standard ports.
We actually do have APIs for all the necessary ports except FireWire–that’s why I only included FireWire in my initial list–but they aren’t broadly implemented, and aren’t a standard part of the JDK.
March 26th, 2007 at 8:48 pm
Jan,
Better printer support would be nice. It’s sort of on the edge of what’s possible to do yourself though. You could always fake the GUI. Whether there are any settings you can’t set with the printer is a more serious question. And in these days of IP printers, you could potentially write a pure Java printer driver if you really had to.
Backwards regular expressions you could absolutely write in Java if you wanted to. There were regex engines before
java.util.regex, they still work, and you could always write another.Non-rectangular windows, though, that one can’t be done in Java. I’m unaware of a need for it, but you’re absolutely right that it can’t be done.
March 27th, 2007 at 12:39 am
There’s a good reason why the Java USB API is not supported on Windows. It’s not simply a matter of writing JNI calls that translate Java methods to Windows API calls. The API is for USB RAW I/O. But on Windows, there is no user-mode API for accessing USB devices. That is only possible for Kernel mode drivers. The way Windows expects USB to be used is either the device is one of the standard device classes (mass storage, human interface etc.) or the vendor provides a kernel-model driver that associates itself with the specific device with a specific vendor ID and product ID. That driver would then provide it’s own user mode API. So, long story short, on Windows, you cant just list connected devices and start talking to them, which is what the Java USB API is for. At least, not without installing a special kernel-mode driver.
March 27th, 2007 at 5:12 am
What is peoples problem with Java?! It’s not a native language and it isn’t a replacement for C or C++. Don’t try to make out that it is. I am commercially a Java developer. However, this doesn’t automatically mean I’m against C/C++; in fact the contrary. I’m surprised the people who are supposed to be knowledgeable in the field do not understand the reasons why a particular technology is created. Don’t be so one-dimensional and exploit the benefits of different technologies; no one language cures all computer evils! This is why so many projects fail as the wrong tool is so often used for the wrong reason! To surmise: Java will never be a replacement for C/C++; it has always been this way.
March 27th, 2007 at 6:38 am
Elliot Rusty: of course, using C/C++ you can burn a CD. But not using C# or Ruby. You can do it with .NET only using native access, like JNI.
March 28th, 2007 at 10:26 am
No USB, no Bluetooth, that I’m aware of.
This is a real bummer for desktop applications. Well, Java 6 improved on many things, let’s hope Java 7 well bring even more.
@Dan: no, Java is not C++, but it’s pretty weak to say “oh, just use C++” to people who’d like to build real applications in Java. I think after all those years you should be able to do that, and C++ IMHO isn’t the right thing for many applications, due to its complexity.
Java is no replacement to C, however, because C focuses on very small size, and on systems programming. But Java isn’t claiming to be suited for that purpose in the first place.
March 28th, 2007 at 11:17 am
Gee, it’s almost as if no one language fills all needs. Hard to believe.
March 28th, 2007 at 4:47 pm
The problem isn’t with “Java” it is with JNI. Java does all those things and more when you have unfettered access to the OS API. Microsoft created JDirect to do just that, but Sun sued them out of the Java business for doing it. Fortunately Apple put J/Direct into their Java and so you can do anything you want in Java on Mac OS X, no need for native code, Obective-C or anything else if you don’t want to. A great demonstration of that is NeoOffice. It is a port of OpenOffice to Mac OS X and it uses the Java bindings for the GUI so that it was easier to write and more reliable than using C++.
March 28th, 2007 at 6:39 pm
ICMP would be nice.. I had to shell out to write this: http://www.goldb.org/netplot.html
March 28th, 2007 at 7:46 pm
At first it seemed like you were asking for Java to implement all features of all OSes anywhere in a WORA manner. This is an impossible, and contradictory goal. But I think what you really want is a way to write low level code in Java (when speed is not of the essence), even if it is not WORA. We used to do this in BASIC with PEEK and POKE. The difficulty for Java is that it becomes difficult to keep the “safe” feature of Java programming. As soon as Java can call arbitrary OS functions, security is out the window - so such Java code would have to be specially trusted, just like JNI code. Despite this, low level code in Java can be easier than in C.
Another approach is to forget the WORA, and define specific optional APIs that are not available on all platforms. Imagine “import win32.*;” or “import posix.*;”. Of course, you might as well use .NET as use a win32 API in Java, so scratch that and just do posix. For the really low level stuff like low level USB you need to be even more specific. Like “import linux.*;”.
Java still has value as a medium high level language for low level stuff - especially if you need Java anyway. It is much faster than scripting languages, as fast or faster than C even (but uses a lot more memory than C in the “fast as C” JIT configurations, mainly due to the way the standard library loads everything into memory.)
March 29th, 2007 at 1:08 am
An equivalent of the Unix “ps” and “kill” commands for the JVM would be nice. Maybe for “top” and “vmstat” too…
March 29th, 2007 at 2:22 am
Just look at VisualAge for Smalltalk. They build a rather small layer which allows access to library functions (DLL on Windows, shared objects on Linux/Unix, etc.). EVERY access to the underlying operating system functions is done with this layer, whether it is GUI access, file I/O or network i/O or access to private APIs of the VM. The OS abstraction itself is build in Smalltalk.
This is just what Java needs, a simple to use class library with a small and portable JNI stub.
March 29th, 2007 at 7:38 am
Java wont be that *funny* language, But its the *Extra stuffed* language for all Kind of Enterprise Application. No other language can “override” Java in this way. Each language will have its own feature, Even Java is used to talk to any Kind of Application as DB , Mainframe System etc.None of the Other can be used which are that *lispy* and *pythony* drived !
March 29th, 2007 at 8:30 am
I’m surprised fewer people haven’t mentioned video and sound support.
As Sergey said, the JMF hasn’t been updated in ages and never really had decent Mac support in the first place. Apple’s got their QuickTime libraries, but they don’t work with Linux. As far as I know, there’s no easy way to play a video on all three major platforms.
March 30th, 2007 at 1:51 am
Java wasn’t created to solve every problem. It’s unreasonable to expect it to provide direct access to OS functions for every OS and at the same time maintain its WORA property. If you need to do low level programming or something OS-specific, use C/C++ and JNI. The possibility is there if you need it.
As for sound/video support, JMF may have a lot of room for improvement but how much demand for it is there? Java isn’t the first choice for desktop applications, although it has made major leaps forward in the last few years. But it still is the best thing on the server side and nothing comes close to it… yet.
March 30th, 2007 at 9:00 am
It seems quite ridiculous that serial and parallel ports are not supported as standard, irritating that Bluetooth is not supported and annoying that full network and file system access is not provided as standard. It also does seem pretty stupid to not support USB and Firewire, the arguments against this do not seem valid for a general purpose application language like Java.
Stuart Gathman hints at a possible approach for I/O, provide a Java wrappers for Posix, so that we can get platform portable access to most of the useful Posix facilities on various OSs, including Windows, even if via GNU libraries.
WORA should not be an issue, provide generic factories and interfaces to tell you want devices are available and want their facilities are, this should not be hard. Another approach is to provide a virtual device file system(s) with special filenames and virtual files to get and set device capabilities and view/read sub-device trees e.g. for USB.
Use some imagination!
April 1st, 2007 at 7:02 am
On calling OS functions directly:
I’ve put up a few demos of this, using JNA. It’s a lot like JDirect.
This allows much greater leverage in building custom libraries (like things like file manipulation, transparent/shaped windows, etc) which require native access but which you’d probably prefer to write in java over C++. And you don’t have to deal with JNI compilation and linkage headaches.
April 2nd, 2007 at 2:48 am
Another tool like JNA is JNIEasy, it may be used to wrap C++ classes too from Java.
April 2nd, 2007 at 9:34 am
“# Hernan Says:
March 29th, 2007 at 1:08 am
An equivalent of the Unix “ps†and “kill†commands for the JVM would be nice. Maybe for “top†and “vmstat†too…”
What I really want is a sane way to wrap an application in java, or some standard launcher technology.
When you are running multiple Java applications, the process list shows “java.exe” instead of my program name. The only way is in windows you can map an existing Window (if the app has one) to the process name.
May 14th, 2007 at 4:10 pm
Oh my god, not JAVA!