Skip to content

Commit

Permalink
Support annotationProcessorPaths in DevMojo
Browse files Browse the repository at this point in the history
  • Loading branch information
FroMage committed Nov 13, 2023
1 parent c34a5a3 commit 5a4e24e
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class Context {
private final List<String> compilerPluginOptions;
private final boolean ignoreModuleInfo;
private final File generatedSourcesDirectory;
private final Set<File> annotationProcessorPaths;

public Context(
String name,
Expand All @@ -68,6 +69,7 @@ public Context(
List<String> compilePluginArtifacts,
List<String> compilerPluginOptions,
File generatedSourcesDirectory,
Set<File> annotationProcessorPaths,
String ignoreModuleInfo) {
this.name = name;
this.classpath = classpath;
Expand All @@ -84,6 +86,7 @@ public Context(
this.compilerPluginOptions = compilerPluginOptions;
this.ignoreModuleInfo = Boolean.parseBoolean(ignoreModuleInfo);
this.generatedSourcesDirectory = generatedSourcesDirectory;
this.annotationProcessorPaths = annotationProcessorPaths;
}

public String getName() {
Expand All @@ -98,6 +101,10 @@ public Set<File> getReloadableClasspath() {
return reloadableClasspath;
}

public Set<File> getAnnotationProcessorPaths() {
return annotationProcessorPaths;
}

public File getProjectDirectory() {
return projectDirectory;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ public class DevModeContext implements Serializable {
private String baseName;
private final Set<ArtifactKey> localArtifacts = new HashSet<>();

private Set<File> processorPaths;

public boolean isLocalProjectDiscovery() {
return localProjectDiscovery;
}
Expand Down Expand Up @@ -239,6 +241,14 @@ public Set<ArtifactKey> getLocalArtifacts() {
return localArtifacts;
}

public void setAnnotationProcessorPaths(Set<File> processorPaths) {
this.processorPaths = processorPaths;
}

public Set<File> getAnnotationProcessorPaths() {
return processorPaths;
}

public static class ModuleInfo implements Serializable {

private static final long serialVersionUID = -1376678003747618410L;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public void compile(Set<File> filesToCompile, CompilationProvider.Context contex
final QuarkusFileManager.Context sourcesContext = new QuarkusFileManager.Context(
context.getClasspath(), context.getReloadableClasspath(),
context.getOutputDirectory(), context.getGeneratedSourcesDirectory(),
context.getAnnotationProcessorPaths(),
context.getSourceEncoding(),
context.ignoreModuleInfo());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ public void setupSourceCompilationContext(DevModeContext context,
context.getCompilerPluginsOptions(),
compilationUnit.getGeneratedSourcesPath() == null ? null
: new File(compilationUnit.getGeneratedSourcesPath()),
context.getAnnotationProcessorPaths(),
context.getBuildSystemProperties().getOrDefault("quarkus.live-reload.ignore-module-info",
"true")));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ public B compilerPluginOptions(List<String> options) {
return (B) this;
}

@SuppressWarnings("unchecked")
public B annotationProcessorPaths(Set<File> processorPaths) {
QuarkusDevModeLauncher.this.processorPaths = processorPaths;
return (B) this;
}

@SuppressWarnings("unchecked")
public B releaseJavaVersion(String releaseJavaVersion) {
QuarkusDevModeLauncher.this.releaseJavaVersion = releaseJavaVersion;
Expand Down Expand Up @@ -317,6 +323,7 @@ public R build() throws Exception {
private ModuleInfo main;
private List<ModuleInfo> dependencies = new ArrayList<>(0);
private LinkedHashMap<ArtifactKey, File> classpath = new LinkedHashMap<>();
private Set<File> processorPaths;

protected QuarkusDevModeLauncher() {
}
Expand Down Expand Up @@ -442,6 +449,9 @@ protected void prepare() throws Exception {
if (compilerPluginOptions != null) {
devModeContext.setCompilerPluginsOptions(compilerPluginOptions);
}
if (processorPaths != null) {
devModeContext.setAnnotationProcessorPaths(processorPaths);
}

devModeContext.setReleaseJavaVersion(releaseJavaVersion);
devModeContext.setSourceJavaVersion(sourceJavaVersion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ protected QuarkusFileManager(StandardJavaFileManager fileManager, Context contex
if (context.getGeneratedSourcesDirectory() != null) {
this.fileManager.setLocation(StandardLocation.SOURCE_OUTPUT, List.of(context.getGeneratedSourcesDirectory()));
}
if (context.getAnnotationProcessorPaths() != null) {
this.fileManager.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, context.getAnnotationProcessorPaths());
}
} catch (IOException e) {
throw new RuntimeException("Cannot initialize file manager", e);
}
Expand All @@ -35,6 +38,9 @@ public void reset(Context context) {
if (context.getGeneratedSourcesDirectory() != null) {
this.fileManager.setLocation(StandardLocation.SOURCE_OUTPUT, List.of(context.getGeneratedSourcesDirectory()));
}
if (context.getAnnotationProcessorPaths() != null) {
this.fileManager.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, context.getAnnotationProcessorPaths());
}
} catch (IOException e) {
throw new RuntimeException("Cannot reset file manager", e);
}
Expand All @@ -52,15 +58,22 @@ public static class Context {
private final Charset sourceEncoding;
private final boolean ignoreModuleInfo;
private final File generatedSourcesDirectory;
private final Set<File> annotationProcessorPaths;

public Context(Set<File> classPath, Set<File> reloadableClassPath,
File outputDirectory, File generatedSourcesDirectory, Charset sourceEncoding, boolean ignoreModuleInfo) {
File outputDirectory, File generatedSourcesDirectory, Set<File> annotationProcessorPaths,
Charset sourceEncoding, boolean ignoreModuleInfo) {
this.classPath = classPath;
this.reloadableClassPath = reloadableClassPath;
this.outputDirectory = outputDirectory;
this.sourceEncoding = sourceEncoding;
this.ignoreModuleInfo = ignoreModuleInfo;
this.generatedSourcesDirectory = generatedSourcesDirectory;
this.annotationProcessorPaths = annotationProcessorPaths;
}

public Set<File> getAnnotationProcessorPaths() {
return annotationProcessorPaths;
}

public Set<File> getClassPath() {
Expand Down
104 changes: 104 additions & 0 deletions devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
Expand All @@ -43,6 +44,8 @@
import org.aesh.terminal.utils.ANSI;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.BuildBase;
import org.apache.maven.model.Dependency;
Expand Down Expand Up @@ -267,6 +270,9 @@ public class DevMojo extends AbstractMojo {
@Component
private MavenVersionEnforcer mavenVersionEnforcer;

@Component
private ArtifactHandlerManager artifactHandlerManager;

@Component
private RepositorySystem repoSystem;

Expand Down Expand Up @@ -708,6 +714,73 @@ private void executeGoal(PluginExec pluginExec, String goal, Map<String, String>
pluginManager));
}

private Set<File> readAnnotationProcessorPaths(Xpp3Dom pluginConfig) throws MojoExecutionException {
Xpp3Dom annotationProcessorPaths = pluginConfig.getChild("annotationProcessorPaths");
if (annotationProcessorPaths == null) {
return Collections.emptySet();
}
Xpp3Dom[] paths = annotationProcessorPaths.getChildren("path");
Set<File> elements = new LinkedHashSet<>();
try {
List<org.eclipse.aether.graph.Dependency> dependencies = convertToDependencies(paths);
CollectRequest collectRequest = new CollectRequest(dependencies, Collections.emptyList(),
project.getRemoteProjectRepositories());
DependencyRequest dependencyRequest = new DependencyRequest();
dependencyRequest.setCollectRequest(collectRequest);
DependencyResult dependencyResult = repoSystem.resolveDependencies(session.getRepositorySession(),
dependencyRequest);

for (ArtifactResult resolved : dependencyResult.getArtifactResults()) {
elements.add(resolved.getArtifact().getFile());
}
return elements;
} catch (Exception e) {
throw new MojoExecutionException(
"Resolution of annotationProcessorPath dependencies failed: " + e.getLocalizedMessage(), e);
}
}

private List<org.eclipse.aether.graph.Dependency> convertToDependencies(Xpp3Dom[] paths) {
List<org.eclipse.aether.graph.Dependency> dependencies = new ArrayList<>();
for (Xpp3Dom path : paths) {
String type = getValue(path, "type", "jar");
ArtifactHandler handler = artifactHandlerManager.getArtifactHandler(type);
org.eclipse.aether.artifact.Artifact artifact = new DefaultArtifact(
getValue(path, "groupId", null),
getValue(path, "artifactId", null),
getValue(path, "classifier", null),
handler.getExtension(),
getValue(path, "version", null));
Set<org.eclipse.aether.graph.Exclusion> exclusions = convertToAetherExclusions(path.getChild("exclusions"));
dependencies.add(new org.eclipse.aether.graph.Dependency(artifact, JavaScopes.RUNTIME, false, exclusions));
}
return dependencies;
}

private String getValue(Xpp3Dom path, String element, String defaultValue) {
Xpp3Dom child = path.getChild(element);
if (child == null) {
return defaultValue;
}
return child.getValue();
}

private Set<org.eclipse.aether.graph.Exclusion> convertToAetherExclusions(Xpp3Dom exclusions) {
if (exclusions == null) {
return Collections.emptySet();
}
Set<Exclusion> aetherExclusions = new HashSet<>();
for (Xpp3Dom exclusion : exclusions.getChildren("exclusion")) {
Exclusion aetherExclusion = new Exclusion(
getValue(exclusion, "groupId", null),
getValue(exclusion, "artifactId", null),
getValue(exclusion, "classifier", null),
getValue(exclusion, "extension", "jar"));
aetherExclusions.add(aetherExclusion);
}
return aetherExclusions;
}

private boolean isGoalConfigured(Plugin plugin, String goal) {
if (plugin == null) {
return false;
Expand Down Expand Up @@ -1156,6 +1229,7 @@ private QuarkusDevModeLauncher newLauncher(Boolean debugPortOk, String bootstrap
}

setKotlinSpecificFlags(builder);
setAnnotationProcessorFlags(builder);

// path to the serialized application model
final Path appModelLocation = resolveSerializedModelLocation();
Expand Down Expand Up @@ -1406,6 +1480,36 @@ private void setKotlinSpecificFlags(MavenDevModeLauncher.Builder builder) {
builder.compilerPluginOptions(options);
}

private void setAnnotationProcessorFlags(MavenDevModeLauncher.Builder builder) {
Plugin compilerMavenPlugin = null;
for (Plugin plugin : project.getBuildPlugins()) {
if (plugin.getArtifactId().equals("maven-compiler-plugin")
&& plugin.getGroupId().equals("org.apache.maven.plugins")) {
compilerMavenPlugin = plugin;
break;
}
}

if (compilerMavenPlugin == null) {
return;
}

getLog().debug("Maven compiler plugin found, looking for annotation processors");

List<String> options = new ArrayList<>();
Xpp3Dom compilerPluginConfiguration = (Xpp3Dom) compilerMavenPlugin.getConfiguration();
try {
Set<File> processorPaths = this.readAnnotationProcessorPaths(compilerPluginConfiguration);
getLog().debug("Found processor paths: " + processorPaths);
if (!processorPaths.isEmpty()) {
builder.annotationProcessorPaths(processorPaths);
}
} catch (MojoExecutionException e) {
throw new RuntimeException(e);
}
builder.compilerPluginOptions(options);
}

protected void modifyDevModeContext(MavenDevModeLauncher.Builder builder) {

}
Expand Down

0 comments on commit 5a4e24e

Please sign in to comment.