Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.lang.NoSuchMethodError: 'org.eclipse.core.resources.IProject org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest.getProject()' #918

Closed
kwin opened this issue Sep 20, 2022 · 14 comments

Comments

@kwin
Copy link
Member

kwin commented Sep 20, 2022

Due to this commit c3ade99#diff-9673d52c15edc7a4a06b4de0e0ac93f73952e7b69f05cc1d1c1fd2653655a4bb the class ProjectConfigurationRequest does no longer expose a getProject() method.

As none of the methods of ProjectConfigurationRequest apart from getMavenSession(...) in the previous commit https://github.com/eclipse-m2e/m2e-core/blob/fa8a40ba94473380c5c8a7f95555bcf5fda74e11/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/ProjectConfigurationRequest.java were deprecated I consider this a mistake.

Otherwise all downstream consumers, e.g. https://github.com/apache/sling-ide-tooling/blob/93bcb69fe7cfad6b68d5caf838a14d3bdf887b92/eclipse/eclipse-m2e-ui/src/org/apache/sling/ide/eclipse/m2e/internal/AbstractBundleProjectConfigurator.java#L48 would need to be changed to be compatible with m2e 2.x.

Configuring a Maven project in m2e 2.x leads to the following exception with that plugin:

java.lang.NoSuchMethodError: 'org.eclipse.core.resources.IProject org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest.getProject()'
	at org.apache.sling.ide.eclipse.m2e.internal.AbstractBundleProjectConfigurator.configure(AbstractBundleProjectConfigurator.java:48)
	at org.eclipse.m2e.core.project.configurator.AbstractLifecycleMapping.configure(AbstractLifecycleMapping.java:125)
	at org.eclipse.m2e.core.internal.project.ProjectConfigurationManager.lambda$6(ProjectConfigurationManager.java:475)
	at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.executeBare(MavenExecutionContext.java:350)
	at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:262)
	at org.eclipse.m2e.core.internal.project.ProjectConfigurationManager.updateProjectConfiguration(ProjectConfigurationManager.java:469)
	at org.eclipse.m2e.core.internal.project.ProjectConfigurationManager.lambda$4(ProjectConfigurationManager.java:413)
	at java.base/java.util.Collection.removeIf(Collection.java:576)
	at org.eclipse.m2e.core.internal.project.ProjectConfigurationManager.updateProjectConfiguration0(ProjectConfigurationManager.java:407)
	at org.eclipse.m2e.core.internal.project.ProjectConfigurationManager.lambda$3(ProjectConfigurationManager.java:339)
	at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.executeBare(MavenExecutionContext.java:350)
	at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:262)
	at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:205)
	at org.eclipse.m2e.core.internal.embedder.MavenImpl.execute(MavenImpl.java:1093)
	at org.eclipse.m2e.core.internal.project.ProjectConfigurationManager.updateProjectConfiguration(ProjectConfigurationManager.java:338)
	at org.eclipse.m2e.core.ui.internal.UpdateMavenProjectJob.runInWorkspace(UpdateMavenProjectJob.java:80)
	at org.eclipse.core.internal.resources.InternalWorkspaceJob.run(InternalWorkspaceJob.java:43)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)

The same is true for the no-longer existing methods getPom() and getResolverConfiguration().

@laeubi
Copy link
Member

laeubi commented Sep 20, 2022

Otherwise all downstream consumers [...] would need to be changed to be compatible with m2e 2.x.

2.x is a breaking change and consumers need to adapt. Actually it is invalid to import API with open version range and should always exclude the next major version as per https://enroute.osgi.org/FAQ/210-semantic_versioning.html

@kwin
Copy link
Member Author

kwin commented Sep 20, 2022

Changing API without deprecating it before is very consumer/developer unfriendly. I would assume that due to this change 99% of the custom project configurators are broken with 2.x

@laeubi
Copy link
Member

laeubi commented Sep 20, 2022

As said, any connector needs to adapt to the new API whether or not it was deprecated. So 100% of m2e connectors actually need to adapt to the new 2.x API.

And as said, the correct version range for any consumer prior to 2.x was [1.x, 2). Adopters should change this after upgrading to [2, 3)

@kwin
Copy link
Member Author

kwin commented Sep 20, 2022

Actually it is invalid to import API with open version range and should always exclude the next major version as per https://enroute.osgi.org/FAQ/210-semantic_versioning.html

OSGi mandates exported package versions, but m2e core exports packages without an explicit version (leading to the default 0.0.0 being assumed, https://docs.osgi.org/specification/osgi.core/7.0.0/framework.module.html#framework.module.exportpackage). That leads to open range import-package statements in consumers.

@laeubi
Copy link
Member

laeubi commented Sep 20, 2022

OSGi mandates exported package versions, but m2e core exports packages without an explicit version

Contributions are welcome :-)

@kwin
Copy link
Member Author

kwin commented Sep 20, 2022

The readme says for 2.x

This major release improves (and cleans up) various legacy APIs. ("https://github.com/eclipse-m2e/m2e-core/blob/master/RELEASE_NOTES.md#multiple-api-breakage)

I was assuming that legacy was marked as deprecated before, otherwise how should consumers know which parts of the API m2e core developers consider legacy? Even in semantic versioning it is good practice to first deprecate in a minor version before you remove, otherwise you don't give consumers time to adapt.

@kwin
Copy link
Member Author

kwin commented Sep 20, 2022

And as said, the correct version range for any consumer prior to 2.x was [1.x, 2).

Which OSGi instruction are you referring to? https://docs.osgi.org/specification/osgi.core/7.0.0/framework.module.html#framework.module.requirebundle is IMHO worst practice and the version range is just plain wrong for Import-Package as outlined above.

@laeubi
Copy link
Member

laeubi commented Sep 20, 2022

As said 2.x requires adjustments, to existing APIs, to replaced API and maybe anything else. From 2.0 on we again try to maintain backward compatibility as much as possible, but we won't add anything back if there is a replacement.

Part of 2.x was the movement to Java 17 and some of its new language constructs (records) that are most likely binary incompatible with any pre 1.x API.

@kwin
Copy link
Member Author

kwin commented Sep 20, 2022

Part of 2.x was the movement to Java 17 and some of its new language constructs (records) that are most likely binary incompatible with any pre 1.x API.

Good point, this indeed is true to records (https://docs.oracle.com/javase/specs/jls/se17/html/jls-13.html#jls-13.4.27 wich are in no way backwards compatible (even with simple getter methods of classes), so writing a plugin which is compatible with 1.x as well as 2.x is just not possible as it requires recompilation. In the future to ease a transitioning phase you should do a release in between which already has the new API but keeps the old one (as deprecated) otherwise with 3.x again everything will stop working....

@laeubi
Copy link
Member

laeubi commented Sep 20, 2022

If anyone step up to support this use-case probably yes ... in general I don't see we can/will support spawning multiple major versions will become any goal of current m2e commiters ...

@laeubi laeubi closed this as completed Sep 20, 2022
@eric-milles
Copy link

There, backwards compatible. Was that so hard?

public record ProjectConfigurationRequest(IMavenProjectFacade mavenProjectFacade, MavenProject mavenProject) {
  @Deprecated
  public IMavenProjectFacade getMavenProjectFacade() {
    return mavenProjectFacade();
  }
  @Deprecated
  public MavenProject getMavenProject() {
    return mavenProject();
  }
  @Deprecated
  public IFile getPom() {
    return mavenProjectFacade().getPom();
  }
  @Deprecated
  public IProject getProject() {
    return mavenProjectFacade().getProject();
  }
  @Deprecated
  public ResolverConfiguration getResolverConfiguration() {
    return mavenProjectFacade().getResolverConfiguration();
  }
}

@HannesWell
Copy link
Contributor

There, backwards compatible. Was that so hard?

Feel free to create a PR and contribute it. ;)

But please add a note about when those then deprecated getters are planned to be removed. I'm interested when you think we we should better break the API if not with a major version increment?

And keep in mind that the main problem is that many connectors or in general consumers are unmaintained, so any kind of change will break them. Even the version bump to 2.0 alone can break unmaintained consumers, if they require m2e version [1.x,2). If one manages to adjust the version range, adjusting those getters is trivial. So while this might fix your case it will not solve all problems.
Because we cannot maintain a full backward-compatible API it IMHO does not really make sense to try hard to keep as much as possible compatible. Either a version is backwards-compatible or not. Being 'partly' backward-compatible only gives the false impression that requiring m2e [1.x,3) is save and therefore contradicts the purpose of semantic versioning.

@mickaelistria
Copy link
Contributor

But please add a note about when those then deprecated getters are planned to be removed. I'm interested when you think we we should better break the API if not with a major version increment?

We clearly won't accept in a good shape project additional deprecated API. It's just too late to think about backward-compatibility, interested parties should have considered that earlier and voiced before we released 2.0.

@laeubi
Copy link
Member

laeubi commented Oct 8, 2022

But please add a note about when those then deprecated getters are planned to be removed. I'm interested when you think we we should better break the API if not with a major version increment?

We clearly won't accept in a good shape project additional deprecated API. It's just too late to think about backward-compatibility, interested parties should have considered that earlier and voiced before we released 2.0.

I agree, a major release is not and will never be backward compatible (otherwise it won't require a major release). Also as noted above, it won't be binary backward compatible so a project needs to adjust anyways...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants