【问题标题】:Maven compilation failure when switching on enum打开枚举时Maven编译失败
【发布时间】:2013-05-07 10:02:17
【问题描述】:

我正在简化(这是一个词吗?)一个项目,其构建过程迄今为止完全基于 ant/shell 脚本。

考虑以下枚举

public enum ResourceType {
    A, B;
}

以下bean:

public ResourceTypeOwner {
    //set get resourceType property
}

还有如下代码sn-p:

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");
    }
}

使用 maven 构建时出现编译错误:

无法打开 ResourceType 类型的值。只能转换 int 允许使用值或枚举变量

pom.xml 有如下插件配置供编译

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

ant(使用 org.eclipse.jdt.core.JDTCompilerAdapter)和 eclipse 构建/编译都很好。我显然做错了什么(除非它是一个未报告的 maven-compiler-plugin 或 plexus-compiler-eclipse 插件错误,这有点不太可能,打开枚举既不是坏事也不是火箭科学)。有人有想法吗?

其他环境细节

$mvn -version Apache Maven 3.0.4 (r1232337; 2012-01-17 10:44:56+0200) Maven 主页:/home/d/dev/tools/apache-maven-3.0.4 Java 版本: 1.6.0_35,供应商:Sun Microsystems Inc. Java 主页:/opt/jdk1.6.0_35/jre 默认语言环境:en_US,平台编码:UTF-8 操作系统名称:“linux”,版本:“3.2.0-40-generic”,arch:“amd64”,家族: “unix”

更新:

标准 JDK 编译器成功编译特定类。看起来像 plexus-compiler-eclipse 2.2 问题。

【问题讨论】:

  • 检查你的类路径中是否只有一个ResourceType(包括依赖项)。我相信您还有另一个(常规)同名课程。
  • 我刚刚在整个 mvn 存储库中搜索了具有相同名称的类。没有了。此外,它发生在两个不同的枚举上(这些是在整个项目上打开枚举的唯一情况)。最后将枚举重命名为 ResourceType123456(使用 eclipse 重构)。同样的问题。不过谢谢。
  • 一定要用eclipse编译器吗? jdk 有什么问题?
  • 存在泛型推断的情况,主要是 javac 不允许而 ecj 允许。考虑 foo() 和 bar() 和 foo 在其方法体中调用 bar。 Javac 也强制您将第二个参数添加到 foo 中。我不是建议 foo 应该只有一个类型参数,但我没有编写整个代码库;)
  • 我也有同样的问题。它特定于 eclipse 编译器。

标签: java maven-3 maven-compiler-plugin


【解决方案1】:

我能够重现并发现问题。

原来设置org.eclipse.jdt.core.compiler.compliance需要设置为目标版本才能使用 能够识别java.lang.Enum

只有在设置了targetVersionoptimize 时,plexus-compiler-eclipse 才会设置此设置。 [1]

像这样修改你的 pom,它应该可以工作:

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

我不确定为什么在 plexus-compiler-eclipse 中决定优化会影响合规级别,所以这实际上是一种解决方法。

另外,这段代码足以触发问题:

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

【讨论】:

【解决方案2】:

不要在 Maven 构建中使用 eclipse 编译器。如果您省略该行

    <compilerId>eclipse</compilerId>

一切正常,说明这是eclipse编译器特有的问题。

【讨论】:

  • 我的 maven 配置使用 eclipse 编译器。 Java7 不是一个选项。我不明白为什么 rt1==rt2 只有当枚举是进行切换的类的内部类时。普通的JDK编译具体的类,貌似是plexus-compiler-eclipse插件的bug。
  • @dkateros:对不起,我完全改变了我的答案,因为我发现我被引导到了错误的方向。但正如我所说,不使用eclipse编译器就可以了。或者是否有特殊原因使用它而不是常规 JDK​​?应该始终尝试让 maven 构建 IDE 不可知论。
  • 感谢您的回答。不幸的是,如果没有 eclipse 编译器,构建将失败并出现许多问题:/ 我在 plexus 用户邮件列表上发布了这个问题。
  • eclipse编译器可以读取java 6源码,生成java 5字节码。这与我们有关。
  • dkateros:您能否提供 plexus 用户邮件列表的链接 - 以及您的问题?在也可以找到存档的死链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 2018-11-22
  • 2018-04-07
  • 2011-09-27
相关资源
最近更新 更多