eclipse-m2e / m2e-core

Eclipse Public License 2.0
113 stars 116 forks source link

Random "NoSuchMethodError" for "org.eclipse.m2e.core.project.IMavenProjectRegistry.getProjects()" #1820

Closed thahnen closed 3 months ago

thahnen commented 3 months ago

Hey everyone,

I noticed the following error that happens not all the time, but randomly. Which is super confusing:

'org.eclipse.m2e.core.project.IMavenProjectFacade[] org.eclipse.m2e.core.project.IMavenProjectRegistry.getProjects()'
java.lang.NoSuchMethodError: 'org.eclipse.m2e.core.project.IMavenProjectFacade[] org.eclipse.m2e.core.project.IMavenProjectRegistry.getProjects()'
    at org.sonarlint.eclipse.m2e.internal.MavenUtils.getProjectSubProjects(MavenUtils.java:159)
    at org.sonarlint.eclipse.m2e.internal.MavenModuleFilter.getSubProjects(MavenModuleFilter.java:100)
    at org.sonarlint.eclipse.core.internal.backend.FileSystemSynchronizer.getSubProjects(FileSystemSynchronizer.java:270)
    at org.sonarlint.eclipse.core.internal.backend.FileSystemSynchronizer$1.run(FileSystemSynchronizer.java:116)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)

For every project we run the following method and even with debugging it only happens very sporadically and doesn't look deterministic.

public static Collection<ISonarLintProject> getProjectSubProjects(ISonarLintProject project) {
    var modules = new ArrayList<ISonarLintProject>();

    var projectManager = MavenPlugin.getMavenProjectRegistry();

    // If an exception is thrown here due to the SonarLintUtils.adapt(...) returning null, something must be broken on
    // the IDE side as isPartOfHierarchy(...) already made that adaption and the contract is to call it prior to
    // calling this method!
    var slProject = SonarLintUtils.adapt(project.getResource(), IProject.class,
      "[MavenUtils#getProjectSubProjects] Try find Eclipse from '" + project.getName() + "'");
    var projectFacade = projectManager.create(slProject, null);
    if (projectFacade == null) {
      return modules;
    }

    try {
      var parentProject = projectFacade.getMavenProject(null);

      for (var mavenProjectFacade : projectManager.getProjects()) {
        var mavenProject = mavenProjectFacade.getMavenProject(null);
        if (checkIfPossibleParentProject(mavenProject, parentProject)) {
          var possibleSlProject = SonarLintUtils.adapt(mavenProjectFacade.getProject(), ISonarLintProject.class,
            "[MavenUtils#getProjectSubProjects] Try get SonarLint project from '" + mavenProject.getName() + "'");
          if (possibleSlProject != null) {
            modules.add(possibleSlProject);
          }
        }
      }
    } catch (Exception | NoSuchMethodError ex) {
      SonarLintLogger.get().error(ex.getMessage(), ex);
    }

    return modules;
  }

I now put the NoSuchMethodError in the catch block. As I said, for some projects, it has no problems, but rarely it fails. It happens on all the following Eclipse IDE versions and m2e:

Does this ring a bell? For me it doesn't make any sense as the method should be there. For new and older versions of m2e.

Best, Tobias

thahnen commented 3 months ago

I changed the code to the following, and at least from running it like 100 times for now, it didn't appear again. I have little to no clue why it thought that we wanted to have an array as a return value instead of the List<...> :confused:

List<IMavenProjectFacade> projects = projectManager.getProjects();
for (var mavenProjectFacade : projects) {
  // ...
}

Running on Java 11 so I don't know if it is mistaken because of the call in the loop header or because of the usage of var in there.

laeubi commented 3 months ago

Maybe a compiler bug you migth want to report it here: https://github.com/eclipse-jdt/eclipse.jdt.core

thahnen commented 3 months ago

Ah damnit, I found the error. He is me 🤔

Compiled against a newer Version of m2e and ran with an older one. Or Vice versa. The signature was changed somewhere along the way from IMavenProjectFacade[] to List<IMavenProjectFacade>.

I‘ll close this now, but thanks for the hint nevertheless.