2013-05-21 5 views
14

Ich habe den folgenden Javac-Kompilierungsfehler festgestellt, bei dem javac Anmerkungen in einer statischen verschachtelten Klasse mit einer öffentlichen Enumeration nicht erkannte. Sobald ich die Enumeration aus der statischen geschachtelten Klasse verschoben habe, wurden die Kompilierungsfehler behoben. Weiß jemand, warum Javac fehlgeschlagen ist? Ist das ein Java Compiler Bug? Oder gibt es eine Java Nuance, die mir nicht bewusst ist?Javac kompiliert keine Annotationen für statische verschachtelte Klassen mit einer öffentlichen Enumeration.

Unten ist ein eigenständiger Testfall.

Fails zu kompilieren:

package test; 

import test.AnnotationBug.NestedClassWithEnum.ParticipantType; 

import lombok.Data; 
import lombok.NoArgsConstructor; 

import com.googlecode.objectify.annotation.Embed; 

public class AnnotationBug { 

    ParticipantType type; 

    @Embed 
    @Data 
    @NoArgsConstructor 
    public static final class NestedClassNoEnum { 
    } 

    @Embed 
    @Data 
    @NoArgsConstructor 
    public static final class NestedClassWithEnum { 
    ParticipantType type; 

    public enum ParticipantType { 
     ORGANIZER, 
     REGISTERED, 
     WAIT_LISTED 
    } 
    } 
} 

Compilation Ausgabe:

$ javac -classpath /home/avaliani/projects/jars/objectify-4.0b2.jar:/home/avaliani/projects/jars/lombok.jar test/AnnotationBug.java 
test/AnnotationBug.java:20: error: cannot find symbol 
    @Embed 
^
    symbol: class Embed 
    location: class AnnotationBug 
test/AnnotationBug.java:21: error: cannot find symbol 
    @Data 
^
    symbol: class Data 
    location: class AnnotationBug 
test/AnnotationBug.java:22: error: cannot find symbol 
    @NoArgsConstructor 
^
    symbol: class NoArgsConstructor 
    location: class AnnotationBug 

Compiliert:

package test; 

// import test.AnnotationBug.NestedClassWithEnum.ParticipantType; 

import lombok.Data; 
import lombok.NoArgsConstructor; 

import com.googlecode.objectify.annotation.Embed; 

public class AnnotationBug { 

    ParticipantType type; 

    @Embed 
    @Data 
    @NoArgsConstructor 
    public static final class NestedClassNoEnum { 
    } 

    @Embed 
    @Data 
    @NoArgsConstructor 
    public static final class NestedClassWithEnum { 
    ParticipantType type; 

    } 

    public enum ParticipantType { 
    ORGANIZER, 
    REGISTERED, 
    WAIT_LISTED 
    } 
} 

Compiliert ohne Fehler:

$ javac -classpath /home/avaliani/projects/jars/objectify-4.0b2.jar:/home/avaliani/projects/jars/lombok.jar test/AnnotationBug.java 

Dinge hinweisen:

1) die Zeilennummer des Kompilation Ausfalls Hinweis. Es gibt kein Problem, die Annotation von NestedClassNoEnum zu analysieren.

2) Java-Version:

$ java -version 
java version "1.7.0_21" 
OpenJDK Runtime Environment (IcedTea 2.3.9) (7u21-2.3.9-0ubuntu0.12.10.1) 
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode) 
+3

Haben Sie versucht, eine/einige/alle Anmerkungen zu entfernen, um zu sehen, ob Sie sie auf eine davon isolieren können? Zum Beispiel scheint dies Ihre einzige Verwendung von '@ Embed' und' @ NoArgsConstructor' in Ihrem verbundenen Code zu sein, vielleicht ist es etwas mit ihnen. Können Sie es in einer viel kleineren, einfacheren Klasse reproduzieren? – ajp15243

+0

Hallo @ ajp15243. Danke für deine Nachricht. Ich habe den Testfall in einen eigenständigen Testfall geändert. Beachten Sie, dass ich versucht habe, die Einbettung-Annotation zu entfernen, und der Compiler die NoArgsConstructor- und Data-Annotationen nicht kompilieren konnte. Ich bin ziemlich sicher, dass das Problem nicht bei den Anmerkungen liegt. – Amir

+0

@Amir In der Tat, mein Fehler - Ich habe Ihr erstes Beispiel neu erstellt, indem ich den Code der Annotationen der Bibliotheken, auf die Sie sich beziehen, kopiert habe und sie auf oracle jdk 7u10 gut zusammengestellt hat. Sieht nach einem Fehler aus. – assylias

Antwort

8

Wenn Sie den Import von statischer Klasse entfernen, wird der Code kompiliert fein, finden Sie im folgenden Code [Anmerkung: Ich habe nicht verwendet @Embed Anmerkung, wie ich nicht Glas aufweist, wurde für sie, aber es wird keinen Unterschied machen]:

//import NestedClassWithEnum.ParticipantType; 
import lombok.Data; 
import lombok.NoArgsConstructor; 


public class AnnotationBug { 

    NestedClassWithEnum.ParticipantType type; 


    @Data 
    @NoArgsConstructor 
    public static final class NestedClassNoEnum { 
    } 


    @Data 
    @NoArgsConstructor 
    public static final class NestedClassWithEnum { 
     ParticipantType type; 

     public enum ParticipantType { 
      ORGANIZER, 
      REGISTERED, 
      WAIT_LISTED 
     } 
    } 
} 

Grund scheint classloading von enumns und statische Klassen zusammenhängen. Enums are eagerly loaded wo als statische Klassen träge geladen werden. So könnte Java versuchen, zur Kompilierzeit selbst zu stoppen, aber es ist eine Vermutung.

EDIT: Wie im Gespräch mit Paul, ist oben raten nicht korrekt.

+0

Classloading tritt zur Laufzeit auf, und dies ist ein Problem bei der Kompilierung. +1 für die Beobachtung obwohl. –

+0

@PaulBellora: was ich damit sagen will ist, dass enums eifrig geladen sind [http://stackoverflow.com/questions/9408322/java-lazy-loading-of-enum-instances], wo statische Klassen träge geladen werden. So könnte Java versuchen, zur Kompilierzeit selbst zu stoppen, aber es ist eine Vermutung. – Lokesh

+0

Sie könnten diesen Beitrag missverstehen. Enum * -Konstanten * werden eifrig geladen, sobald die enum-Klasse geladen ist (sie sind Teil von static init). Aber eine Enum-Klasse selbst wird nicht anders als die anderen Klassen geladen. –

Verwandte Themen