AspectJ compile issues, java8 lambda expression, switch statement

1k Views Asked by At

I am trying to use aspectJ to do AOP programming. But AJC compiler throw errors below, javac compiler works perfectly.

Error:(19, 0) ajc: The method getKey() is undefined for the type Object
Error:(19, 0) ajc: The method getValue() is undefined for the type Object
Error:(22, 0) ajc: Cannot refer to the static enum field ApplicationType.transport within an initializer
Error:(25, 0) ajc: Cannot refer to the static enum field ApplicationType.exposure within an initializer
Error:(28, 0) ajc: Cannot refer to the static enum field ApplicationType.manufacture within an initializer
Error:(31, 0) ajc: Cannot refer to the static enum field ApplicationType.factoryhub within an initializer

My source file is Maps.java ApplicationType.java --

public class Maps {
    public static <K, V> Map<K, V> toMap(Map.Entry<K, V>... entries) {
        return Collections.unmodifiableMap(
          Stream
            .of(entries)
             // compile error The method getKey() is undefined for the type Object
            .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())));
    }
}
ApplicationType.java 
public enum ApplicationType {

    transport(0),
    exposure(1),
    manufacture(2),
    factoryhub(3);

    private int code;

    ApplicationType(int code) {
        this.code = code;
    }

    ApplicationType(String application) {
        for (ApplicationType value : values()) {
            if (value.name().equals(application)) {
                switch (value) {
//ajc: Cannot refer to the static enum field ApplicationType.transport within an initializer
                    case transport:
                        setCode(0);
                        break;
                    case exposure:
                        setCode(1);
                        break;
                    case manufacture:
                        setCode(2);
                        break;
                    case factoryhub:
                        setCode(3);
                        break;
                    default:
                        break;
                }
            }
        }
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }
}
1

There are 1 best solutions below

0
On BEST ANSWER

Fix for

Error:(19, 0) ajc: The method getKey() is undefined for the type Object
Error:(19, 0) ajc: The method getValue() is undefined for the type Object

Reason for above errors is aspectj unable to discover the type of .toMap result. Lambda expressions are evaluated lazily whenever a collect operation is performed. To fix the error, see the variation of the code below. Store the results of .toMap operation explicitly and then user Collections.unmodifiableMap

public static <K, V> Map<K, V> toMap(final Map.Entry<K, V>... entries) {
    Map<K, V> map = Stream.of(entries).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    return Collections.unmodifiableMap(map);
}

Fix for:

Error:(22, 0) ajc: Cannot refer to the static enum field ApplicationType.transport within an initializer

Overloaded constructor Application(String name) for enum looks incorrect. You can simplify your enum code as shown below to get rid of error.

public enum ApplicationType {
    transport(0),
    exposure(1),
    manufacture(2),
    factoryhub(3);

    private int code;

    ApplicationType(int code) {
        this.code = code;
    }

    public static ApplicationType parse(String name) {
        return ApplicationType.valueOf(name.toLowerCase());
    }

    public int getCode() {
        return code;
    }
}

I have added a parse method in case you want the enum back based on name.

Hope this helps.