简体   繁体   English

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

[英]Maven compilation fails with “cannot find symbol” while with Eclipse, it compiles

I have a compilation error in Maven but in Eclipse everything goes well. 我在Maven中有一个编译错误但在Eclipse中一切顺利。

Is there something I am doing wrong or is it a Maven bug? 有什么我做错了或是Maven bug吗?

I have created a code snippet, so you can try to reproduce it. 我创建了一个代码片段,因此您可以尝试重现它。

Here are the Java source files and a pom.xml. 以下是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>

When I run mvn clean compile , I get this output: 当我运行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

Here is the result of mvn --version : 这是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"

If you reverse the order of your imports... 如果你颠倒你的进口顺序......

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

...it will compile just fine. ......它会编译得很好。 This is likely due to the compiler presuming that folders A, D and C exist beneath p1 , which isn't the case. 这可能是由于编译器假定文件夹A,D和C存在于p1下面,但实际情况并非如此。

But instead of doing that (which just feels wrong), you should change how you bring in C in methodA . 但不是这样做(这只是感觉错了),你应该改变你带来怎样CmethodA

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

You can also get rid of the import of the inner class as well, since that's no longer necessary with the above. 你也可以摆脱内部类的导入,因为上面不再需要了。

I agree with the other answer that "import p1.ADC;" 我同意另一个答案“进口p1.ADC;” feels wrong and will confuse readers, but technically this may well be OK after all: 感觉不对,会让读者感到困惑,但从技术上讲,这可能是好的:

First, note that from seeing "import p1.ADC" it would be wrong for a compiler to jump to the conclusion that p1.AD must be a package (as suggested in the other answer). 首先,请注意,从看到“import p1.ADC”开始,编译器跳到p1.AD必须是包的结论是错误的(如另一个答案所示)。 It's perfectly OK to import nested types by their qualified name. 通过其限定名称导入嵌套类型是完全可以的。

Whether or not the example is legal Java depends on how we interpret this sentence from JLS 7.5.1: 该示例是否合法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. 如果在包含import声明的编译单元中声明了single-type-import声明导入的类型,则忽略import声明。

Taking this sentence literally would imply that compilers simply ignore the import for C, resulting in a compile error against the unqualified reference "C" within methodA(). 从字面上理解这句话意味着编译器只是忽略了C的导入,导致在methodA()中针对非限定引用“C”的编译错误。

That's not what any of the compiler reports. 这不是任何编译器报告的内容。

Eclipse seems to interpret the JLS sentence as requesting to ignore any redundant imports of toplevel types from the same compilation unit. Eclipse中似乎解释JLS句子请求忽略来自同一编译单元顶层类型的任何多余的进口。 An import of a nested type is not redundant in this interpretation and can be used to successfully resolve C by its unqualified name. 嵌套类型的导入在此解释中并不是多余的,可用于通过其非限定名称成功解析C.

Javac seems to discard the subsequent import , ie, the import for C is used but the unrelated import for E is discarded. javac的似乎放弃后续导入 ,即用于 C中的进口,但对于E的进口无关丢弃。 This appears to be the most plausible explanation why changing the order of imports changes the compiler result, which is not backed by anything in JLS. 这似乎是最合理的解释,为什么更改导入顺序会更改编译器结果,而JLS中的任何内容都不会对其进行备份。 Moreover, when flipping the order of imports javac seems to agree with Eclipse's interpretation, in that an import of a nested type even from the same compilation unit is useful and should not be ignored. 此外,当翻转导入顺序时,javac似乎与Eclipse的解释一致,因为即使从同一个编译单元导入嵌套类型也是有用的,不应该被忽略。

Ergo: javac seems confused (aka has a bug). Ergo: javac似乎很困惑(又名有一个bug)。

First try mvn clean if that runs successfully then try mvn install . 首先尝试mvn clean如果成功运行然后尝试mvn install If this works fine then you can try mvn compile . 如果这样工作正常,那么你可以尝试mvn compile This process worked for me. 这个过程对我有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM