Maven 编译失败并显示 "cannot find symbol",而使用 Eclipse,它编译

Maven compilation fails with "cannot find symbol" while with Eclipse, it compiles

我在 Maven 中遇到编译错误,但在 Eclipse 中一切正常。

是我做错了什么还是 Maven 错误?

我已经创建了一个代码片段,因此您可以尝试重现它。

这是 Java 源文件和一个 pom.xml。

package p1;

import p1.A.D.C;
import p1.p2.E;

public class A {
    interface B<T> {
        T methodB();
    }

    class D implements B<E> {
        C c = new C();

        public C getC() {
            return c;
        }

        class C {
            public void methodC() {
                System.out.println(this);
            }
        }

        @Override
        public E methodB() {
            return new E();
        }
    }

    public void methodA() {
        D d = new D();
        d.methodB();
        C c = d.getC();
        c.methodC();
    }

    public static void main(String[] args) {
        A a = new A();
        a.methodA();
    }
}


package p1.p2;

public class E {
}


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>mvntst</groupId>
  <artifactId>test</artifactId>
  <version>0</version>
  <packaging>jar</packaging>
  <name>mvntst</name>
</project>

当我 运行 mvn clean compile 时,我得到这个输出:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project test: Compilation failure
[ERROR] /C:/dev/test/CompilerTest/MavenTest/src/main/java/p1/A.java:[6,30] cannot find symbol
[ERROR] symbol:   class E                                                                                                                       
[ERROR] location: class p1.A
[ERROR] -> [Help 1]                                                                                                                             
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.                                                             
[ERROR] Re-run Maven using the -X switch to enable full debug logging.                                                                          
[ERROR]                                                                                                                                         
[ERROR] For more information about the errors and possible solutions, please read the following articles:                                       
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

这是 mvn --version 的结果:

Apache Maven 3.3.1 (cab6659f9874fa96462afef40fcf6bc033d58c1c; 2015-03-13T23:10:27+03:00)
Maven home: C:\dev\apache-maven-3.3.1\bin\..
Java version: 1.8.0_40, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk1.8.0_40\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 7", version: "6.1", arch: "amd64", family: "dos"

如果您反转 导入顺序...

import p1.p2.E;
import p1.A.D.C;

...它会编译得很好。这可能是由于编译器假定文件夹 A、D 和 C 存在于 p1 下,但事实并非如此。

但与其这样做(感觉 不对),您应该改变在 methodA 中引入 C 的方式。

public void methodA() {
    D d = new D();
    d.methodB();
    D.C c = d.getC();
    c.methodC();
}

您也可以删除内部 class 的导入,因为上面的内容不再需要它。

我同意另一个回答 "import p1.A.D.C;" 感觉 错误并且会使读者感到困惑,但从技术上讲这毕竟可能没问题:

首先,请注意,从看到 "import p1.A.D.C" 来看,编译器跳到 p1.A.D 必须是一个包的结论是错误的(如其他答案中所建议的)。完全可以通过限定名称导入嵌套类型。

示例是否合法Java取决于我们如何解释JLS 7.5.1中的这句话:

If the type imported by the single-type-import declaration is declared in the compilation unit that contains the import declaration, the import declaration is ignored.

从字面上理解这句话意味着编译器简单地忽略 C 的导入,导致编译错误针对 methodA() 中的不合格引用 "C"

这不是任何编译器报告的内容。

Eclipse 似乎将 JLS 语句解释为请求忽略来自同一编译单元的任何 冗余 导入 toplevel 类型。嵌套类型的导入在此解释中并不多余,可用于通过其非限定名称成功解析 C。

Javac 似乎 丢弃后续导入 ,即 C 的导入是 ,但不相关的导入因为 E 被丢弃。这似乎是最合理的解释,为什么更改导入顺序会更改编译器结果,这在 JLS 中没有任何支持。 此外,当翻转导入顺序时,javac 似乎与 Eclipse 的解释一致,因为即使从同一编译单元导入嵌套类型也是有用的,不应忽略。

因此: javac 似乎很困惑(也就是有一个错误)。

首先尝试 mvn clean 如果运行成功然后尝试 mvn install。如果这工作正常,那么您可以尝试 mvn compile。这个过程对我有用。