How to Make Java Suited For Desktop Apps
How to Make Java Suited For Desktop Apps.
Even if you manage to create a terrific first Swing app for your users, the second one will probably hurt you.
Joshua Marinacci's asked on his Blog Why don't you ship Swing apps? and suggested some usual reasons like deploying the JRE, Swing API complexity and corporate focus on web apps. I'd like to add and discuss one more reason:
- No class / code sharing
When you develop apps for in-house use it's almost certain there will be users who run many of those apps at the same time.
For the first one you strive to become a good Swing programmer, get all fancy third-party libraries from JNDC and JGoodies, bundle the JRE (or deploy it on all clients by using you preferred enterprise management system / login script hack) and get the work done, hoping the cross-platform compatibility you get will pay for the extra effort, specially with so many new Linux desktops out there.
But when it comes the second application, it'll load another JVM and spend another 25+Mb with standard and third-party libraries. There's a reason all GUI platforms are based on (1) OS-Level code or (2) Shared / Dynamic Link Libraries.
I remember using the first Java installer for Oracle 8i, I needed more RAM to run the installer than to run the development and sometimes the production servers, just because the installer called two or three other Java apps for creating the database and configuring networking parameters.
It should be easy to create a "Java Launcher" that justs calls each app main method and runs everything as different threads inside the same JVM, but Swing developers screwed this up by creating hidden threads and requiring us all to call System.exit(0) to finish the application.
You can see almost every other GUI toolkit for Java lets you control the event loop and would not suffer from this problem. Check, for example, Eclipse SWT and the JavaGnome Project. (Well, I really don't know if these would allow many independent GUI apps running on the same JVM, but I can imagine they allowing this without requiring me to rewrite my apps, just internal changes.)
Research projects like the Sun MVM can aleviate this, if their features are integrated into Mustang or another Java release, but I wonder how this will affect the classloading magic application server and other Java apps have to perform.
Besides, when everything runs on the same JVM, you get to manage conflicting versions of the same libraries. Java classloaders have the abilities to work around this if we come with a standard for describing / naming library releases used by each app.
Other possible solution is used by the GCJ Project which extends the famous GNU C Compiler to compile Java sources. When the standard class library and popular third-party ones are natively compiled as shared libraries, you get code sharing among apps for free. GCJ can mix native code and standard bytecodes, so this could be an interesting option. Shame it doesn't includes a JIT for speeding up the bytecodes.
Sun itself provides the JMF as both a pure-Java package and as optimized â€œperformance packsâ€ with native code for Windows and Linux. What about a â€œSwing Performance Packâ€? What about a JCP standard for compiling and deploying Java libraries as native shared libraries, requiring the standard bytecodes to be supplied alongside the native code, so there's no platform lock-in? And what about a standard feature by which the JRE compiles whole packages into native code (it should be easy from its own JIT) and caches the results?
I think these two ideas (class sharing and native compilation) are not conflicting, but complementary. After all, both depends on solving the problem of managing multiple versions of the same libraries / jar packages around the system. I personally would love not having dozen copies of Jakarta Commons and other popular libraries around my system.