Skip to content

Commit

Permalink
[MCOMPILER-391] Use dep mgmt to resolve annotation processors and the…
Browse files Browse the repository at this point in the history
…ir deps

 * dependency managemet can be used for two slighty difference use
   cases (when it comes to annotation processors):
     -- getting the version of the top-level processor path elements
     -- passing the list of managed dependencies to maven-resolver
        when resolving the whole processorpath
   These two can be combined, so there is total of 4 valid combinations
   (some of them make more sense than the others, but generally there is
   no reason to not support all of them)

 * using dependency management when resolving transitive dependencies of
   annotation processors is something that may or may not be desired.
   For that reason, there is a new flag that explicitly enables this
   behavior, while default is to _not_ use dependency management
   (the current behavior)
  • Loading branch information
psiroky authored and slawekjaranowski committed Jun 5, 2023
1 parent 9f821e9 commit 94eb582
Show file tree
Hide file tree
Showing 23 changed files with 1,008 additions and 14 deletions.
34 changes: 34 additions & 0 deletions src/it/MCOMPILER-391-processorpath-dep-mgmt/annotation-api/pom.xml
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.apache.maven.plugins.compiler.it</groupId>
<artifactId>mcompiler391-test</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<artifactId>mcompiler391-annotation-api</artifactId>

</project>
@@ -0,0 +1,35 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package mcompiler391;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface SimpleAnnotation {
/**
* Specifies which class (FQCN) is supposed to be on classpath during annotation processing.
* Used to check if the dependency resolution mechanism of maven-compiler-plugin is constructing
* the classpath (processorpath) correctly, based on the plugin configuration and dependency management.
*/
String onClasspath() default "";
}
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.apache.maven.plugins.compiler.it</groupId>
<artifactId>mcompiler391-test</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<artifactId>mcompiler391-annotation-processor-dep</artifactId>

</project>
@@ -0,0 +1,21 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package mcompiler391;

public class AnnotationProcessorDependencyV1 {}
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.apache.maven.plugins.compiler.it</groupId>
<artifactId>mcompiler391-test</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<!-- Same groupId + artifactId as for v1 (1.0.0-SNAPSHOT), but different version to test version overrides
via dependency management -->
<artifactId>mcompiler391-annotation-processor-dep</artifactId>
<version>2.0.0-SNAPSHOT</version>

</project>
@@ -0,0 +1,21 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package mcompiler391;

public class AnnotationProcessorDependencyV2 {}
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.apache.maven.plugins.compiler.it</groupId>
<artifactId>mcompiler391-test</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<artifactId>mcompiler391-annotation-processor</artifactId>

<dependencies>
<dependency>
<groupId>org.apache.maven.plugins.compiler.it</groupId>
<artifactId>mcompiler391-annotation-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins.compiler.it</groupId>
<artifactId>mcompiler391-annotation-processor-dep</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>

</project>
@@ -0,0 +1,87 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package mcompiler391;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.tools.FileObject;
import javax.tools.StandardLocation;

import java.io.IOException;
import java.io.Writer;
import java.util.Set;

@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes("mcompiler391.SimpleAnnotation")
public class SimpleAnnotationProcessor extends AbstractProcessor {

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (annotations.isEmpty()) {
return true;
}

Filer filer = processingEnv.getFiler();

Elements elementUtils = processingEnv.getElementUtils();

Set<? extends Element> elements =
roundEnv.getElementsAnnotatedWith(annotations.iterator().next());

for (Element element : elements) {
Name name = element.getSimpleName();
PackageElement packageElement = elementUtils.getPackageOf(element);

SimpleAnnotation annotation = element.getAnnotation(SimpleAnnotation.class);
assertThatClassIsOnClasspath(annotation.onClasspath());

try {
Name packageName = packageElement.getQualifiedName();
FileObject resource =
filer.createResource(StandardLocation.SOURCE_OUTPUT, packageName, name + ".txt", element);

Writer writer = resource.openWriter();
writer.write(name.toString());
writer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return !elements.isEmpty();
}

private void assertThatClassIsOnClasspath(String fqcn) {
try {
getClass().getClassLoader().loadClass(fqcn);
} catch (ClassNotFoundException cnfe) {
String msg =
String.format("Expected class '%s' to be on the classpath (processorpath), but it wasn't.", fqcn);
throw new RuntimeException(msg, cnfe);
}
}
}

0 comments on commit 94eb582

Please sign in to comment.