Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eclipse Mars consistently fails resolving imports after saving, but cleaning projects alone solves

This started to happen to me and all my teammates at some point and we cannot figure out what is that triggered that and how to solve that.
We all have the same Java projects in our workspaces. In Project menu we all have Build automatically ticked.
Let's say that my workspace has no compilation errors. I make a trivial change to one of the Java classes, I save, Eclipse starts rebuilding and the result is that hundreds of classes - in more than one project - have now compilation errors. That is because for some reason a lot of import statements now show the error The import [xxx] cannot be resolved.
But those imports (and the whole workspace for that matter) were perfectly error-free before I saved my trivial, completely unrelated change, and they all go back to being perfectly error-free if at this point I just do Project / Clean which of course triggers a workspace rebuild.

The .log file in the workspace folder doesn't show anything; if it's empty before I save, it's still empty after my save caused those errors to appear.

This is way more annoying than it might sound, because building the whole workspace can take minutes, and since a mere Project / Clean makes all failing imports work again this cannot be due to something wrong in our code.

I know this is a long shot but considering how reproducible this issue is for us (100% of the times on 100% of the several computers involved) maybe someone else had the same problem and discovered the cause or a solution.

The version is Eclipse Java EE IDE for Web Developers, Mars.1 Release (4.5.1), on Windows 8.

We use Gradle (2.6) by creating External Tool Configurations that point to gradlew.bat and with a string prompt. We run those manually to configure the projects after importing them into Eclipse (by entering eclipse in the string prompt) and to build the JARs for the deployment (by entering build in the string prompt), however I don't think Gradle is involved in the problematic build by Eclipse.

ADDED: I'm no longer sure it's accurate to say that this problem is 100% reproducible, because the following happens:

  • Initial state: no errors present (which can only be because I cleaned all projects) and no unsaved changes.

  • I make a change to a class in the editor, I save and that generates the errors.

  • I undo that change, save and clean; so I'm back to exactly the initial state.

  • I redo that change (identical), I save and this time I don't get the errors.

ADDED: Using javap to inspect the generated .class files, I notice the 2 following things:

1) Minor and major versions are always the same no matter the .class file got built with the errors or without (minor version: 0; major version: 51). Of course when the .class file is built with the errors it contains the error messages while when it's built without the errors it doesn't contain the error messages.

2) Comparing the outputs of javap for both .class files, I see that in the "Constant pool" section the lines are identical (showing names of class members and objects, f.ex. Ljava/lang/String;) up until a line about a class my.package.MyClassImpl where the problematic .class file has

#32 = Utf8 LMyClassImpl;

and the correct .class file has the same but fully qualified:

#32 = Utf8 Lmy.package.MyClassImpl;

I'm sure this has to do with the problem.

ADDED: The problem disappears if I tick the “Rebuild class files modified by others” checkbox in Eclipse preferences under Java / Compiler / Building / Output folder. At least all the cases where a certain change was showing the problem don't show it any longer. This is just a workaround and I'm keeping investigating the root cause, however this hints strongly towards Eclipse’s internal Java compiler playing a major role in this problem.

ADDED: Below is the content of the .classpath and .project files of two of the projects. The first project is one that shows those compilation errors. The second project is one that never does. I had to replace many lines with .... in one file because of the 30.000 chars limit and I can't seem to be able to find how to attach files; if that is allowed and someone points me to how to do that I will attach them without cuts and remove their content from the question.

Note the interesting difference that the first .classpath has an entry excluding="**/*.class" and the second doesn't. However when I modify the Java Build Path of all the projects that have that through Eclipse (Project Properties / Java Build Path / Source) removing their excluded:**/*.class the resulting .classpath files don't have that entry but the compilation errors appear anyway (also after restarting Eclipse). And if I do the opposite (i.e. add excluded:**/*.class to all projects that don't have it) then the .classpath files of all the projects get that entry but the compilation errors still show up. I would have bet that this would solve the problem but it doesn't.

MyProjectThatGetsErrors: .project file:

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    <name>MyProjectThatGetsErrors</name>
    <comment/>
    <projects/>
    <natures>
        <nature>org.eclipse.jdt.core.javanature</nature>
    </natures>
    <buildSpec>
        <buildCommand>
            <name>org.eclipse.jdt.core.javabuilder</name>
            <arguments/>
        </buildCommand>
    </buildSpec>
    <linkedResources/>
</projectDescription>

MyProjectThatGetsErrors: .classpath file:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry excluding="**/*.class" kind="src" path="src/main/java"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
    <classpathentry kind="src" path="/MyUtilsProject1"/>
    <classpathentry kind="src" path="/MyUtilsProject2"/>
    <classpathentry kind="lib" path="C:/Users/Me/.gradle/caches/modules-2/files-2.1/org.eclipse.jetty/jetty-io/8.1.15.v20140411/8849cf59187275366cd05f37b2fb71319291370b/jetty-io-8.1.15.v20140411.jar" sourcepath="C:/Users/Me/.gradle/caches/modules-2/files-2.1/org.eclipse.jetty/jetty-io/8.1.15.v20140411/49fd78caf4ca0c7cdbc532fc48ff46183bb8fb62/jetty-io-8.1.15.v20140411-sources.jar"/>
....
....
    <classpathentry kind="lib" path="D:/EclipseMars/git/MyProjectThatGetsErrors/lib/tapestry5-highcharts-1.2.0.jar"/>
    <classpathentry kind="output" path="bin"/>
</classpath>

MyUtilsProject1: .project file:

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    <name>MyUtilsProject1</name>
    <comment/>
    <projects/>
    <natures>
        <nature>org.eclipse.jdt.core.javanature</nature>
    </natures>
    <buildSpec>
        <buildCommand>
            <name>org.eclipse.jdt.core.javabuilder</name>
            <arguments/>
        </buildCommand>
    </buildSpec>
    <linkedResources/>
</projectDescription>

MyUtilsProject1: .classpath file:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" path="src/main/java"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
    <classpathentry kind="lib" path="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-digester/commons-digester/1.8/dc6a73fdbd1fa3f0944e8497c6c872fa21dca37e/commons-digester-1.8.jar" sourcepath="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-digester/commons-digester/1.8/6c296de7dc352e0af9a40f92f5af995314d41fc9/commons-digester-1.8-sources.jar"/>
    <classpathentry kind="lib" path="C:/Users/Me/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.3.2/90a3822c38ec8c996e84c16a3477ef632cbc87a3/commons-lang3-3.3.2.jar" sourcepath="C:/Users/Me/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.3.2/d2a489573c0ed2c4942b3660decad5d65087b406/commons-lang3-3.3.2-sources.jar"/>
    <classpathentry kind="lib" path="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-configuration/commons-configuration/1.6/32cadde23955d7681b0d94a2715846d20b425235/commons-configuration-1.6.jar" sourcepath="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-configuration/commons-configuration/1.6/2d24067548bf9022d03cfd6ca302e1f6c5d4936/commons-configuration-1.6-sources.jar"/>
    <classpathentry kind="lib" path="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-fileupload/commons-fileupload/1.2/a10c06183fe21f3bb3dda3b5946b93db6e2ad5cc/commons-fileupload-1.2.jar" sourcepath="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-fileupload/commons-fileupload/1.2/c7859b375ae5bc1b4a4f2b91ce6d1d387e676e61/commons-fileupload-1.2-sources.jar"/>
    <classpathentry kind="lib" path="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-beanutils/commons-beanutils-core/1.8.0/175dc721f87e4bc5cc0573f990e28c3cf9117508/commons-beanutils-core-1.8.0.jar"/>
    <classpathentry kind="lib" path="C:/Users/Me/.gradle/caches/modules-2/files-2.1/org.apache.velocity/velocity/1.7/2ceb567b8f3f21118ecdec129fe1271dbc09aa7a/velocity-1.7.jar" sourcepath="C:/Users/Me/.gradle/caches/modules-2/files-2.1/org.apache.velocity/velocity/1.7/eb11eb70171ed64842b2e5216d5904e21ed162ac/velocity-1.7-sources.jar"/>
    <classpathentry kind="lib" path="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-collections/commons-collections/3.2.1/761ea405b9b37ced573d2df0d1e3a4e0f9edc668/commons-collections-3.2.1.jar" sourcepath="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-collections/commons-collections/3.2.1/fa095ef874374e5b2a11f8b06c26a5d68c7cb3a4/commons-collections-3.2.1-sources.jar"/>
    <classpathentry kind="lib" path="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-beanutils/commons-beanutils/1.7.0/5675fd96b29656504b86029551973d60fb41339b/commons-beanutils-1.7.0.jar" sourcepath="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-beanutils/commons-beanutils/1.7.0/b68c4fc66026e8c08df7fb57c7dc1e94a6ed8cbb/commons-beanutils-1.7.0-sources.jar"/>
    <classpathentry kind="lib" path="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-lang/commons-lang/2.4/16313e02a793435009f1e458fa4af5d879f6fb11/commons-lang-2.4.jar" sourcepath="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-lang/commons-lang/2.4/2b8c4b3035e45520ef42033e823c7d33e4b4402c/commons-lang-2.4-sources.jar"/>
    <classpathentry kind="lib" path="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-logging/commons-logging/1.1.1/5043bfebc3db072ed80fbd362e7caf00e885d8ae/commons-logging-1.1.1.jar" sourcepath="C:/Users/Me/.gradle/caches/modules-2/files-2.1/commons-logging/commons-logging/1.1.1/f3f156cbff0e0fb0d64bfce31a352cce4a33bc19/commons-logging-1.1.1-sources.jar"/>
    <classpathentry kind="lib" path="D:/EclipseMars/git/MyUtilsProject1/lib/MyCompany cayenne-client-3.0.2.jar"/>
    <classpathentry kind="output" path="bin"/>
</classpath>

ADDED: When I switch to a different Git branch or pull changes into my workspace, which of course causes those compilation errors to appear, sometimes Eclipse shows an error dialog about a NullPointerException in the Java Builder, and in that case it does write it in the log (see stacktrace below). However 99% of the times when those errors show up there is no such null pointer.

!ENTRY org.eclipse.core.resources 4 75 2015-11-10 13:51:31.544
!MESSAGE Errors occurred during the build.
!SUBENTRY 1 org.eclipse.jdt.core 4 75 2015-11-10 13:51:31.544
!MESSAGE Errors running builder 'Java Builder' on project 'MyProject'.
!STACK 0
java.lang.NullPointerException
    at org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding$2.compare(ReferenceBinding.java:92)
    at org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding$2.compare(ReferenceBinding.java:1)
    at java.util.TimSort.binarySort(TimSort.java:265)
    at java.util.TimSort.sort(TimSort.java:208)
    at java.util.Arrays.sort(Arrays.java:727)
    at org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding.sortFields(ReferenceBinding.java:217)
    at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.fields(BinaryTypeBinding.java:946)
    at org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding.fields(ParameterizedTypeBinding.java:458)
    at org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding.getField(ParameterizedTypeBinding.java:643)
    at org.eclipse.jdt.internal.compiler.lookup.Scope.findField(Scope.java:1371)
    at org.eclipse.jdt.internal.compiler.ast.FieldDeclaration.resolve(FieldDeclaration.java:194)
    at org.eclipse.jdt.internal.compiler.lookup.FieldBinding.constant(FieldBinding.java:215)
    at org.eclipse.jdt.internal.compiler.lookup.FieldBinding.constant(FieldBinding.java:240)
    at org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference.getOtherFieldBindings(QualifiedNameReference.java:729)
    at org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference.resolveType(QualifiedNameReference.java:1079)
    at org.eclipse.jdt.internal.compiler.ast.ReturnStatement.resolve(ReturnStatement.java:341)
    at org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.resolveStatements(AbstractMethodDeclaration.java:641)
    at org.eclipse.jdt.internal.compiler.ast.MethodDeclaration.resolveStatements(MethodDeclaration.java:309)
    at org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.resolve(AbstractMethodDeclaration.java:551)
    at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.resolve(TypeDeclaration.java:1188)
    at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.resolve(TypeDeclaration.java:1301)
    at org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.resolve(CompilationUnitDeclaration.java:590)
    at org.eclipse.jdt.internal.compiler.Compiler.process(Compiler.java:861)
    at org.eclipse.jdt.internal.compiler.ProcessTaskManager.run(ProcessTaskManager.java:141)
    at java.lang.Thread.run(Thread.java:744)
like image 533
SantiBailors Avatar asked Nov 02 '15 11:11

SantiBailors


People also ask

How do I fix error import Cannot be resolved?

Whenever you come across this problem just go to Project > Clean, then select Clean all projects. It should get resolved, otherwise try to delete those jars and add them again.

Can not be resolved to a type java?

This means that your project isn't setup to include the JUnit libraries when it compiles; JUnit is not included in the Java runtime libraries (JRE System Library) so you have to add it to the build path.


1 Answers

I suspect the root of your problem is due to the fact that you're trying to use Gradle to tell Eclipse how Eclipse should configure your projects. There is a bit of conflict between Gradle (or Maven) and Eclipse; unfortunately, the Gradle (and Maven) teams have pushed the idea that the build tool is good for generating IDE configurations, when in fact they're not very good at it. The IDE (and developer using it) should be responsible for creating and managing its project configuration files.

Eclipse has Gradle tooling that you can install and knows exactly how to configure and maintain your Eclipse projects correctly based on the build.gradle files in them. It's called Buildship. I strongly recommend you install Buildship and use it to import the projects into your Eclipse workspace. It will properly set up a Classpath Container that stays in sync with the dependencies listed in your build files, as well as properly coordinate the work that Eclipse's compiler needs to do and the work that Gradle itself needs to do so they don't conflict with each other.

It also provides a nice Gradle tasks view that you can use to easily invoke Gradle tasks from within Eclipse (replacing your homemade External Tools configuration).

like image 96
E-Riz Avatar answered Oct 10 '22 08:10

E-Riz