Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javac fails to compile annotations on static nested classes that have a public enum

Tags:

java

lombok

I encountered the following javac compilation failure where javac did not recognize annotations on a static nested class that had a public enum. Once I moved the enum out of the static nested class the compilation errors were resolved. Does anyone know why javac failed? Is this a java compiler bug? Or is there a java nuance that I am unaware of?

Below is a standalone test case.

Fails to compile:

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 output:

$ 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

Compiles:

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
  }
}

Compiles without errors:

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

Things to point out:

1) Note the line number of the compilation failure. There is no problem parsing NestedClassNoEnum's annotation.

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)
like image 369
Amir Avatar asked May 21 '13 20:05

Amir


2 Answers

If you remove the import of static class, the code compiles fine, see the below code[Note: i have not used @Embed annotation as i was not having jar for it but it will not make any difference]:

//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
        }
    }
}

Reason seems to be related to classloading of enumns and static classes. Enums are eagerly loaded where as static classes are loaded lazily. So java might be trying to stop at compile time itself, but its a guess.

EDIT: As per discussion with paul, above guess is not correct.

like image 147
Lokesh Avatar answered Nov 02 '22 05:11

Lokesh


This is a Lombok bug. See https://github.com/rzwitserloot/lombok/issues/1249 for the official bug report.

like image 41
Gili Avatar answered Nov 02 '22 05:11

Gili