Tags: Java
Romain Guy has written a blog entry about SwingUtilities2, and I find it a little confusing because in one paragraph he's suggesting the reader to use this class, and in the next he is saying to steer clear of it. Maybe he's quoting someone else and didn't make that clear?
In any case, Sun ships in our JDK a whole lotta private classes. It's relatively easy to dig around and find interesting classes or methods to call. And the exercise is somewhat like the old past-time of Windows programmers of finding undocumented API's to call to do goofy things.
I want to write a little to clarify what I think Romain was saying.
I'm sure the SwingUtilities2
class has some useful features. No doubt that's why it's there. But if one uses that class, one should absolutely expect their programs to break.
We treat the public documented API's as our contract with you, the developers of Java applications. We go to great length to maintain compatibility with the public API's. But when something is undocumented or otherwise clearly a private API, we feel very free to make changes.
The SwingUtilities2
class which Romain mentions is in the latter camp. We mave made zero contract with the public about that class, just like all the other private classes. Those are all implementation details which are free to change at any time as we refactor the internals to fix bugs and add features.
For the public classes, the ones for which we gaurantee compatibility, we have review processes up the yinyang to check for changes. I work with one of the review processes, called the "CCC" (which is probably short for "Change Control Committee", but I like to think of it as the "Committee for Concerned Citizens"). For "substantive" changes we go through a review process and generally strive to keep behavior, exceptions, signatures, etc, the same from release to release. The process gets a little tricky from time to time, especially when the current behavior of a method is buggy and fixing the behavior means an incompatibility which will break software that depends on the buggy behavior. Fortunately those are rare instances.
In any case, this is going on a little longer than I intended.
The short message is a strong recommendation to stay away from using private classes. If you do this, your program will be tied most strongly to Sun's Java, and will probably break in a later release.
Source: weblogs.java.net
Comments
Oops, I am sorry if I wasn't clear but I really didn't suggest to use it. I wrote this entry because I just tried an application using SwingUtilities2 and I couldn't run it on Mustang. Thanks for the follow up though.
Posted by: gfx on January 14, 2006 at 10:31 PM
Speaking as someone who wrote an 800 page book more or less about using the undocumented classes, this strikes me as a deficiency in Java. If it were possible for superpackages to access the package protected parts of their subpackages, then this wouldn't be an issue. For example, if
sun.net could be replaced by a java.net.impl
package that was only accessible to classes in the java.net
packages , no one could go mucking around with it. Don't blame programmers for using what you put there. Do not rely on social convention to enforce what could be enforced by code.
Posted by: elharo on January 15, 2006 at 03:13 AM
I'm sure there's something which could be done in the packaging that could be done to hide the implementation even more strongly. If it's a deficiency, then it's a deficiency other software systems share. For example there's several books for Windows that do the same as yours, and reveal "secrets". That deficiency hasn't kept Windows from basically taking over the world (in terms of being the most common personal computer operating system). As an object oriented system we, Sun, probably ought to do a better job of hiding the implementation details. That's what object oriented systems do, is hide details.
Posted by: robogeek on January 15, 2006 at 08:16 AM
Java developers are as bad at writing portable code at their jobs as anyone else. They'll cut corners when the task demands it, because it's human to do so. If a sun.net or com.sun class is made available to do a job, then people will use it. That's no different from 'secret' Windows APIs, or what have you. This could be easily fixed at the compiler level, by simply having the 1.3/1.4/1.5/1.6 compiler refuse to compile code that imports from sun.* and com.sun.* namespaces. A different approach would be to split the JRE into OSGi bundles, which would allow people only to use the exported API. I've been thinking about that for GNU Classpath in the long term, since I'd like to avoid the mistakes whoever is responsible for this mess made by allowing people to easily lock themselves in into the dominant platform. FWIW, you'll find several instances of such unportable code in NetBeans (imports sun.net. stuff directly to work around crashes with JDK 1.4.1's Jar caching, and does some stuff with some com.sun.java.swing.* classes, whatever those do), and OpenOffice.org (huge chunks of undocumented 'junk code' calling directly into Sun-specific internals to work around lack of sane APIs, bugs, or whatever, that have been partially cleaned up meanwhile thanks to Caolan from Red Hat, and Kai and other people from Sun), the two projects I looked into. It's mildly ironic that Sun's own open source projects don't follow the house rules on not using VM-specific classes plastered on the JDK documentation, but as I said above, Java developers will cut corners, too, when the job demands it. cheers, dalibor topic
Posted by: robilad on January 15, 2006 at 10:13 AM
Will this be addressed by JSR 277?
Posted by: coxcu on January 16, 2006 at 07:02 AM
I don't think anything needs to be done to hide these classes. Modern IDEs have features to do this, and sometimes there might be a legitimate reason for using these classes (for experimentation,etc.). If something is available, yes they will use it. But they know full well the consequences for doing that. And when code breaks when moving to another version or implementation of Java, no one is to blame put the people who wrote the code that used these classes.
Posted by: prunge on January 16, 2006 at 04:02 PM
If you write against undocumented APIs or APIs documented to be unstable you're on your own when that API changes. Tough luck to you, you could and should have known. That's not a deficiency in Java, it's a deficiency in the people using those APIs if they don't understand that and take responsibility. I can write C applications that call unpublished APIs deep inside Windows (and have in fact done so for OS/2), but if I do that I know I can't complain if Microsoft (or whomever) changes his OS so that call no longer works or has unexpected results. I only have myself to blame. It's the same with Java. Of course someone writing a book about such things doesn't like that little fact, he needs to constantly revise his book for every new release of the platform to take all those changes into account. Tough luck boy, that's the consequence of your own choice of subject. Your decision to write about using things Sun says quite clearly are not to be relied upon as stable is yours and yours alone and brings that consequence.
Posted by: jwenting on January 17, 2006 at 01:06 AM
Hmmm. Does this also count for the com.sun.security.*
classes?
There is an example of how to get the currently logged in user at Java Almanac, GetLogin
It seems to be an official book "... from the source".
Are there any suggestions on how to do this in a jvm compatible way?
Posted by: twolm on January 17, 2006 at 01:16 AM
As I understand, com.sun.*
classes are not public APIs (IBM and Apple don't need to provide them) but they are vendor APIs that's supported by Sun. As for sun.*
classes, they are completely implementation details. A method does not automatically becomes a API only because it's a public method in a public class.
Posted by: weijun on January 17, 2006 at 04:55 PM
twolm: yes. Those things don't necessarily exist on non-Sun VMs, even if they are certified as compatible, since they are not part of the Java API. If you need such functionality, use third party open source libraries. GNU Classpath should get a JAAS implementation merged in soon, afair.
cheers, dalibor topic
Posted by: robilad on January 17, 2006 at 07:39 PM