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

m2e plugin sometimes "loses" resources - using snapshot 2.1.201.20230809-1423 #1511

Closed
tarioch opened this issue Aug 16, 2023 · 35 comments
Closed

Comments

@tarioch
Copy link

tarioch commented Aug 16, 2023

In some cases, the resources are deleted from the target folder and not copied over again.

e.g. one case I encounter is, if I do any change in the pom file, all my resources disappear until I touch any of the resources or java files.

This is the split up from the issues which are still existing in snapshot 2.1.201.20230809-1423

See #1302 for more details.

Reproduction: #1478

@tarioch
Copy link
Author

tarioch commented Oct 9, 2023

@laeubi anything we can help on getting any progress on this?

@laeubi
Copy link
Member

laeubi commented Oct 9, 2023

@tarioch It actually should have been improved by the last m2e eclipse release, but we can only try to make it less often as the underlying cause is here:

but it hasn't gotten much attention from the maven people yet (and I'm not a maven committer).

@laeubi
Copy link
Member

laeubi commented Oct 9, 2023

Beside that, sponsoring is a good way to get specific issues fixed, so if this is crucial to your business and you likes to speed up the development of m2e in general a sponsoring would allow me to assign more time-slots to bug fixing or contact me for an individual contract for example fixing a specific issue, m2e is sadly manly drive by volunteers working on their (spare) free time so it often takes some time if no one can dedicate time or money.

@tarioch
Copy link
Author

tarioch commented Oct 16, 2023

Thanks for your response. Unfortunately even with latest version it still is still very, very bad. Is there a fundamental change why this issue happens since 2022-12? I haven't seen it before.

@tarioch
Copy link
Author

tarioch commented Oct 25, 2023

Did do some more testing, now used the plain eclipse java installation from eclipse and a very tiny project (empty pom file, one empty class and one dummy resource).

2022-12/m2e 2.1.2

Adding/removing a dependency to the pom.xml doesn't impact the resources, classes don't seem to get recompiled, resources are untouched

2023-03/m2e 2.2.1 (same behavior also in latest 2023-09)

Adding/removing a dependency to the pom.xml does seem to trigger a rebuild, afterwards the resource file is gone and the class file has a newer timestamp

Any idea what the big change in m2e 2.2 was that changed this behavior? From the release notes I saw that there was a change to execute plugins by default in incremental builds and I tried with the setting changed to ignore, but it's still the same behavior.

@lihomev5
Copy link

Did do some more testing, now used the plain eclipse java installation from eclipse and a very tiny project (empty pom file, one empty class and one dummy resource).

2022-12/m2e 2.1.2

Adding/removing a dependency to the pom.xml doesn't impact the resources, classes don't seem to get recompiled, resources are untouched

2023-03/m2e 2.2.1 (same behavior also in latest 2023-09)

Adding/removing a dependency to the pom.xml does seem to trigger a rebuild, afterwards the resource file is gone and the class file has a newer timestamp

Any idea what the big change in m2e 2.2 was that changed this behavior? From the release notes I saw that there was a change to execute plugins by default in incremental builds and I tried with the setting changed to ignore, but it's still the same behavior.

I've downgraded the version to 2.1.2, and it is as normal as you said.
just uninstall it, then use this url: "Eclipse IDE integration for Maven - https://download.eclipse.org/technology/m2e/releases/2.1.2" to install it.
I am using eclipse 2023-09 (4.29.0)

@mickaelistria
Copy link
Contributor

@tarioch if you can create a minimal unit test (similar to what was done in #1478 ) that reproduces the issue, that would help. Then one could just bisect on the changes to find what has caused it and consider futher fixes more easily.

@laeubi
Copy link
Member

laeubi commented Oct 30, 2023

Then one could just bisect on the changes to find what has caused it and consider futher fixes more easily.

I already analyzed that, the problem is that resource-mojo assumes that if a resource never gets deleted from the output without getting it as a "delta" what is not always true and m2e no longer perform such updates because it lead to infinite build cycles, I already proposed a fix but it got less interest and I'm currently not have time to push it forward:

so it does not really help to complain about m2e "not coping" because m2e does never has nor do copy anything...

@HannesWell
Copy link
Contributor

If the maven-resources plugin cannot be fixed.
Maybe we could provide a connector in m2e that helps the plugin to do it right?

@laeubi
Copy link
Member

laeubi commented Nov 10, 2023

If the maven-resources plugin cannot be fixed.

It can be fixed, see PR I just don't have had the time yet to look into the test failure what might just be a changed assumption.

I now also created

to supply a more modern API for file changes.

@laeubi
Copy link
Member

laeubi commented Nov 10, 2023

Maybe we could provide a connector in m2e that helps the plugin to do it right?

THis would require to disable the plugin completely and rewrite all its functionality from scratch...

@OLibutzki
Copy link

I've downgraded the version to 2.1.2, and it is as normal as you said.

I can confirm that downgrading to 2.1.2 solves the issue, but this is not a suitable solution in the long run. m2e 2.1.2 is not compatible to Java 21, so this issue is a blocker for upgrading to the latest Java LTS version.

I already analyzed that, the problem is that resource-mojo assumes that if a resource never gets deleted from the output without getting it as a "delta" what is not always true and m2e no longer perform such updates because it lead to infinite build cycles

I understand that there was a motivation for fixing the infinite build cycle, but at least for our projects the change made the situation even worse. As we have a lot of resources, some of them seem to be midding on the classpath randomly (I am quite sure it's not random, but from an end-user's perspective it feels like that).

I understand that you propose to change the scanner in Maven Filtering, but until that issue is fixed, it would be helpful to get back the old behaviour in order to make m2e useable again.

Maybe you could provide a configuration option to switch the behaviour, so the users can decide for the lesser of two evils:

  • infinite build cycles
  • resources not being copied

@laeubi
Copy link
Member

laeubi commented Nov 21, 2023

That is not really suitable, m2e is not responsible for other maven plugins, if these plugins have bugs these need to be addressed (but not at m2e side). If we install any workaround this will mean we need to maintain it forever because no one will ever fix the root problem if it "just works for me".

@laeubi
Copy link
Member

laeubi commented Nov 21, 2023

If this is crucial to someones business and likes to speed up the development in that area a sponsoring would allow me to assign more time-slots particular issue.

In the meanwhile I'll try to trigger the maven devs if we can get some speedup on this (i'm not a committer on that project):

@kohlschuetter
Copy link
Contributor

@laeubi It looks like MSHARED-1285 was merged an hour ago. How can we test that this fix is effective?

@kohlschuetter
Copy link
Contributor

kohlschuetter commented Dec 19, 2023

@laeubi I'm still seeing errors with MSHARED-1285. I'm able to verify that the new code is called, but it looks like something is deleting files from the target directory after the check returns with a "file is up to date" response. And that deletion is not detected by Eclipse, even if "Refresh using native hooks or polling" is on (presumably because it's an output directory?)

By manually preventing the file from being deleted (using "chflags uchg ..." on macOS), I can see that the attempt to delete the file is made from here:

java.nio.file.FileSystemException: /path/to/project/target-eclipse/classes/my/package/file.xyz: Operation not permitted
	at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:100)
	at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
	at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
	at java.base/sun.nio.fs.UnixFileSystemProvider.implDelete(UnixFileSystemProvider.java:248)
	at java.base/sun.nio.fs.AbstractFileSystemProvider.deleteIfExists(AbstractFileSystemProvider.java:110)
	at java.base/java.nio.file.Files.deleteIfExists(Files.java:1191)
	at org.eclipse.core.internal.filesystem.local.LocalFile.internalDelete(LocalFile.java:242)
	at org.eclipse.core.internal.filesystem.local.LocalFile.internalDelete(LocalFile.java:274)
	at org.eclipse.core.internal.filesystem.local.LocalFile.internalDelete(LocalFile.java:274)
	at org.eclipse.core.internal.filesystem.local.LocalFile.internalDelete(LocalFile.java:274)
	at org.eclipse.core.internal.filesystem.local.LocalFile.internalDelete(LocalFile.java:274)
	at org.eclipse.core.internal.filesystem.local.LocalFile.internalDelete(LocalFile.java:274)
	at org.eclipse.core.internal.filesystem.local.LocalFile.delete(LocalFile.java:159)
	at org.eclipse.core.internal.localstore.DeleteVisitor.delete(DeleteVisitor.java:66)
	at org.eclipse.core.internal.localstore.DeleteVisitor.visit(DeleteVisitor.java:156)
	at org.eclipse.core.internal.localstore.UnifiedTree.accept(UnifiedTree.java:119)
	at org.eclipse.core.internal.localstore.FileSystemResourceManager.delete(FileSystemResourceManager.java:414)
	at org.eclipse.core.internal.resources.ResourceTree.internalDeleteFolder(ResourceTree.java:364)
	at org.eclipse.core.internal.resources.ResourceTree.standardDeleteFolder(ResourceTree.java:816)
	at org.eclipse.core.internal.resources.Resource.unprotectedDelete(Resource.java:1839)
	at org.eclipse.core.internal.resources.Resource.delete(Resource.java:808)
	at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.cleanOutputFolders(BatchImageBuilder.java:140)
	at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.build(BatchImageBuilder.java:65)
	at org.eclipse.jdt.internal.core.builder.JavaBuilder.buildAll(JavaBuilder.java:286)
	at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:205)
	at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:1079)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:47)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:296)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:352)
	at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:441)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:47)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:444)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:403)
	at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:668)
	at org.eclipse.core.internal.resources.Project$1.run(Project.java:604)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2453)
	at org.eclipse.core.internal.resources.Project.internalBuild(Project.java:642)
	at org.eclipse.core.internal.resources.Project.build(Project.java:154)
	at org.eclipse.debug.core.model.LaunchConfigurationDelegate.lambda$0(LaunchConfigurationDelegate.java:415)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2453)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2473)
	at org.eclipse.debug.core.model.LaunchConfigurationDelegate.buildProjects(LaunchConfigurationDelegate.java:421)
	at org.eclipse.debug.core.model.LaunchConfigurationDelegate.buildForLaunch(LaunchConfigurationDelegate.java:122)
	at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:780)
	at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:716)
	at org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(DebugUIPlugin.java:1040)
	at org.eclipse.debug.internal.ui.DebugUIPlugin$1.run(DebugUIPlugin.java:1243)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)

My suspicion is that "is up to date" check is run too early, or the "Maven Project Builder" doesn't take deletions from the "Java Builder" into account.

Reordering the "Java Builder" and the "Maven Project Builder" has no effect. (Disabling the "Java Builder" has an effect but I guess that's undesirable)

@laeubi
Copy link
Member

laeubi commented Dec 20, 2023

@laeubi It looks like MSHARED-1285 was merged an hour ago. How can we test that this fix is effective?

You need a local build or wait for a new release (not sure if there are snapshot builds), then add an additional dependency to the resources plugin, but I suppose you already have found out :-)

My suspicion is that "is up to date" check is run too early, or the "Maven Project Builder" doesn't take deletions from the "Java Builder" into account.

Deletions are cached until the next change in some file if only the output folder is affected, usually it is like this:

  • You change some source file(s)
  • JDT might or might not delete the output folder and generates the class files from fresh
  • The m2e gets notified and calls the mojos and hopefully restores the old state (that's why up-to-date is important as the file is probably deleted).

Looking at the BuildManager.basicBuild(IBuildConfiguration, int, IBuildContext, ICommand[], MultiStatus, IProgressMonitor) it seems to execute the builders in the order defined in the project file, but it might not reload that immediately so to be sure you should restart Eclipse to see if it makes a difference. Beside that I can't see a way to have a special ordering.

@kohlschuetter
Copy link
Contributor

@laeubi Reordering the builders such that "Maven Builder" comes first (then restarting) has the effect that deletions aren't even triggering the code in MSHARED-1285.

I verified this by

  • checking out maven-resources-plugin and maven-filtering
  • adding some debugging to maven-filtering's DefaultMavenResourcesFiltering.java (printing debug lines to a file I can monitor)
  • changing the mavenFilteringVersion property in maven-resources-plugin
  • install both Maven projects (3.3.2-SNAPSHOT)
  • update my project's dependency of maven-resources-plugin

@kohlschuetter
Copy link
Contributor

kohlschuetter commented Dec 20, 2023

@laeubi Could it be that your change 8e5cd49 (for #1275) is at play here?

+        if(buildOutputLocation.isPrefixOf(fullPath)) {
+          //anything in the build output is not interesting for a change as it is produced by the build
+          //lets see if there are more interesting parts...
+          return true;
+        }

I think this check would simply ignore deletions in target/classes

@laeubi
Copy link
Member

laeubi commented Dec 20, 2023

I think this check would simply ignore deletions in target/classes

As explained above, deletions in target/classes should simply never happen unless a build running what will need to restore the result. So if you see that happen that only a deletion is performed but not a regular build something seems buggy. At least in the stacktrace you see that actually a full build is taking place here.

@kohlschuetter
Copy link
Contributor

@laeubi I can confirm that removing the if(buildOutputLocation.isPrefixOf(fullPath)) { check resolves the problem for me.

I'm triggering the bug by adding/removing a dependency in pom.xml. I don't see any problems after removing that check.

@laeubi
Copy link
Member

laeubi commented Dec 20, 2023

I'm triggering the bug by adding/removing a dependency in pom.xml

The please add a test-case to m2e so it can be analyzed

I don't see any problems after removing that check

It can produce endless build cycles if a mojo constantly modifies a file during its build

@kohlschuetter
Copy link
Contributor

The please add a test-case to m2e so it can be analyzed

I'm not sure how to distill this Eclipse problem into a runnable test case, maybe you could help me with that. I'm literally just right now picking up how to build these things to alleviate the pain as an Eclipse user, not an Eclipse developer.

It can produce endless build cycles if a mojo constantly modifies a file during its build

Checking only for missing files/deletions in an output folder on the classpath/modulepath should be sufficient.

I think the problem of endless build cycles can be avoided by limiting the number of cycles it executes to 2.

@laeubi
Copy link
Member

laeubi commented Dec 20, 2023

I'm not sure how to distill this Eclipse problem into a runnable test case, maybe you could help me with that. I'm literally just right now picking up how to build these things to alleviate the pain as an Eclipse user, not an Eclipse developer.

You should be able to copy an existing test-case from here:
https://github.com/eclipse-m2e/m2e-core/tree/master/org.eclipse.m2e.core.tests

It usually is always the same:

  1. have a project that reproduce the problem
  2. import that project and trigger a build in the test
  3. now check if the project is in a state you would have expected it.

Checking only for missing files/deletions in an output folder on the classpath/modulepath should be sufficient.

In general the output folder is nothing that m2e has to be concerned as it is the property of the build cycle, nothing there should result in an (incremental) build as it is the output not the input of a build.

I think the problem of endless build cycles can be avoided by limiting the number of cycles it executes to 2.

You can't know that it is triggered by the previous one and having users to restart eclipse after the second change they made in their workspace seems not suitable ;-)

@kohlschuetter
Copy link
Contributor

kohlschuetter commented Dec 20, 2023

I think the problem of endless build cycles can be avoided by limiting the number of cycles it executes to 2.

You can't know that it is triggered by the previous one and having users to restart eclipse after the second change they made in their workspace seems not suitable ;-)

I don't understand what you mean by that. What restart?
Detecting a first invocation versus a subsequent one triggered by a build cycle should be trivial even if Eclipse wouldn't help m2e there: If there were modifications in a source folder, then it's a user-triggered invocation, if there are only changes in a target folder, then it may be a subsequent invocation.

Checking only for missing files/deletions in an output folder on the classpath/modulepath should be sufficient.

In general the output folder is nothing that m2e has to be concerned as it is the property of the build cycle, nothing there should result in an (incremental) build as it is the output not the input of a build.

You could say m2e should be concerned because that change in February, which, for what it's worth, didn't include any tests, broke existing working behavior, costing many users countless hours of frustration.

@fbricon fbricon changed the title m2e plugin sometimes "looses" resources - using snapshot 2.1.201.20230809-1423 m2e plugin sometimes "loses" resources - using snapshot 2.1.201.20230809-1423 Dec 20, 2023
@laeubi
Copy link
Member

laeubi commented Dec 20, 2023

Detecting a first invocation versus a subsequent one triggered by a build cycle should be trivial

Contributions are always welcome especially trivial ones ;-)

broke existing working behavior

There is not a single test failing so there is no "existing behavior" only something that sometimes worked also know as "undefined behavior".

That's why I said if you can reproduce a problem with a simple add/remove dependency there should be a test added so we can define the desired behavior even though this seems to be a different bug, that is that m2e does not triggers a full build when dependencies change what is never an incremental change as then everything could change in any way.

kohlschuetter added a commit to kohlschuetter/m2e-core that referenced this issue Dec 20, 2023
The Java Builder may delete files from the project output directory that
need to be re-created by the m2e Maven Builder.

With commit 8e5cd49 (a fix for eclipse-m2e#1275),
any changes to the project output directory were ignored, leading to
unexpected errors when running an application after modifying the
project POM: resources were missing from the target classpath, leading
all sorts of unexpected program behavior.

This change allows marking these changes as relevant, as long as the
following conditions are met:

- The expected resource no longer exists (i.e., it was deleted by
  another builder, plugin or outside process)
- The modification applies to a resource in the classes or test-classes
  folder (i.e., outputLocation/testOutputLocation)

eclipse-m2e#1511
eclipse-m2e#1275
kohlschuetter added a commit to kohlschuetter/m2e-core that referenced this issue Dec 20, 2023
The Java Builder may delete files from the project output directory that
need to be re-created by the m2e Maven Builder.

With commit 8e5cd49 (a fix for eclipse-m2e#1275),
any changes to the project output directory were ignored, leading to
unexpected errors when running an application after modifying the
project POM: resources were missing from the target classpath, leading
all sorts of unexpected program behavior.

This change allows marking these changes as relevant, as long as the
following conditions are met:

- The expected resource no longer exists (i.e., it was deleted by
  another builder, plugin or outside process)
- The modification applies to a resource in the classes or test-classes
  folder (i.e., outputLocation/testOutputLocation)

eclipse-m2e#1511
eclipse-m2e#1275
@kohlschuetter
Copy link
Contributor

@laeubi Please take a look at my pull request. I hope this works for you.

For others trying to validate this:

  • Check out the master branch at https://github.com/kohlschuetter/m2e-core
  • run mvn package -pl \!org.eclipse.m2e.rcptt.tests
  • add the folder m2e-core/products/m2e-ide/target/repository to Eclipse (Help -> Install New Software -> Add ... -> Local ...)
  • Uncheck "Group items by category" to see all plugins
  • Install M2E Maven Integration for Eclipse (which should have today's date)
  • Reboot Eclipse
  • Enjoy a "lossless" development environment :-)

kohlschuetter added a commit to kohlschuetter/m2e-core that referenced this issue Dec 20, 2023
kohlschuetter added a commit to kohlschuetter/m2e-core that referenced this issue Dec 20, 2023
@lalmeras
Copy link

I just apply @kohlschuetter workaround:

  • install a 2023.12 Eclipse JEE IDE
  • setup a dumb project with a property file
  • when I add / remove a dependency, properties disappears in target folder/
  • apply @kohlschuetter procedure to update m2e plugin, restart IDE
  • when I add / remove a dependency, properties are not dropped from target folder/

So it « works ».

I read considerations about how the bug is fixed. I do not have enough insight at the time to judge the current proposal.

laeubi pushed a commit that referenced this issue Dec 22, 2023
The Java Builder may delete files from the project output directory that
need to be re-created by the m2e Maven Builder.

With commit 8e5cd49,
any changes to the project output directory were ignored, leading to
unexpected errors when running an application after modifying the
project POM: resources were missing from the target classpath, leading
all sorts of unexpected program behavior.

This change allows marking these changes as relevant, as long as the
following conditions are met:

- The expected resource no longer exists (i.e., it was deleted by
  another builder, plugin or outside process)
- The modification applies to a resource in the classes or test-classes
  folder (i.e., outputLocation/testOutputLocation)

See #1511
See #1275
@laeubi
Copy link
Member

laeubi commented Dec 27, 2023

So it « works ».
I read considerations about how the bug is fixed

It fixes the problem that when the output folders are deleted but do not fixes for example this reproducer:

so one still need the MSHARED-1285 bugfix as well for cases where the output folder is not deleted, and we would need a testcase for what is described by @kohlschuetter and @lalmeras as a test-case to ensure it works in the future.

@goodale
Copy link

goodale commented Jan 23, 2024

is there any update on this regression bug? I continue to experience these types of issues since this bug was first reported. the only solution seems to be remove the app from 'Modules' and adding it back again to get Eclipse/Spring to redeploy.

Caused by: java.io.FileNotFoundException: class path resource [XXXX] cannot be opened because it does not exist

@pcdavid
Copy link

pcdavid commented Jan 24, 2024

Which version of m2e are you using? I don't believe there's been an actual release since the fix was merged, but I've been using the nightly builds from https://download.eclipse.org/technology/m2e/snapshots/latest/ for a while (M2E - Maven Integration for Eclipse 2.4.300.20240123-0523 at the moment) and do not experience this bug anymore.

Before the fix I had been using the workaround mentioned here with success.

@goodale
Copy link

goodale commented Jan 24, 2024 via email

@HannesWell
Copy link
Contributor

Which version of m2e are you using? I don't believe there's been an actual release since the fix was merged,

We plan to perform a release soon, probably at the weekend.

@eliasbalasis
Copy link

I think I am suffering from similar symptoms but under conditions I haven't been able to explain, but most certainly while rebuilding chains of modules as part of POM changes.
I am using Eclipse 2023-09 with m2e 2.4.0 but I am confident I have experienced the same symptoms on Eclipse 2023-12
I hope this helps.

@laeubi
Copy link
Member

laeubi commented Feb 21, 2024

M2e has a new release where, together with apache/maven-filtering#77 this should now fix the problem.

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