Slashdot Mirror


10 Reasons We Need Java 3

An anonymous reader writes "This article on O'Reilly Network (written by one of the most active Java book writers ever, Elliotte Rusty Harold) has some interesting points about the need for a new 'cleaned up' Java version, made to incorporate the advances in the last 7 years of its life and without the requirement to keep compatibility with old versions."

13 of 568 comments (clear)

  1. Re:One big thing Java needs by Westley · · Score: 2, Informative
    This is already coming in Java 1.5 (with any luck) in the form of the isolation API. See JSR 121.

    Jon

  2. Re:The "most controversial" proposal by Westley · · Score: 5, Informative
    What you really need is generics (as in C++ templates). Java collections are vile, since they suffer from type loss even when used with "real" objects. I'm surprised that didn't come into this top ten; it's a major language deficiency.

    The article was about what can't be built on top of Java2. As Java2 (in 1.5) will be getting generics, I'm not surprised this was left out of the article. I believe there may well be some automatic boxing if you wish to use it, e.g.

    List<Integer> x = new List<Integer>();
    x.add (5);

    but it's all up for debate at the moment of course...

    Jon

  3. Re:One big thing Java needs by Anonymous Coward · · Score: 1, Informative

    What you want is called Echidna and works for all JVMs:

    http://www.javagroup.org/echidna/

  4. Fill in the blanks by d3xt3r · · Score: 3, Informative
    BTW, the blank overhead was supposed to be SMP. Java threads that take advantage of SMP are a requirement for server side tasks. Again, Sun's Solaris and Linux JVMs and Apple's OS X JVM, all already take advantage of this.

    So much for proof reading. :)

  5. Some observations by Twylite · · Score: 5, Informative

    This is a refreshing view on changes to Java, because it doesn't make the traditional calls for templates, a preprocessor, and operator overloading. Most of the article is well considered and logical, and should be implemented in a move to Java 3.

    There are however some issues with which I must disagree:

    • Under the discussion of primitive types, the author proposes that the current wrap-around handing of primitive types is incorrect. Mathematically, yes - but not in computing terms.
      While the overhead of promoting all primitive types to objects may be insignificant, the overhead of checking all arithmetic for overflow does have the possibility of causing significant overhead.
      Not only that, but you will still end up with a RuntimeException, because you cannot expect ALL arithmetic to be in a try ... catch block. So all this becomes is an aid in debugging or forcing a crash (rather than progress based on an invalid computation) on a live system. I have to question whether the performance trade-off is worth it.
      Overflow errors are a well known problem - well-written software should not suffer from them.
    • Still on the primitive types discussion, I don't believe the author has considered the impact of using an arbitrary-size number computing which does not require such numbers. The performance overhead is potentially huge, and you lose the ability to performance a large number of optimisations based on the fact that you are dealing with a quantity of a determistic size (in memory). There are also threading and synchronisation considerations, which I will discuss later.
    • The byte type is unfortunately defined in Java. It should be unsigned, to begin with. It is certainly necessary for many IO operations, and data encoding/decoding; moveover it would be preferable if bytes had the special property that aritmetic operators converted other types to bytes (even if data loss was involved) rather than vice verse.
      Many Java developers are caught by using code like b = (byte)i; rather than b = (byte)(i & 0xff);. It is generally true that when dealing with bytes, you want to keep data as bytes until you explicitly make it into another type.
      Finally, byte arithmetic should always overflow, as is expected in CPUs.
    • Last note on primitives (and it applies to 4-byte chars as well): the assumption we are afforded by Moore's law does NOT apply as the author suggests. Rather, what was designed to run on a low-end Sun or 486 Intel PC is now expected to run on a 1Mhz 8-bit CPU with 32Kb memory.
      While J2ME is not fully Java-compliant (no floating point support, for example), it still largely conforms to the write-once test-everywhere rule, and this is part of Java's attractiveness.
    • Onto the size of chars. This is a bit of a tough one -- which it would be nice to have a 4-byte character, I have dealt with several Java applications which were very String-intensive. They could gobble up 256Mb RAM in a matter of seconds. A 4-byte char only worsens this problem. It is even doubtful that a char object (as opposed to primative) would help, given the overhead that would be associated with the object (at minimum a type and representation lenght - you're back at 4 bytes again).
      More memory is not always a good solution. Java's garbage collection architecture is very wasteful of memory at the best of times; at the worst of times you are using immutable objects like Strings, so you can't pool or reuse the objects. As increasingly more applications handle text because of our new XML obsession, this situation becomes worse.
    • Threading next. I have studied Java's threading model in some detail, including the issue of non-atomic longs. The problem comes down to one of efficiency - again.
      Java implementations typically do not emulate threads on their most common platforms - they make use of the native threading model of the operating system. This means that making a 64-bit operation atomic must involve the use of a lock; so instead of a 64-bit operation taking up 4 times the time of a 32-bit operation, it could take that plus two calls into kernel space.
      As mentioned before, the same is true of using arbitrary-size numbers. Only a number that the CPU can treat atomically will result in an atomic operation without additional synchronisation.
    • With regard to monitors, I fail to see the need for multiple monitors per object. Every object is a monitor, and Java syntax provides for implicit synchronisation on the current object as well as explicit synchronisation on an arbitrary object.
      Thus, to have different types of operations (all implemenented in one object) synchronised on different locks, simply use each in an explicit synchronisation block and have private or protected lock objects specifically for that purpose.
      Decoupling monitors from objects would kill a lot of the ease-of-use that makes Java threading such a pleasure by comparison to many other models.
    • On the other hand, there are many weaknesses in Java threading. It lacks a strongly-defined policy for thread scheduling, which can make the design of complex multithreaded applications very difficult.
      Furthermore it ONLY has monitors as locking primitives, which rules out the use of overlapping locks, which are one of the few effective synchronisation primitives which can overcome weakly-defined scheduling.
      Java would do well to add an additional synchronisation primitive - either mutexes (as error-prone as they are), or interlocked increment-and-compare (which can solve a number of synchronisation problems far more effectively than mutexes).
    • Onto the XML question, and getting to my area of pet hate: The XML Silver Bullet.com. The author's bias towards XML is understandable, but he needs to realise, as do the millions of developers who let the marketting machine think for them, that XML is a poor implementation of a decent idea.
      For a better critique of XML take a look at http://www.eastcoast.co.za/twylite/pml/pml.html" >my anti-XML page (incomplete, but the anti-XML rationale is presented).
      In particular, XML is a very poor choice for the encoding of Java objects, because of its lack of terseness, and the relatively slower speed of parsing XML - both of which impose significant penalties in a distributed environment.
      Some hard facts to back up these claims: in an application I have worked on, we experimented with SOAP instead of our original binary protocol. The result was a 80% decrease in call rate.
      In a few years, the XML phenomenon will wear off, and world+dog will wonder why we are wasting our precious bandwidth on all the overhead. Already WS developers are starting to wonder how it will affect their resources, and we have proposals for a binary encoded XML for the mobile world.
      This "simple" specification is too complex and too overkill for most tasks, so every "lightweight" XML parser on the market conveniently leaves out certain parts of the specification - be it DTD, PI, CDATA, whatever. We already have XML documents that aren't compatible between two parsers, the situation will only worsen.
      And in the end we will realise that it isn't necessary to make computer data human-readable, because really, everything is just a bucket of bytes and a rule on how to view it, and XML is a very, very poor rule.

    Java is not perfect. It is not a silver bullet, and it is certainly not everything to everyone. Instead, it offers an environment that, to a lot of people, is a damn sight better than C++ because it avoids the error-prone complexities and power of the latter. But you must accepts its weaknesses as a trade-off.

    --
    i-name =twylite [http://public.xdi.org/=twylite], see idcommons.net
  6. Re:The Mac OS X JVM has this already by maraist · · Score: 4, Informative

    BTW, on Linux, there is no real difference between a process and a thread, so Sun's JVM is already "multi-process" on Linux.

    You confuse me, because you obviously must understand the difference between threaded and multi-processed, yet you claim that there's no difference in Linux. There are numerous functional differences between the two. First and foremost, you have 100% isolation (sand-boxing). You're not concerned with race-conditions (well, you have to go out of your way to produce them at least), you have to explicitly share material (e.g. pipes or magical fork-aware objects), you're crash-proof (apache has a master process image; if one worker "thread" dies for almost any reason (baring OS problems), it VERY quickly forks a new worker which is 100% ready to go), and finally, MP has better caching issues with multiple CPUs (e.g. no shared and slow writable cache). To boot, while MT saves more total memory, MP more efficiently distributes it to workers. Non modified memory is freely shared in a safe manner (marked as read-only by the OS, and thereby efficiently cached by each CPU), and only modified memory gets moved. Granted, in JVM's garbage collector, the entire heap is constantly remodified.

    As other's have said, I support the general idea of Apple method of sharing memory space between JVM's; though I don't know it's particulars. Most notably, the shared memory should be read-only (to avoid interdependency crashes). Next, it should only be shared per user (or at least copy-on-write), to disallow viral infections.

    My concern is obviously for that of robustness. Java is already flimsy as it is in this respect (imagine running an entire OS with a single such point of failure).

    --
    -Michael
  7. Re:One big thing Java needs by jilles · · Score: 4, Informative

    In a JVM the data is all loaded classes, their on the fly compilations and many other resources that can and should be shared by java applications. Much of the overhead of starting a java application actually comes from loading and compiling classes. If you can share JVMs the classes have to be loaded only once.

    Due to the fact that the java classloader happens to be one of its cool features it is actually dead easy to implement this feature safely. Many java application launchers exist already that can let you share a jvm with multiple applications. I used several of them and was amazed at the difference in performance.

    --

    Jilles
  8. Re:Point by point by Keith+Russell · · Score: 4, Informative
    eliminating checked exceptions (as Bruce Eckel has advocated),
    Don't know enough to understand what this means. Is he wanting to get rid of catch clauses?

    Exceptions come in two flavors, and the difference is simple. Checked exceptions must be caught, Unchecked exceptions don't. If you call a method that throws a checked exception, you must catch that exception, or the compiler flags it as an error. If the exception is unchecked, you can call the method outside a try-catch block without complaint from the compiler.

    Interesting that Java has checked exceptions, .NET doesn't, and developers from both camps want things the other way around.

    --
    This sig intentionally left blank.
  9. Re:Point by point by jwpalmer · · Score: 2, Informative
    Classloaders are implemented the right way. So don't change this (The exception messages could be improved though).

    Ack. The classloader architecture is one of the most poorly designed and inconsistently implemented parts of Java. The problem is that almost no one has to delve that deep into the doo-doo to get things done.

    However, if you're unlucky enough to be building an enterprise server architecture that requires separate classloaders (to avoid the JAR-version-hell of the classpath) get ready for fun:

    1. Half of the APIs in Java don't correctly use classloaders when they should. For example, when initializing the security API, you can't pass in a classloader - Java assumes that you will be using the standard classpath. WRONG!
    2. Statics allocated in classes are NOT garbage collected when the classloader is destroyed. So, if you use a classloader to manage your resources and allow a graceful stop and restart, all of your strings, objects, what have you will never get GCd. UNBELIEVABLY WRONG!
    3. The list goes on and on...

    As I said, the only reason that people believe the classloader API isn't broken is that they probably haven't had to use it. It needs serious help, above and beyond the ridiculously pervasive classpath issues.

  10. Re:One big thing Java needs by tullmann · · Score: 2, Informative

    Multi-process JVMs are coming. Its called "Application Isolatation".

    JSR-121: http://www.jcp.org/jsr/detail/121.jsp

    The Expert Group is hoping to release its draft API to community review in a month or so. The draft API on the above web page is 1 year out of date, but is useful to get a handle on the scope of what's being done (if not how the API will accomplish it).

    If you can't wait, check out the JanosVM:

    http://www.cs.utah.edu/flux/janos/janosvm.html

  11. IBM's Persistent Reusable JVM and security by Nick+Mitchell · · Score: 2, Informative
    Check this out, dudes: The 390 Persistent Resuable JVM

    The 390 machines use this not for performance, but actually for security. Each transaction uses a fresh JVM heap, so there is no possibility that errant code might mistakenly (who, me? hehe) read something is shouldn't, like the previous transaction's cleartext user info.

    nick (i believe this post is past the SAT, the Slashdot Attention Threshold, hehe, lesse if anyone reads it)
  12. Re:This is all academic by jbolden · · Score: 2, Informative

    Microsoft's browser support running the JVM of your choice. I've been running Sun's on I.E. for years now. You do the same things with your Java apps that sites did for years when they posted Acrobat "to use this site you'll need...".

  13. My suggestions by Anonymous Coward · · Score: 1, Informative

    I am a pretty experienced Java developer, this is my own list:

    Garbage Collection: When it takes place and how long it takes is very nebulous. I have heard MANY people say that Garbage Collection CAN be done well, but it isn't done well in Java now. Try running a webserver with a lot of threads, when you get low on memory force a garbage collect - be prepared to wait. You need more control over garbage collection, the ability to run it in the background, the ability to set time limits, do partial cleanups, etc.

    Replace BOTH AWT and Swing: Swing is broken. In each new version something stops working in Swing, it is overcomplicated and buggy. If you want to have some fun get the 1.3 source and read JInternalPane, you can find about 20 obvious bugs with ease. AWT and Swing are very inneficient. Whenever you add something to the AWT Hierarchy it generates all sorts of events, updates the cursor, etc etc. The layout managers are a mess, about 3 people on earth understand how BoxLayout works. Why isn't there a vertical equivalent of flow layout? The XUL Box container is easier to understand AND does more than most of the AWT/Swing layout managers. The way they interpret alignment, pref/min/max size and other variables changes with each layout. Things like KeyEvents are also a disaster. Swing is over-engineered, its too complex to understand and to make work properly.

    Meanwhile AWT is buggy as well, and full of deprecated and just plain odd methods. There are obvious bugs in things like targeting mouse events, focus management, etc. (Which changed in 1.4 and is not compatible with 1.3!)

    Classloader: This is one that many people may not have experience with, but is a big problem when you are running say a webserver. The same class loaded by two different class loaders is considered 2 separate classes, just with the same name. They don't share static variables, for example. There are also a lot of conflicts when the webserver uses a package and your program attempts to use a newer/older version of the same package.

    I'm not an expert on the subject but it needs to be fixed or modified somehow.