Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven compilation failure when switching on enum

I am mavenifying (is that a word?) a project whose build process has been so far based entirely on ant/shell scripts.

Consider the following enum

public enum ResourceType {
    A, B;
}

The following bean:

public ResourceTypeOwner {
    //set get resourceType property
}

And the following code snippet:

void foo(ResourceTypeOwner rto) {
    ResourceType resourceType = rto.getResourceType();
    switch (resourceType) {
    case A:
        handleA(resourceType); break;
    case B:
        handleB(resourceType); break;
    default:
        throw new RuntimeException("Unsupported resource type");
    }
}

I am getting a compilation error when building with maven:

Cannot switch on a value of type ResourceType. Only convertible int values or enum variables are permitted

The pom.xml has the following plugin configuration for compiling

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.0</version>
        <configuration>
            <compilerId>eclipse</compilerId>
            <compilerVersion>1.6</compilerVersion>
            <source>1.6</source>
            <target>1.6</target>
        </configuration>
        <dependencies>
            <dependency>
                <groupId>org.codehaus.plexus</groupId>
                <artifactId>plexus-compiler-eclipse</artifactId>
                <version>2.2</version>
            </dependency>
        </dependencies>
    </plugin>
...
</plugins>

Both ant (with org.eclipse.jdt.core.JDTCompilerAdapter) and eclipse build/compile fine. I am obviously doing something wrong (unless it's an unreported maven-compiler-plugin or plexus-compiler-eclipse plugin bug, which is somewhat unlikely, switching on enums is neither bad nor rocket science). Does anybody have an idea?

Additional environment details

$mvn -version Apache Maven 3.0.4 (r1232337; 2012-01-17 10:44:56+0200) Maven home: /home/d/dev/tools/apache-maven-3.0.4 Java version: 1.6.0_35, vendor: Sun Microsystems Inc. Java home: /opt/jdk1.6.0_35/jre Default locale: en_US, platform encoding: UTF-8 OS name: "linux", version: "3.2.0-40-generic", arch: "amd64", family: "unix"

UPDATE:

Standard JDK compiler compiles the specific class successfully. Looks like an plexus-compiler-eclipse 2.2 issue.

like image 341
dkateros Avatar asked Oct 05 '22 03:10

dkateros


1 Answers

I was able to reproduce and found the problem.

Turns out that the setting org.eclipse.jdt.core.compiler.compliance needs to be set to the target version in order for it to be able to recognize java.lang.Enum.

This setting is only set by plexus-compiler-eclipse when both targetVersion AND optimize is set. [1]

Modify your pom like this and it should work:

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version> <!-- or 3.0 -->
    <configuration>
        <compilerId>eclipse</compilerId>
        <source>1.6</source>
        <target>1.6</target>
        <optimize>true</optimize>   <!-- add this line! -->

I'm not sure why it was decided in plexus-compiler-eclipse that optimization would affect the compliance level, so this is in fact a workaround.

Also, this code is enough to trigger the issue:

class Foo {
    static enum MyEnum { A }

    void foo() {
        switch ( MyEnum.A ) { case A: }
    }
}

[1] https://github.com/sonatype/plexus-compiler/blob/master/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EclipseJavaCompiler.java#L156

like image 128
Kenney Avatar answered Oct 10 '22 12:10

Kenney