Skip to content

Commit

Permalink
Provide an eviction pattern to get rid of classloaders for bad behavi…
Browse files Browse the repository at this point in the history
…ng plugins, apache#440
  • Loading branch information
gnodet committed Jul 20, 2021
1 parent 791807f commit 9ed8647
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,11 @@ public enum Environment {
/**
* Log mojos execution time at the end of the build.
*/
MVND_BUILD_TIME("mvnd.buildTime", null, null, OptionType.BOOLEAN, Flags.NONE);
MVND_BUILD_TIME("mvnd.buildTime", null, null, OptionType.BOOLEAN, Flags.NONE),
/**
* Regexp pattern that will force eviction of the plugin realms if one of its dependencies matches.
*/
MVND_PLUGIN_REALM_EVICT_PATTERN("mvnd.pluginRealmEvictPattern", null, "", OptionType.STRING, Flags.OPTIONAL);

static Properties properties;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@

import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
Expand All @@ -27,6 +31,7 @@
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionResult;
import org.eclipse.sisu.Typed;
import org.mvndaemon.mvnd.common.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -39,6 +44,8 @@ public class InvalidatingPluginRealmCacheEventSpy extends AbstractEventSpy {

private final InvalidatingPluginRealmCache cache;
private Path multiModuleProjectDirectory;
private String pattern;
private PathMatcher matcher;

@Inject
public InvalidatingPluginRealmCacheEventSpy(InvalidatingPluginRealmCache cache) {
Expand All @@ -51,6 +58,38 @@ public void onEvent(Object event) throws Exception {
if (event instanceof MavenExecutionRequest) {
/* Store the multiModuleProjectDirectory path */
multiModuleProjectDirectory = ((MavenExecutionRequest) event).getMultiModuleProjectDirectory().toPath();
pattern = Environment.MVND_PLUGIN_REALM_EVICT_PATTERN.asOptional()
.orElse(Environment.MVND_PLUGIN_REALM_EVICT_PATTERN.getDefault());
if (!pattern.isEmpty()) {
String[] patterns = pattern.split(",");
List<PathMatcher> matchers = new ArrayList<>();
for (String pattern : patterns) {
if (pattern.startsWith("mvn:")) {
String[] parts = pattern.substring("mvn:".length()).split(":");
String groupId, artifactId, version;
if (parts.length >= 3) {
version = parts[2];
} else {
version = "*";
}
if (parts.length >= 2) {
groupId = parts[0];
artifactId = parts[1];
} else {
groupId = "*";
artifactId = parts[0];
}
pattern = "glob:**/" + ("*".equals(groupId) ? "" : groupId.replace('.', '/') + "/")
+ artifactId + "/" + ("*".equals(version) ? "**" : version + "/**");
}
matchers.add(getPathMatcher(pattern));
}
if (matchers.size() == 1) {
matcher = matchers.iterator().next();
} else {
matcher = path -> matchers.stream().anyMatch(f -> f.matches(path));
}
}
} else if (event instanceof MavenExecutionResult) {
/* Evict the entries referring to jars under multiModuleProjectDirectory */
cache.cache.removeIf(this::shouldEvict);
Expand All @@ -70,6 +109,11 @@ private boolean shouldEvict(InvalidatingPluginRealmCache.Key k, InvalidatingPlug
"Removing PluginRealmCache entry {} because it refers to an artifact in the build tree {}",
k, path);
return true;
} else if (matcher != null && matcher.matches(path)) {
LOG.debug(
"Removing PluginRealmCache entry {} because its components {} matches the eviction pattern '{}'",
k, path, pattern);
return true;
}
}
}
Expand All @@ -78,4 +122,12 @@ private boolean shouldEvict(InvalidatingPluginRealmCache.Key k, InvalidatingPlug
return true;
}
}

private static PathMatcher getPathMatcher(String pattern) {
if (!pattern.startsWith("glob:") && !pattern.startsWith("regex:")) {
pattern = "glob:" + pattern;
}
return FileSystems.getDefault().getPathMatcher(pattern);
}

}

0 comments on commit 9ed8647

Please sign in to comment.