Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [m2e-dev] Project rename breaks dependent projects.

Does manual update always get workspace into a good state? If it does, I
wonder if we can ignore the problem, maybe document as a known
limitation. How often do people really rename their workspace projects
without change pom.xml soon after rename? I agree that tracking multiple
projects per-GAV is the right way solve this problem, but I am not sure
it's worth the effort. But if you feel like fixing this, you have my
moral support :-)

<rant>
I tried to fix some concurrency problems around maven project cache last
couple of days, and I gave up. Project registry has grown so complicated
that it almost impossible to change anything there. I wish we had time
to clean this. I am not sure we can without breaking existing APIs,
unfortunately.
</rant>

--
Regards,
Igor


On 2014-10-05, 14:16, Anton Tanasenko wrote:
Hi,
I've encountered another issue with ProjectRegistryRefreshJob. This time
when renaming a project.
Having a simple setup with project A (gav=test:a:1.0) depending on B
(gav=test:b:1.0), when you rename B to B1 and autobuild is on. It is not
related to my in-progress bug 445675 with autobuild.

What happens, is RefreshJob receives a PRE_DELETE(B) and ADDED(B1)
resourceChange events in sequence. PRE_DELETE schedules a refresh on
deleted B, but before it gets to actually run, B1 is getting built by
MavenBuilder, which performs a refresh of B1. This results in an error,
that test:a is missing a dependency test:b.

Scenario 1 (Autobuild=on)
1. ResourceChanged PRE_DELETE (B)
2. Refresh of B scheduled
3. ResourceChanged ADDED (B1) (ignored by ProjectRegistryRefreshJob)
4. Building B1
4.1. Refresh phase1 B1
4.2. Refresh phase2 B1
4.3. Refresh phase2 A
No errors yet
5. Refresh B
5.1. Refresh phase1 B
5.2. Refresh phase2 B
5.3. Refresh phase2 A (error marker added)
Result: B1(test:a) has an unresolved dependency test:b
To get rid of the error, one has to manually perform Update project on
both A and B1.


If you have autobuild turned off, then such a rename will not cause a
build of new B1 project. and refresh of deleted B gets to run as soon as
possible.

Scenario 2 (Autobuild=off)
1. ResourceChanged PRE_DELETE (B)
2. Refresh of B scheduled
3. ResourceChanged ADDED (B1) (ignored by ProjectRegistryRefreshJob)
4. Refresh B
4.1. Refresh phase1 B
4.2. Refresh phase2 B
4.3. Refresh phase2 A
Error marker added

Autobuild gets turned on manually
5. Building B1
5.1. Refresh phase1 B1
5.2. Refresh phase2 B1
5.3. Refresh phase2 A
Result: no errors

At first I tried a workaround: since AutobuildJob's schedule delay is
between 100 and 1000ms depending on circumstances, I put a delay of 10ms
to RefreshJob for deleted projects. It did cause a refresh of B to start
earlier, however a refresh of B1 (as called by MavenBuilder) ran in
parallel before B got refreshed - this is because RefreshJob only locks
applyMutableState with workspace rule (lines 101-102 ). Extending it to
also include a call to refresh did the trick - Scenario 1 steps were the
same as Scenario 2.
I was not entirely happy about such workaround, since under some weird
circumstances, build could still run earlier than refresh job, so I
finally traced the problem down to ProjectRegistry.

BasicProjectRegistry has a Map<ArtifactKey, IFile> workspaceArtifacts
field which can only accomodate one project with the same ArtifactKey.
Whenever there is a new project facade (import, gav change, etc.) an
entry with corresponding ArtifactKey would get overwritten even if there
was something else. All the other registry contents can cope with
same-gav projects quite nicely.

So basically project registry inconsistencies will occur whenever there
is more than one same-gav project present at the same time. For
instance, with the initial setup importing another test:b:1.0 (as B1)
project and then changing its version to, say, 1.1 will cause test:a to
'miss' dependency to test:b:1.0 in the presence of seemingly valid B
(test:b:1.0).

I went and implemented a patch that turns this map into Map<ArtifactKey,
Set<IFile>> (also migrating it from <ArtifactKey, IFile> after workspace
state deserialization) that maintains a Set of poms for each ArtifactKey
and that fixed all abovementioned scenarios.
Also, the Set there is an instance of LinkedHashSet that preserves the
import order of projects and workspace dependency resolution always
yields the first one.

Igor, I'd issue a bug and send code for review (when I have a bit more
time to make proper tests) unless you have some comments against such
change.

PS: could RefreshJob's call to refresh() not being covered by workspace
root rule be a potential problem? There are checks against
MutableProjectRegistry#isStale() in some places that re-schedule the job
though.

--
Regards,
Anton.


_______________________________________________
m2e-dev mailing list
m2e-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/m2e-dev



Back to the top