Discussions

News: Nasty Little JDK 1.5 Compiler Bug: final + ternary

  1. There is a serious error in the JDK 1.5 compiler, pointed out to me by one of my readers (of The Java Specialists' Newsletter), Amotz Anner.

    Amotz has submitted a bug report already to Sun, and as soon as we have a number from Sun (may take up to three weeks) we will post that in a follow-up.

    Here is the problem:

    final String name = false ? "Heinz" : null;
    System.out.println(name);

    When compiled using the JDK 1.5 compiler, it will print out "Heinz". It does not matter whether you say -source 1.[234] or whether you run it using any of the JDK 1.[2345].x JVMs from Sun.

    This happens only when the local variable is set to "final" and one of the values of the ternary if-else is literal null.

    PLEASE let's not make this into a mud-slinging match against Sun Microsystems, ok? They are overloaded with bug reports as it is. The reason that I post this is to make you aware to NOT use the final local variables in combination with ternary if-else until further notice. You might not be compiling with JDK 1.5, but one of your colleagues might.

    What are your favorite JVM bugs? :)

    Threaded Messages (31)

  2. I m sure there is a jdk 1.5.(x+1) on the way. nothing is perfect in first shot. 1.4 itself is going thru so many versions as we speak.
       But this will be a good thread to make a list of all issues for the dev community to know.
       Its just a bit too early i guess - not a lot of us have gives a test drive to 1.5 yet to this extent.
  3. How not to be informative[ Go to top ]

    But this will be a good thread to make a list of all issues for the dev community to know.
    No, it wouldn't. This is a lousy place. A week from now, this discussion will be buried under any number of other discussions on this site, and folks either won't see it and learn about a bug, or won't see and add their bugs. If informing the developer community of bugs is important (and I'll provisionally agree that it is), then do a good job of it.

    Additionally, a threaded discussion isn't a good way to *list* problems. That's what tools like bugzilla, or even a simple tabular list of links, is good for. Threaded discussions are to *discuss* things. To carry on conversations.

    I applaud the original poster's plea to not turn this into a mudslinging match. I imagine he didn't include the final line of that post, "What's your favorite JVM bug?" That sounds to me like an attempt to inspire exactly the sort of mudslinging he argued against. (Perhaps he did write that comment, and meant it another way, in which case I apologise for my suspicious mind).

    Disclosure: I don't work for Sun, but I used to.
  4. How not to be informative[ Go to top ]

    I imagine he didn't include the final line of that post, "What's your favorite JVM bug?" That sounds to me like an attempt to inspire exactly the sort of mudslinging he argued against. (Perhaps he did write that comment, and meant it another way, in which case I apologise for my suspicious mind)
    Well spotted Glen, that line was certainly not put in by me. Must have been one of the editors ... (let's not start mudslinging them either... ;-)

    On the JavaLobby site, someone posted a link to a bug report on the JavaSoft site. It looks like that bug will be gone in the next release, but be careful - it also applies to final fields as well as local variables.

    For the record, the URL for the bug tracking is http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5105890

    Heinz
  5. jdk "bugzilla"[ Go to top ]

    But this will be a good thread to make a list of all issues for the dev community to know.
    Additionally, a threaded discussion isn't a good way to *list* problems. That's what tools like bugzilla, or even a simple tabular list of links, is good for.
    There is a "bugzilla" already available for the jdk - just go to

    http://bugs.sun.com/bugdatabase/search.do?action=1&category=java&bugStatus=&keyword=1.5&maxResults=10&startIndex=1&sortBy=relevance
  6. Maybe..[ Go to top ]

    .. it's an attempt to deprecate those bloody ternary operators that allow people to produce nice concise unreadable code ;)

    Nath
  7. final String name = false ? "Heinz" : null;
    System.out.println(name);
    When compiled using the JDK 1.5 compiler, it will print out "Heinz".
    Not here. I get null. Are you sure you're using 1.5.0 final release?
  8. final String name = false ? "Heinz" : null;System.out.println(name);When compiled using the JDK 1.5 compiler, it will print out "Heinz".
    Not here. I get null. Are you sure you're using 1.5.0 final release?
    Yes, as far as I know I am. Here is the version information:

    java version "1.5.0"<br>
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)<br>
    Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)<br>

    I will download another version now to compare.

    Make sure that you compile it with the JDK 1.5 compiler, don't use your IDE, such as Eclipse. The bug is in the compiler, not the JVM.

    Heinz
  9. final String name = false ? "Heinz" : null;System.out.println(name);When compiled using the JDK 1.5 compiler, it will print out "Heinz".
    Not here. I get null. Are you sure you're using 1.5.0 final release?
    Yes, I downloaded the latest version again, and it is the same as I had.

    Good news - Sun have fixed this bug and it will be in the next release at the end of the year!
  10. Bug not apparent in the Linux VM[ Go to top ]

    I compiled and ran this code on the Linux version of the Sun VM (1.5.0-b64) and it works fine (i.e. returns null).

    Maybe it only affects Windows VM's.

    Greg
  11. The BUG does exist[ Go to top ]

    final String name = false ? "Heinz" : null;System.out.println(name);When compiled using the JDK 1.5 compiler, it will print out "Heinz".
    Not here. I get null. Are you sure you're using 1.5.0 final release?
    I got "Heinz" with JDK 5.0 final.
    Decompiling with JAD, I got:
    // Decompiled by Jad v1.5.8f. Copyright 2001 Pavel Kouznetsov.
    // Jad home page: http://www.kpdus.com/jad.html
    // Decompiler options: packimports(3)
    // Source File Name: Test.java

    import java.io.PrintStream;

    public class Test
    {

        public Test()
        {
        }

        public static transient void main(String args[])
            throws Exception
        {
            String name = (String)null;
            System.out.println("Heinz");
        }
    }
  12. The BUG does exist[ Go to top ]

    That looks final to me. Static transient?
  13. Nasty? I think not[ Go to top ]

    final String name = false ? "Heinz" : null;
    So basically it won't compile obfuscated code? Not exactly "nasty".

    Seriously, this is not a great piece of code, I agree it should work and that this is indeed a bug but I wouldn't have accepted this if I'd seen it in one of my team's code.

    -John-
  14. RE: Nasty? I think not[ Go to top ]

    final String name = false ? "Heinz" : null;
    So basically it won't compile obfuscated code? Not exactly "nasty".Seriously, this is not a great piece of code, I agree it should work and that this is indeed a bug but I wouldn't have accepted this if I'd seen it in one of my team's code.-John-
    Hmmm. Ternary statements are so maligned. The corresponding code in an if block is IMHO more difficult to read.

    They do also get a lot of brownie points for using final in the variable declaration, love them finals!
  15. RE: Nasty? I think not[ Go to top ]

    Hmmm. Ternary statements are so maligned. The corresponding code in an if block is IMHO more difficult to read.
    They do also get a lot of brownie points for using final in the variable declaration, love them finals!
    Ternary statements are good in many cases I agree, finals are very good in all applicable places but this just doesn't look right. I'll accept that it's certainly not the worst thing I've ever seen but I'm not sure you should really put logic (ternary statements) into code initialisation. Before we get into an argument about the fact that non-finals can't be used in inner classes or that you can only initialise a final at declaration etc. my point was simply that this is not "run of the mill" code and could be simplified.

    I'll leave it that, I agree it's a bug but not one I'm going to worry too much about, thanks for pointing it out though.

    -John-
  16. Nasty? I think not[ Go to top ]

    final String name = false ? "Heinz" : null;
    Seriously, this is not a great piece of code, I agree it should work and that this is indeed a bug but I wouldn't have accepted this if I'd seen it in one of my team's code.-John-
    Comeon John. That was the simplest example that could show the bug.
  17. Nasty? I think not[ Go to top ]

    final String name = false ? "Heinz" : null;
    So basically it won't compile obfuscated code? Not exactly "nasty".Seriously, this is not a great piece of code, I agree it should work and that this is indeed a bug but I wouldn't have accepted this if I'd seen it in one of my team's code.
    Just rewrite the code:
    final String name = getBoolean() ? "Heinz" : null;
    Regardless of the result of "getBoolean()", "name" will always be "Heinz".

    I woudn't qulify this code as "nasty".
  18. Nasty? I think not[ Go to top ]

    Thanks, it helps to understand the example.
    This case should not occur a lot and I guess Sun will soon correct this point in the upcomming release.
  19. Nasty? I think not[ Go to top ]

    If using non-null initializers, like:
        static final String name = false ? "Heinz": "John";
    it seems to work Ok.
  20. If you'll compile it without -g compiler generates just:
        System.out.println("Heinz");
    In case of -g flag it is being compiled into:
        name = null;
        System.out.println("Heinz");
  21. Nasty? I think not[ Go to top ]

    If using non-null initializers, like:    static final String name = false ? "Heinz": "John";it seems to work Ok.
    Yip, that is right. The bug happens when one side is null. Also, if it is nonfinal, it also works correctly.
  22. Guarding Against Null[ Go to top ]

    final String name = false ? "Heinz" : null;
    So basically it won't compile obfuscated code? Not exactly "nasty".Seriously, this is not a great piece of code, I agree it should work and that this is indeed a bug but I wouldn't have accepted this if I'd seen it in one of my team's code.
    Just rewrite the code:
    final String name = getBoolean() ? "Heinz" : null;
    Regardless of the result of "getBoolean()", "name" will always be "Heinz".I woudn't qulify this code as "nasty".
    I know I often use the following to guard against null.
    <code>
    final String partName = (null == part ? null : part.getName());
    </code>
    It sounds like a lot of my code would be broken.
  23. Confirmed With 1.5.0 beta[ Go to top ]

    I don't have the final release installed, but I have confirmed that the bug does exist in the beta.
    public class CompilerBugTest {
    public static void main (String [] args) {
    final String foo = (false ? "a" : null);
    System.out.println("foo = " + foo);
    }
    }

    $ /cygdrive/c/Program\ Files/Java/j2sdk1.5.0/bin/javac -version CompilerBugTest
    .java
    javac 1.5.0-beta

    $ java CompilerBugTest
    foo = a
    I think I'm going to add test case for this in to our project's suite to guard against it affecting us.
  24. It's so strange. If I compile that block of code in Textpad (which I am so sure that uses the Jave 1.5.0 I installed on my machine), it prints "null". But when I compile and run it in the DOS prompt windows, it prints "Heinz". So where does the problem lie? I'm using Window$ XP Pro SP2. I haven't tested it on Linux yet.
  25. It's so strange. If I compile that block of code in Textpad (which I am so sure that uses the Jave 1.5.0 I installed on my machine), it prints "null". But when I compile and run it in the DOS prompt windows, it prints "Heinz". So where does the problem lie? I'm using Window$ XP Pro SP2. I haven't tested it on Linux yet.
    Maybe you need to check your classpath setting and which makes you a mistake.
    I cant understand the mistake if i code the compiler, i think it is impossible for such a big error.
    As the Texpad(i dont know what it is, maybe a simple IDE) can run the program correctly, so it will.

    Another more things to check:
    1. please add the following statement into your code
    System.out.println( getClass().getProtectionDomain().getCodeSource().getLocation() );
    2. check it is the classpath that your javac compile to
    3. if not, it is your problem yourself
  26. Don't understand[ Go to top ]

    final String name = false ? "Heinz" : null;System.out.println(name);When compiled using the JDK 1.5 compiler, it will print out "Heinz
    I don't understand the interest of this code.
    Ca
  27. Don't understand[ Go to top ]

    final String name = false ? "Heinz" : null;System.out.println(name);When compiled using the JDK 1.5 compiler, it will print out "Heinz
    I don't understand the interest of this code.
    Usually you use the final word to instantiate constants.
    So something like final String name="Heinz";
    What is the interest to test a String like a boolean, especially with the final keyword.
    Can you explain in which case you are using this?
  28. Don't understand[ Go to top ]

    final String name = false ? "Heinz" : null;System.out.println(name);When compiled using the JDK 1.5 compiler, it will print out "Heinz
    I don't understand the interest of this code.Usually you use the final word to instantiate constants.So something like final String name="Heinz";What is the interest to test a String like a boolean, especially with the final keyword.Can you explain in which case you are using this?
    You also use final if you then want to use that variable inside an anonymous inner class or something like that.
    E.G.

    final String name = false?"Heinz":null;
    ...
    Thread t = new Thread(new Runnable()
    {
        public void run()
        {
        ... use the name variable in this method ...
        }
    });

    t.start();
  29. Ran it on Win xp JDK 1.5 final release.

    Indeed, it returns null... weird.
  30. Ran it on Win xp JDK 1.5 final release.Indeed, it returns null... weird.
    Did you also compile it with JDK 1.5 javac? The bug is in the compiler, not the JVM.
  31. Ran it on Win xp JDK 1.5 final release.Indeed, it returns null... weird.
    Did you also compile it with JDK 1.5 javac? The bug is in the compiler, not the JVM.
    Of course I compiled it with the JDK 1.5 javac.
  32. works ok on NT 4.0[ Go to top ]

    at work, using a NT4.0 sp6 machine, it works ok.

    the javac -version does not exist in my jdk 1.5 version.....