Monatliches Archiv für August, 2006

Spaß mit Java. Heute: VerifyError bei inneren Klassen

Eigent­lich wollte ich heute den neus­ten Build unse­rer Soft­ware releasen. Mit dem vori­gen hatte es näm­lich ein Pro­blem gege­ben: Bei unse­rer Mit­ar­bei­te­rin waren Feh­ler­re­ports auf­ge­lau­fen, dass sich eine Maske nicht öffnen ließ. Prü­fung mei­ner­seits: Die Java-​Laufzeitumgebung mel­det einen „Veri­fy­Er­ror”. Hm. Muss wohl was beim Packen schief­ge­gan­gen sein.

Also heute mor­gen den Pack­pro­zess genau beob­ach­tet: Alles roger. Trotz­dem das Binary noch­mal getes­tet: Bautz! Feh­ler immer noch da.

Und dann habe ich wirk­lich den gesam­ten Tag damit zuge­bracht, das Pro­blem zu ana­ly­sie­ren und letzt­lich zu lösen: Der Com­pi­ler von Java 1.4.2, selbst in der aktu­el­len 1.4.2_12-Version, macht einen Feh­ler, wenn man aus der inne­ren Klasse einer inne­ren Klasse her­aus eine Methode der äußers­ten Klasse auf­ruft. Mein Codebeispiel:

public class CompilerProblemDemo extends JPanel {

  public CompilerProblemDemo() {
    super(new BorderLayout());
    add("Center",new InnerPanel());
  }

  private class InnerPanel extends JPanel {

    private JButton testbutton;

    public InnerPanel() {
      super(new BorderLayout());
      testbutton=new JButton("Test");
      testbutton.addFocusListener(new FocusAdapter() {
        public void focusGained(FocusEvent e) {
          // This line leads to VerifyError if compiled with Sun javac 1.4.2_12.
          // Works correctly if compiled with Eclipse 3.2.0 in 1.4 mode
          // Runtime envorinment in both cases: Sun java 1.5.0_07
          CompilerProblemDemo.this.firePropertyChange("gotFocus",null,null);
        }
      });
      add("Center",testbutton);
    }
  }

  public static void main(String[] args) {
    CompilerProblemDemo cpd=new CompilerProblemDemo();
    cpd.addPropertyChangeListener("gotFocus",new PropertyChangeListener() {
      public void propertyChange(PropertyChangeEvent evt) {
        System.out.println("I received the focus event");
      }
    });
    JFrame jf=new JFrame("CompilerProblemDemo");
    ((JPanel)jf.getContentPane()).add("Center",cpd);
    jf.pack();
    jf.show();
  }

}

Fie­ser­weise tritt der Bug im Eclipse-​eigenen Com­pi­ler nicht auf. Nach­dem das Pro­blem loka­li­siert hatte, habe ich den Feh­ler auch in der Bug-​Datenbank bei Sun gefun­den. Dort steht, dass er mit Java 1.5 gefixt ist.

Werde ich wohl doch mal den Com­pi­ler fürs Pro­duk­tiv­sys­tem umstel­len. Zunächst noch im 1.4-Kompatibilitätsmodus, aber der end­gül­tige Schwenk zu Java 1.5 ist auch nicht mehr so lange weg…

Dass es sowas gibt… Ich ver­wende ja nun den Sun-​Compiler extra wegen der Kom­pa­ti­bi­li­tät und so. Frü­her, als ich noch mit jikes die Relea­ses kom­pi­liert habe, da kam sowas ja häu­fi­ger vor. Tststs…