Skip to content

Commit

Permalink
apache#6176: break priming cycle with unreachable artifacts.
Browse files Browse the repository at this point in the history
  • Loading branch information
sdedic committed Jul 14, 2023
1 parent 2c2e57c commit e9cbd83
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,9 @@ private Pair<Collection<ProjectProblem>, Boolean> doGetProblems1(boolean sync) {
c = () -> {
// double check, the project may be invalidated during the time.
MavenProject prj = ((NbMavenProjectImpl)project).getFreshOriginalMavenProject();
Object wasprocessed2 = updatedPrj.getContextValue(MavenModelProblemsProvider.class.getName());
Object wasprocessed2 = prj.getContextValue(MavenModelProblemsProvider.class.getName());
synchronized (MavenModelProblemsProvider.this) {
if (o == updatedPrj && wasprocessed2 != null) {
if (wasprocessed2 != null) {
Pair<Collection<ProjectProblem>, Boolean> cached = problemsCache;
LOG.log(Level.FINER, "getProblems: Project was processed #2, cached is: {0}", cached);
if (cached != null) {
Expand All @@ -210,35 +210,48 @@ private Pair<Collection<ProjectProblem>, Boolean> doGetProblems1(boolean sync) {
}
int round = 0;
List<ProjectProblem> toRet = null;
while (round < 3) {
while (round <= 1) {
try {
boolean ok = false;
synchronized (MavenModelProblemsProvider.this) {
sanityBuildStatus = false;
toRet = new ArrayList<>();
MavenExecutionResult res = MavenProjectCache.getExecutionResult(prj);
if (res != null && res.hasExceptions()) {
toRet.addAll(reportExceptions(res));
try {
sanityBuildStatus = false;
checkMissing = round < 1;
toRet = new ArrayList<>();
MavenExecutionResult res = MavenProjectCache.getExecutionResult(prj);
if (res != null && res.hasExceptions()) {
toRet.addAll(reportExceptions(res));
}
//#217286 doArtifactChecks can call FileOwnerQuery and attempt to aquire the project mutex.
toRet.addAll(doArtifactChecks(prj));
LOG.log(Level.FINER, "getProblems: Project {1} processing finished, result is: {0}",
new Object[] { toRet, prj });
ok = true;
break;
} finally {
if (ok || round > 0) {
//mark the project model as checked once and cached
prj.setContextValue(MavenModelProblemsProvider.class.getName(), new Object());
// change globals before exiting synchronized section
problemsCache = Pair.of(toRet, sanityBuildStatus);
analysedProject = new WeakReference<>(prj);
}
checkMissing = true;
}
//#217286 doArtifactChecks can call FileOwnerQuery and attempt to aquire the project mutex.
toRet.addAll(doArtifactChecks(prj));
//mark the project model as checked once and cached
prj.setContextValue(MavenModelProblemsProvider.class.getName(), new Object());
LOG.log(Level.FINER, "getProblems: Project {1} processing finished, result is: {0}",
new Object[] { toRet, prj });
problemsCache = Pair.of(toRet, sanityBuildStatus);
analysedProject = new WeakReference<>(prj);
}
firePropertyChange();
return Pair.of(toRet, sanityBuildStatus);
} catch (ProblemReporterImpl.ArtifactFoundException ex) {
// should never happen with round > 0
assert round < 1;
round++;
LOG.log(Level.FINER, "getProblems: Project {1} reported missing artifact that actually exists, restarting - {0} round",
new Object[] { round, prj });
// force reload, then wait for the reload to complete
NbMavenProject.fireMavenProjectReload(project);
prj = ((NbMavenProjectImpl)project).getFreshOriginalMavenProject();
}
}
}
//mark the project model as checked once and cached
firePropertyChange();
return Pair.of(toRet, sanityBuildStatus);
};
}
Expand All @@ -260,6 +273,13 @@ private void firePropertyChange() {
support.firePropertyChange(ProjectProblemsProvider.PROP_PROBLEMS, null, null);
}

// @GuardedBy(this)
private boolean checkMissing = true;

private void addMissingArtifact(Artifact a) {
problemReporter.addMissingArtifact(a, checkMissing);
}

@NbBundle.Messages({
"ERR_SystemScope=A 'system' scope dependency was not found. Code completion is affected.",
"MSG_SystemScope=There is a 'system' scoped dependency in the project but the path to the binary is not valid.\n"
Expand Down Expand Up @@ -295,7 +315,7 @@ public Collection<ProjectProblem> doArtifactChecks(@NonNull MavenProject project
//TODO create a correction action for this.
toRet.add(ProjectProblem.createWarning(ERR_SystemScope(), MSG_SystemScope(), new ProblemReporterImpl.MavenProblemResolver(OpenPOMAction.instance().createContextAwareInstance(Lookups.fixed(project)), "SCOPE_DEPENDENCY")));
} else {
problemReporter.addMissingArtifact(art);
addMissingArtifact(art);
if (file == null) {
missingNonSibling = true;
} else {
Expand All @@ -312,7 +332,7 @@ public Collection<ProjectProblem> doArtifactChecks(@NonNull MavenProject project
missingJars.add(art);
}
} else if (NbArtifactFixer.isFallbackFile(file)) {
problemReporter.addMissingArtifact(art);
addMissingArtifact(art);
missingJars.add(art);
missingNonSibling = true;
}
Expand Down Expand Up @@ -351,7 +371,7 @@ private Collection<ProjectProblem> checkParents(@NonNull MavenProject project) {
}
if (NbArtifactFixer.FALLBACK_NAME.equals(m.getName())) {
toRet.add(ProjectProblem.createError(ERR_NoParent(), MSG_NoParent(m.getId()), createSanityBuildAction()));
problemReporter.addMissingArtifact(EmbedderFactory.getProjectEmbedder().createArtifact(m.getGroupId(), m.getArtifactId(), m.getVersion(), "pom"));
addMissingArtifact(EmbedderFactory.getProjectEmbedder().createArtifact(m.getGroupId(), m.getArtifactId(), m.getVersion(), "pom"));
}
}
return toRet;
Expand Down Expand Up @@ -393,11 +413,11 @@ private Collection<ProjectProblem> reportExceptions(MavenExecutionResult res) {
LOG.log(Level.FINE, "Error on loading project " + project.getProjectDirectory(), e);
if (e instanceof ArtifactResolutionException) { // XXX when does this occur?
toRet.add(ProjectProblem.createError(TXT_Artifact_Resolution_problem(), getDescriptionText(e)));
problemReporter.addMissingArtifact(((ArtifactResolutionException) e).getArtifact());
addMissingArtifact(((ArtifactResolutionException) e).getArtifact());

} else if (e instanceof ArtifactNotFoundException) { // XXX when does this occur?
toRet.add(ProjectProblem.createError(TXT_Artifact_Not_Found(), getDescriptionText(e)));
problemReporter.addMissingArtifact(((ArtifactNotFoundException) e).getArtifact());
addMissingArtifact(((ArtifactNotFoundException) e).getArtifact());
} else if (e instanceof ProjectBuildingException) {
LOG.log(Level.FINE, "Creating sanity build action for {0}", project.getProjectDirectory());
toRet.add(ProjectProblem.createError(TXT_Cannot_Load_Project(), getDescriptionText(e), createSanityBuildAction()));
Expand All @@ -408,14 +428,14 @@ private Collection<ProjectProblem> reportExceptions(MavenExecutionResult res) {
if (mp.getException() instanceof UnresolvableModelException) {
// Probably obsoleted by ProblemReporterImpl.checkParent, but just in case:
UnresolvableModelException ume = (UnresolvableModelException) mp.getException();
problemReporter.addMissingArtifact(EmbedderFactory.getProjectEmbedder().createProjectArtifact(ume.getGroupId(), ume.getArtifactId(), ume.getVersion()));
addMissingArtifact(EmbedderFactory.getProjectEmbedder().createProjectArtifact(ume.getGroupId(), ume.getArtifactId(), ume.getVersion()));
} else if (mp.getException() instanceof PluginResolutionException) {
Plugin plugin = ((PluginResolutionException) mp.getException()).getPlugin();
// XXX this is not actually accurate; should rather pick out the ArtifactResolutionException & ArtifactNotFoundException inside
problemReporter.addMissingArtifact(EmbedderFactory.getProjectEmbedder().createArtifact(plugin.getGroupId(), plugin.getArtifactId(), plugin.getVersion(), "jar"));
addMissingArtifact(EmbedderFactory.getProjectEmbedder().createArtifact(plugin.getGroupId(), plugin.getArtifactId(), plugin.getVersion(), "jar"));
} else if (mp.getException() instanceof PluginManagerException) {
PluginManagerException ex = (PluginManagerException) mp.getException();
problemReporter.addMissingArtifact(EmbedderFactory.getProjectEmbedder().createArtifact(ex.getPluginGroupId(), ex.getPluginArtifactId(), ex.getPluginVersion(), "jar"));
addMissingArtifact(EmbedderFactory.getProjectEmbedder().createArtifact(ex.getPluginGroupId(), ex.getPluginArtifactId(), ex.getPluginVersion(), "jar"));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.plugin.PluginArtifactsCache;
import org.netbeans.modules.maven.NbMavenProjectImpl;
import org.netbeans.modules.maven.api.problem.ProblemReport;
Expand Down Expand Up @@ -189,13 +193,23 @@ public boolean isBroken() {
* and some problems encapsulate several missing artifacts.
* @param a an artifact (scope permitted but ignored)
*/
void addMissingArtifact(Artifact a) {
void addMissingArtifact(Artifact a, boolean checkMissing) {
synchronized (reports) {
a = EmbedderFactory.getProjectEmbedder().getLocalRepository().find(a);
//a.getFile should be already normalized but the find() method can pull tricks on us.
//#225008
File f = FileUtil.normalizeFile(a.getFile());
if (f.exists() && f.canRead()) {
if (f.exists() && f.canRead() && checkMissing) {
try {
MavenExecutionRequest rq = EmbedderFactory.getProjectEmbedder().createMavenExecutionRequest();
List<ArtifactRepository> repos = nbproject.getOriginalMavenProject().getRemoteArtifactRepositories();
if (repos.isEmpty()) {
repos = rq.getRemoteRepositories();
}
EmbedderFactory.getProjectEmbedder().resolve(a, repos, EmbedderFactory.getProjectEmbedder().getLocalRepository());
} catch (ArtifactResolutionException | ArtifactNotFoundException ex) {
return;
}
throw new ArtifactFoundException(a, f);
}
if (missingArtifacts.add(f)) {
Expand Down

0 comments on commit e9cbd83

Please sign in to comment.