Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于远程JAR的Java注释处理器 一般问题_Java_Maven_Jpa_Annotation Processing_Javacompiler - Fatal编程技术网

用于远程JAR的Java注释处理器 一般问题

用于远程JAR的Java注释处理器 一般问题,java,maven,jpa,annotation-processing,javacompiler,Java,Maven,Jpa,Annotation Processing,Javacompiler,我有两个项目A和B;B依赖于a。我想基于a中对象的注释,在B中使用注释处理器生成一些代码。当我使用正确的处理器实现运行编译时,只从B中拾取注释对象 我理解默认情况下必须禁用扫描其他JAR,因为您通常不希望对所有依赖项进行注释扫描。我也明白,由于编译器的魔力,我想做的事情可能是不可能的——我对编译器的魔力知之甚少——但我希望不是这样 具体案例 我的项目叫做DB和WEB。WEB显然依赖DB进行JPA访问;这是在Maven中配置的。由于有许多架构选择,DB必须保持为一个单独的JAR。DB不使用Spri

我有两个项目A和B;B依赖于a。我想基于a中对象的注释,在B中使用注释处理器生成一些代码。当我使用正确的处理器实现运行编译时,只从B中拾取注释对象

我理解默认情况下必须禁用扫描其他JAR,因为您通常不希望对所有依赖项进行注释扫描。我也明白,由于编译器的魔力,我想做的事情可能是不可能的——我对编译器的魔力知之甚少——但我希望不是这样

具体案例 我的项目叫做DB和WEB。WEB显然依赖DB进行JPA访问;这是在Maven中配置的。由于有许多架构选择,DB必须保持为一个单独的JAR。DB不使用Spring,除了WEB使用的一些注释;WEB使用SpringMVC

我正试图用注释处理器为我的所有JPA实体生成
crudepository
接口。
@Repository
对象应该放在WEB项目中的
repo
包中,因此它们可以与
@Autowired
一起在WEB应用程序中的任何位置使用。我正在执行扫描的注释是
@javax.persistence.Entity
,但我也尝试了一个自定义注释,得到了相同的结果

@SupportedAnnotationTypes("javax.persistence.Entity")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class RepositoryFactory extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (Element e : roundEnv.getElementsAnnotatedWith(Entity.class)) {
            if (e.getKind() != ElementKind.CLASS) {
                continue;
            }
            // TODO: implement logic to skip manually implemented Repos
            try {
                String name = e.getSimpleName().toString();
                TypeElement clazz = (TypeElement) e;

                JavaFileObject f = processingEnv.getFiler().
                        createSourceFile("blagae.web.repo." + name + "Repo");
                try (Writer w = f.openWriter()) {
                    PrintWriter pw = new PrintWriter(w);
                    pw.println("package blagae.web.repo;");
                    pw.println("import org.springframework.data.repository.CrudRepository;");
                    pw.printf("import %s;\n", clazz.toString());
                    pw.println("import org.springframework.stereotype.Repository;");
                    pw.println("@Repository");
                    pw.printf("public interface %sRepo extends CrudRepository<%s, Long> {}\n", name, name);
                    pw.flush();
                }
            } catch (IOException ex) {
                Logger.getLogger(RepositoryFactory.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return false;
    }
}
但当然,我不指望它,因为它可能会被记录在某个地方。作为一种解决方法,我可以将Spring依赖项添加到db中并在那里生成类,但它们只在SpringMVC应用程序中起作用。我还对可能需要的配置持谨慎态度

更新 一些额外的信息:我正在使用maven处理器插件,我已经验证了它在WEB项目中对于在那里定义的类工作得很好。但是,我特别希望在依赖项项目DB中注释access类。我已经研究了方法
AbstractProcessor::getSupportedOptions
,但我不清楚我能在那里做什么

Maven配置:

<plugin>
    <groupId>org.bsc.maven</groupId>
    <artifactId>maven-processor-plugin</artifactId>
    <version>2.2.4</version>
    <configuration>
        <processors>
            <processor>blagae.utils.RepositoryFactory</processor>
        </processors>
    </configuration>
    <executions>
        <execution>
            <id>process</id>
            <goals>
                <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
        </execution>
    </executions>
</plugin>

org.bsc.maven
maven处理器插件
2.2.4
blagae.utils.RepositoryFactory
过程
过程
生成源
暗示
我的另一个随机想法是为WEB中的DB项目运行
JavaCompiler
进程,但是如何注入
处理器呢?

就我个人而言,我会在单独的maven模块中提取注释处理器,并从WEB模块向其添加依赖项

然而,对于成功触发注释处理器来说,这并不重要

为了让注释处理器工作,您必须提供两件事:

  • 扩展该类的类
  • 一个特殊文件,嵌套在项目的
    META-INF/services
既然您提到目前没有生成任何类,我就假设您丢失了元文件。因此,打开WEB项目并导航到
src/main/resources
文件夹。在中,您必须创建一个
META-INF
文件夹,其中包含嵌套的
services
文件夹。然后,在
services
中创建一个名为
javax.annotation.processing.Processor的文件。文件内容应列出注释处理器的完全限定类名。如果有多个注释处理器,则完全限定的类名应位于单独的行中。但既然你只有一个,你就会有这样的东西:

com.yourdomain.processor.RepositoryFactory
<build>
    <resources>
        ...
        <resource>
            <directory>${project.build.directory}/generated-resources</directory>
        </resource>
    </resources>
</build>
请注意,您必须使用注释处理器的实际完全合格类名更改此行

最后,您应该得到类似的结构:

这个元文件很重要,因为否则编译器不会知道用户定义的注释处理器。有了它,它将使用所有注册的处理器

之后,当您执行
mvn清理安装时
将清理并构建所有模块。但是,由于编译器现在会知道您的注释处理器,因此会触发它。所有生成的源(默认情况下)将位于
目标/生成的源
文件夹中。此外,它们都将位于您在注释过程中配置的包下,即
blagae.web.repo

为了在代码中使用生成的源,必须将
targetr/generated sources
添加到项目类路径中。如果您不想依赖IDE来实现这一点,可以通过向类路径添加
目标/生成源来扩展maven
。比如:

com.yourdomain.processor.RepositoryFactory
<build>
    <resources>
        ...
        <resource>
            <directory>${project.build.directory}/generated-resources</directory>
        </resource>
    </resources>
</build>

...
${project.build.directory}/生成的资源

注释处理器在项目的编译阶段工作(在您的案例中是WEB),编译器编译此项目。当前项目的依赖项已经编译,编译器(以及您的注释处理器)不会接触(或无法访问)第三方库(DB)


您可以尝试将注释处理器提取到单独的project/jar中,并在WEB和DB项目中使用它。在这种情况下,注释处理器将在具体项目的编译阶段创建
crudepository
。DB project中生成的所有类都将在WEB上可用。

在项目A中包括META-INF/beans.xml文件, 其中将包含以下内容:

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee <a href="http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd">http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"</a>
       version="1.1" bean-discovery-mode="all">
</beans>

我不明白这个问题-注释处理器不工作或…?:)我希望在WEB项目上运行注释处理器时从DB项目(=jar)中提取注释。到目前为止,这种情况还没有发生。我可以提出一个解决方案。等一会儿,我好把它写下来