使用Eclipse时,Maven编译失败并显示“找不到符号”,它编译

时间:2015-12-14 17:33:47

标签: java eclipse maven javac

我在Maven中有编译错误,但在Eclipse中一切顺利。

我做错了什么或是Maven bug?

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

以下是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"

3 个答案:

答案 0 :(得分:3)

如果反转您的导入订单......

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

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

但是,不应该这样做(只是感觉错误),你应该改变CmethodA的引入方式。

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

你也可以摆脱内部类的导入,因为上面不再需要了。

答案 1 :(得分:2)

我同意另一个答案“import p1.A.D.C;” 感觉错误并且会让读者感到困惑,但从技术上讲,这可能是好的:

首先,注意看到“import p1.A.D.C”,编译器跳到p1.A.D必须是一个包的结论是错误的(如另一个答案所示)。按照限定名称导入嵌套类型是完全可以的。

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

  

如果声明了single-type-import声明导入的类型   在包含导入声明的编译单元中   导入声明被忽略。

从字面上理解这句话意味着编译器只是忽略C的导入,导致编译错误针对methodA()中的非限定引用“C”

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

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

Javac似乎丢弃后续导入,即使用了的导入,但是E的无关导入被丢弃。这似乎是最合理的解释,为什么更改导入顺序会更改编译器结果,而JLS中的任何内容都不会对其进行备份。 此外,当翻转导入的顺序时,javac似乎与Eclipse的解释一致,即使从同一编译单元导入嵌套类型也是有用的,不应该被忽略。

Ergo: javac似乎很困惑(又有一个错误)。

答案 2 :(得分:1)

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