标签: annotation-processing

如何使用Java 1.6 Annotation Processing执行编译时编织?

我创建了一个注释,将其应用于DTO并编写了Java 1.6样式的annotationProcessor.我可以看到如何让annotationProcessor编写一个新的源文件,这不是我想要做的,我看不到或者找不到如何修改现有的类(理想情况下只是修改字节代码).修改实际上是相当简单的,我希望处理器做的就是插入一个新的getter和setter,其名称来自正在处理的注释的值.

我的注释处理器看起来像这样;

@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes({ "com.kn.salog.annotation.AggregateField" })
public class SalogDTOAnnotationProcessor extends AbstractProcessor {

    @Override
    public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
        //do some stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

java annotations compile-time-weaving annotation-processing

7
推荐指数
4
解决办法
8589
查看次数

Java:反射(在运行时)与镜像(在注释处理中)

我理解概念之间的一般差异

  • 反射(在运行时使用Class, Method, Field, Annotation, ...),和
  • 镜像(在注释处理期间使用TypeMirror, TypeElement, ...).

但有人可以请深入比较这两个概念(或指向一个资源,它在哪里完成)?

例如,哪个概念提供了另一个不提供的信息......

谢谢.

java reflection types mirroring annotation-processing

7
推荐指数
1
解决办法
2101
查看次数

注释处理器上具有级别Diagnostic.Kind.NOTE(和其他)的消息

我有两个Maven项目:

  • 第一个定义注释,注释处理器提供者配置文件,以通过ServiceLoader API触发注释处理器.
  • 另一个依赖于第一个并定义了一些类和接口,其中一个用第一个项目中定义的注释进行注释.

我调用第二个项目的构建(在构建并安装第一个项目之后)mvn clean && mvn compile,以确保编译将发生并且注释处理将运行.它按预期工作:简单的annontation处理器只在target/classes/包含一些虚拟数据的目录中生成一个资源文件.

当我尝试输出一些信息时,processingEnv.getMessager().printMessage(...)我开始遇到麻烦.如果我使用Diagnostic.Kind.ERROR,构建停止并打印消息,正如我所料.但是,对于任何其他Kind(例如NOTEWARNING),消息不会写在屏幕上!

有关我的环境的一些信息:

Kubuntu 12.10
Linux 3.5.0-17-generic
Apache Maven 3.0.4 (r1232337; 2012-01-17 06:44:56-0200)
Java version: 1.7.0_09, vendor: Oracle Corporation
Run Code Online (Sandbox Code Playgroud)

我没有明确声明maven-compiler-plugin任何地方的版本,所以它必须使用默认版本(2.3.2?我不确定).

如何Kind在此设置中启用所有消息的输出?(即通过maven启动annontation处理器)

java maven annotation-processing

7
推荐指数
2
解决办法
1224
查看次数

现代Java注释处理

注释处理仍然是Java 6+的活跃部分,还是已经被弃用/不鼓励/过时的东西.如果过时了,为什么(为什么它不再需要/有用)?如果它仍然非常有用且"活跃"(针对Java 6+ JDK开发的新Java项目仍将从中受益),请确认/更正我如何使用注释处理器的理解:

  1. 你可以创建自己的注释类 @MyAnnotation
  2. 您可以使用标记某些类,方法,字段等 @MyAnnotation
  3. 在构建过程中,您调用自定义MyAnnotationProcessor(如何?)
  4. 处理器扫描您的类路径以查找实例 @MyAnnotation
  5. 通常,注释处理器执行动态字节码注入,即时修改/增强已编译的类

java annotations annotation-processing

7
推荐指数
1
解决办法
4000
查看次数

使用Intellij和Maven调试Java注释处理器

我正在尝试学习如何制作自定义注释处理器,而我却一直试图调试它.

我已经设法在调试模式下运行javac编译器(使用mvnDebug clean install)(与其他人的项目一起使用注释处理器),使用IntelliJ IDEA连接到它并让它停在注释处理器的断点处.


如果我们在项目的某些包中有这样的东西,就像任何其他类一样(例如,没有特殊配置或任何东西):

public class MyProcessor extends AbstractProcessor {...}
Run Code Online (Sandbox Code Playgroud)

我们能否以某种方式将其作为注释处理器挂钩到maven的构建过程中?因此首先编译它,然后整个项目在注释处理器处于活动状态时进行编译.

另外,据我所知,注释处理器需要某种META INF文件,可以使用google autoservices注释处理器生成.

所以也许是一个maven构建过程,我们首先运行自动服务,然后将扩展AbstractProcessor的类作为注释处理器进行编译,最后让整个项目使用我们自己的注释处理器进行编译(并在调试模式下使用javac编译器).

java debugging annotations maven annotation-processing

7
推荐指数
1
解决办法
3172
查看次数

找不到Maven注释处理处理器

我是注释处理的新手,我正在尝试使用Maven使其自动化。我把它放在我的pom.xml中:

<plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.0</version>
            <configuration>
                <annotationProcessors>
                    <annotationProcessor>
                        co.aurasphere.revolver.annotation.processor.InjectAnnotationProcessor</annotationProcessor>
                    <annotationProcessor>
                        co.aurasphere.revolver.annotation.processor.RevolverContextAnnotationProcessor</annotationProcessor>
                </annotationProcessors>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
    </plugins>
Run Code Online (Sandbox Code Playgroud)

问题是,当我尝试构建项目时,由于Maven无法找到处理器,所以我收到CompilationFailureException。

我发现了这样的其他问题,可以通过将依赖项放在插件之外来解决。我尝试过,但是对我来说没有任何改变。

我想念什么吗?

谢谢。

编辑

这是我对另一个包含处理器和注释的项目的依赖:

    <dependencies>
    <dependency>
        <groupId>co.aurasphere</groupId>
        <artifactId>revolver-annotation-processor</artifactId>
        <version>0.0.3-SNAPSHOT</version>
    </dependency>
</dependencies>
Run Code Online (Sandbox Code Playgroud)

编辑2

经过进一步调查,我决定反编译处理器JAR(使用Maven构建),并且碰巧...我的类不在那里。由于某些原因,Maven没有将我的类编译到JAR中,这就是为什么找不到这些类的原因。我已经尝试找出该版本的问题(以前从未发生过这种情况,而我已经使用Maven了一段时间……)。

首先,该项目的包装是jar。这些类都在src / main / java下。我已经在pom.xml中检查了类路径和源路径是相同的。

这是处理器pom:

<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>
<groupId>co.aurasphere</groupId>
<artifactId>revolver-annotation-processor</artifactId>
<version>0.0.3-SNAPSHOT</version>
<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
    </plugins> 
</build>
<dependencies>
    <!-- https://mvnrepository.com/artifact/javax.inject/javax.inject -->
    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.velocity/velocity -->
    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity</artifactId>
        <version>1.7</version>
    </dependency>


</dependencies>
Run Code Online (Sandbox Code Playgroud)

编辑3 …

java annotations maven annotation-processing

7
推荐指数
2
解决办法
8806
查看次数

如何使用@Target(ElementType.TYPE_USE)处理注释?

我正在实现一个注释处理器,以确保标记有注释的元素是实现某个接口的类的实例,或者是实现某个接口的类型的使用:

@Documented
@Target(value = { ElementType.PARAMETER, ElementType.TYPE_USE })
@Retention(value = RetentionPolicy.RUNTIME)
public @interface AuditSubject {

}

public interface Auditable {
    // methods that provide data for writing a log entry...
}

public class Report implements Auditable {

}
Run Code Online (Sandbox Code Playgroud)

对于带注释的元素,必须在方法执行后(使用AOP)创建日志条目.例子:

@CreateLogEntry
public Result persist(@AuditSubject Report newReport) {
    // A log entry must be created based on the incoming 'newReport' instance.    
}

@CreateLogEntry
public UpdateResult<@AuditSubject Report> update(Report update) {
    // A log entry must be created based on the updated report, which …
Run Code Online (Sandbox Code Playgroud)

java annotations annotation-processing java-8 annotation-processor

7
推荐指数
2
解决办法
581
查看次数

使用kapt和gradle时无法调试注释处理器

我正在构建一个注释处理器,我最近使用kotlin-kapt插件从使用默认的annotationProcessor类型转换为kapt.

我正在使用该命令调试我的处理器

./gradlew --no-daemon -Dorg.gradle.debug=true :app:clean :app:compileDebugJavaWithJavac
Run Code Online (Sandbox Code Playgroud)

(完整说明:https://stackoverflow.com/a/42488641/502463)

然后运行远程调试配置.当我使用annotationProcessor时,我可以点击断点,并进行调试.使用kapt,我的处理器运行,但我无法调试它.没有触发断点.

我的kotlin版本是1.1.2-3

remote-debugging annotation-processing kotlin kapt annotation-processor

7
推荐指数
1
解决办法
2108
查看次数

将 Mapstruct 与 Kotlin 结合使用生成源时出现 NonExistentClass 错误

我想使用 Mapstruct 将内部模型映射到 Kotlin 项目中由 OpenApi3 codegen 生成的模型。

当我编译项目时,Mapstruct 似乎无法找到 OpenApi3 codegen 插件生成的源,因为生成的实现包含 aNonExistentClass而不是我的 OpenApi 模型。

我的插件配置是

<plugin>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-maven-plugin</artifactId>
    <configuration>
        <args>
            <arg>-Xjsr305=strict</arg>
        </args>
        <compilerPlugins>
            <plugin>spring</plugin>
            <plugin>jpa</plugin>
        </compilerPlugins>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-allopen</artifactId>
            <version>${kotlin.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-noarg</artifactId>
            <version>${kotlin.version}</version>
        </dependency>
    </dependencies>

    <executions>
        <execution>
            <id>kapt</id>
            <phase>process-sources</phase>
            <goals>
                <goal>kapt</goal>
            </goals>
            <configuration>
                <sourceDirs>
                    <sourceDir>src/main/kotlin</sourceDir>
                    <sourceDir>src/main/java</sourceDir>
                </sourceDirs>
                <annotationProcessorPaths>
                    <annotationProcessorPath>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${mapstruct.version}</version>
                    </annotationProcessorPath>
                </annotationProcessorPaths>
            </configuration>
        </execution>

        <execution>
            <id>compile</id>
            <phase>process-sources</phase>
            <goals>
                <goal>compile</goal>
            </goals>
        </execution>
        <execution>
            <id>test-compile</id>
            <phase>process-test-sources</phase>
            <goals>
                <goal>test-compile</goal>
            </goals>
        </execution>

    </executions>
</plugin> …
Run Code Online (Sandbox Code Playgroud)

annotation-processing kotlin mapstruct openapi

7
推荐指数
1
解决办法
1684
查看次数

使用注释处理器时,IntelliJ 中的 Maven 项目构建失败(google/auto-value)

我使用google/auto-value在 maven 项目中创建不可变的值类。

<?xml version="1.0" encoding="UTF-8"?>
<project 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"
         xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>
    [...]
    <packaging>war</packaging>

    <properties>
        <auto-value.version>1.7</auto-value.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>com.google.auto.value</groupId>
                            <artifactId>auto-value</artifactId>
                            <version>${auto-value.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.google.auto.value</groupId>
            <artifactId>auto-value-annotations</artifactId>
            <version>${auto-value.version}</version>
        </dependency>

        [...]

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.5.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
Run Code Online (Sandbox Code Playgroud)

这就像使用 CLI(例如mvn clean test)的魅力一样,但在 IntelliJ 项目构建期间会产生错误:

Error:java: java.lang.NoClassDefFoundError: com/google/auto/service/AutoService
com.google.auto.service.AutoService
Run Code Online (Sandbox Code Playgroud)

值得注意的是:正确的源代码生成到generated-sources/annotations/...但在这一步之后 IntelliJ 构建失败并且不会创建生成的测试源目录generated-test-sources/...

虽然可以通过将另一个注释处理器路径添加到 maven-compiler-plugin

<path>
    <groupId>com.google.auto.service</groupId>
    <artifactId>auto-service</artifactId>
    <version>1.0-rc6</version>
</path>
Run Code Online (Sandbox Code Playgroud)

此修复程序的缺点是auto-service在 …

intellij-idea maven annotation-processing auto-value

7
推荐指数
2
解决办法
1871
查看次数