【问题标题】:Query DSL & Maven: Classes not generated, but only on command line (in eclipse it is working fine)查询 DSL 和 Maven:类未生成,但仅在命令行上(在 eclipse 中工作正常)
【发布时间】:2018-05-30 15:22:32
【问题描述】:

我们正在使用带有 Java 1.8 的 Spring Boot、Hibernate、Query DSL 和 Maven 的设置

最近,我已将 Query DSL 添加到项目中,配置如下所示。为了使其工作,我必须在 eclipse 项目设置中配置 Java 编译器以允许注释处理,并将 Query DSL .jar 文件添加到 eclipse 注释工厂路径。

此设置按预期工作。它生成了自定义的Q 类,我可以在我的代码中使用它们。现在在命令行上运行mvn clean install 时,我的代码中的每个类都会抛出错误cannot find symbol,因为缺少该类。还有什么我需要配置的 - 类似于 eclipse 设置中的.jar 文件 - 以使构建过程正常工作?

编辑: 这个问题不是 this question 的重复,因为我没有问为什么会出现这个错误(找不到符号),而是问如何配置 QueryDSL 也可以在命令行上工作.

EDIT2:我现在尝试集成 build-helper-maven-plugin 以使用多个源路径作为输入。这也没有帮助。我还尝试将文件生成到src 文件夹中。它也没有帮助。

当我第一次在eclipse中编译库时,mvn compile在命令行中通过,但mvn clean compile仍然失败,因为它只是再次使用了eclipse的编译文件。执行了 apt-maven-plugin,可以在构建过程失败之前看到:

[INFO] --- apt-maven-plugin:1.1.3:process (default) @ project1 ---
[INFO]
[INFO] --- build-helper-maven-plugin:1.9.1:add-source (add-source) @ project1 ---
[INFO] Source directory: C:\Users\user1\git\project1\src\main\generated added.
[INFO]
[INFO] --- maven-processor-plugin:2.2.4:process (process) @ project1 ---
[ERROR] diagnostic: [...]

EDIT3:当我删除每个引用 Q 类的导入语句时,构建过程会(显然)完成。然而,值得注意的是,Q 类在这种情况下被正确编译。它们应在 target 文件夹中以 .class 文件的形式出现。会不会是Q 类编译得太晚了?


这是pom.xml的摘录

<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    [...]
    <prerequisites>
        <maven>3.0.0</maven>
    </prerequisites>

    <dependencies>
        [...]
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
            <version>4.1.3</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
            <version>4.1.3</version>
        </dependency>
    </dependencies>

    <build>
        <defaultGoal>spring-boot:run</defaultGoal>
        <plugins>
            [...]
            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        [...]
    </build>
</project>

这是eclipse项目设置的配置:

这是控制台中显示的错误消息:

[INFO] --- maven-processor-plugin:2.2.4:process (process) @ project1 ---
[ERROR] diagnostic: C:\Users\user1\git\project1\src\main\java\com\project1\repository\UserRepositoryImpl.java:3: error: cannot find symbol
import static com.project1.domain.QUser.user;
                                     ^
  symbol:   class QUser
  location: package com.project1.domain

[ERROR] diagnostic: C:\Users\user1\git\project1\src\main\java\com\project1\repository\UserRepositoryImpl.java:3: error: static import only from classes and interfaces
import static com.project.domain.QUser.user;
^

【问题讨论】:

  • 正如我在上面所写的,很清楚为什么会发生此错误。生成的类不存在,因为在命令行上运行mvn compile 时未正确生成。然后它被导入,显然没有找到。但是,答案应该解决这个潜在的问题,而不是详细介绍这个错误。因此,不是重复的@feelingunwelcome

标签: java maven querydsl


【解决方案1】:

这是一个老问题,但这是我找到解决方案的方式,为 jpa 依赖添加了分类器:

    <!-- BEGIN: 'querydsl-jpa' -->
    <dependency>
        <groupId>com.mysema.querydsl</groupId>
        <artifactId>querydsl-jpa</artifactId>
        <version>${querydsl-jpa.version}</version>
        <classifier>apt</classifier>
    </dependency>
    <!-- END: 'querydsl-jpa' -->

我的完整 pom:

<!-- BEGIN: BUILD -->
<build>

    <!-- BEGIN: PLUGINS -->
    <plugins>

        <!-- BEGIN: apt-maven-plugin -->
        <plugin>
            <groupId>com.mysema.maven</groupId>
            <artifactId>apt-maven-plugin</artifactId>
            <version>${apt.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>process</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>target/generated-sources/apt</outputDirectory>
                        <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <!-- END: apt-maven-plugin -->

    </plugins>
    <!-- END: PLUGINS -->

</build>
<!-- END: BUILD -->

<!-- BEGIN: DEPENDENCIES -->
<dependencies>

    <!-- *********************************************** -->
    <!-- BEGIN: 'QUERYDSL DEPENDENCIES'                  -->

    <!-- BEGIN: 'querydsl-apt' -->
    <dependency>
        <groupId>com.mysema.querydsl</groupId>
        <artifactId>querydsl-apt</artifactId>
        <version>${querydsl-apt.version}</version>
    </dependency>
    <!-- END: 'querydsl-apt' -->

    <!-- BEGIN: 'querydsl-jpa' -->
    <dependency>
        <groupId>com.mysema.querydsl</groupId>
        <artifactId>querydsl-jpa</artifactId>
        <version>${querydsl-jpa.version}</version>
        <classifier>apt</classifier>
    </dependency>
    <!-- END: 'querydsl-jpa' -->

    <!-- *********************************************** -->
    <!-- END: 'QUERYDSL DEPENDENCIES'                    -->


</dependencies>

【讨论】:

    【解决方案2】:

    我宁愿只在数据库更改发生时使用配置文件来生成这些 Qclass。

    缺点:

    -当您不更改数据库架构时,您在拉取请求中的差异是干净的,因为对于每一代,这些文件往往会由于某种原因生成不同的(至少在我的情况下)。

    -您可以管理数据库中存在的表的女巫将具有 Qclasses(有时当您在更改数据库架构后忘记重新生成它们时会很痛苦)

    -嗯,这不是很多时间。但如果您不更改架构并且关闭配置文件,构建速度会更快。

    当您想要生成更改的架构 Qclasses 时,尝试这样的操作并打开配置文件:

    <properties>
        <whitelisted.tables>
            user_accunt,
            other
        </whitelisted.tables>
    </properties>
    <profiles>
        <profile>
            <id>generate</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>com.querydsl</groupId>
                        <artifactId>querydsl-maven-plugin</artifactId>
                        <version>${querydsl.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>export</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <jdbcDriver>org.postgresql.Driver</jdbcDriver>
                            <jdbcUrl>jdbc:postgresql://localhost:port/dbname</jdbcUrl>
                            <packageName>your.package.name.for.q</packageName>
                            <jdbcUser>dbusername</jdbcUser>
                            <jdbcPassword>dbpassword</jdbcPassword>
                            <targetFolder>${project.basedir}/src/main/java/</targetFolder>
                            <spatial>true</spatial>
                            <tableNamePattern>${whitelisted.tables}</tableNamePattern>
                        </configuration>
                        <dependencies>
                            <dependency>
                                <groupId>org.postgresql</groupId>
                                <artifactId>postgresql</artifactId>
                                <version>42.1.1</version>
                            </dependency>
                        </dependencies>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
    

    【讨论】:

    • 我宁愿在构建过程中直接生成这些文件。我还有几个需要生成的 DTO Q 类,所以它不仅在数据库更改时需要。不过还是谢谢!
    • 有没有办法运行 mvn 脚本来生成 Q 类,例如进入src/main/generated,然后将此文件夹用作常规maven构建中的第二个源文件夹?
    • 提供的 MVN 配置允许您在项目中使用这些类。您也可以始终创建不同的模块以将依赖项添加到另一个模块/模块。我可以想象这就是您想要实现的目标。
    【解决方案3】:

    生成的源目录不会自动包含在 jar 中。

    您需要使用 Maven 构建助手插件来修复此问题,例如:

    https://github.com/alexec/javahelp-skeleton/blob/master/pom.xml

    【讨论】:

    • 谢谢,我已经尝试过了,但没有成功。源已添加(根据 maven 日志)但发生相同的错误..
    【解决方案4】:

    你可以尝试几件事:

    1.尝试将&lt;clearOutputDir&gt;false&lt;/clearOutputDir&gt; 放入您的configuration 标签
    2. 有时类可能不会在编译阶段之前生成。所以试着在你的插件中加入相位

       <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>...</goal>
            </goals>
        </execution>
    


    【讨论】:

      【解决方案5】:

      按照惯例,Maven 假定所有源代码都在 'src/main/java' 中,编译它并将所有 *.class 文件放在目标中。

      因此,如果您在 &lt;project-root&gt;/alice/in/wonderland 中有一个类 'Alien.java',您将无法访问它(在 src/main/java 中),因为 maven 将 src/main/java 中的所有内容放在编译器的类路径中,并且因此编译器不知道其他任何地方的任何源代码(*.java)。

      在您的情况下,您在目录target/generated-sources/java 中生成源代码,因此您必须告诉 maven。正如在其他一些答案中提到的,您可以为此使用 build-helper-plugin,让 maven 知道您的源代码位于 target/generated-sources/java 上,由

       <project>
        ...
        <build>
          <plugins>
            <plugin>
              <groupId>org.codehaus.mojo</groupId>
              <artifactId>build-helper-maven-plugin</artifactId>
              <version>3.0.0</version>
              <executions>
                <execution>
                  <id>add-source</id>
                  <phase>generate-sources</phase>
                  <goals>
                    <goal>add-source</goal>
                  </goals>
                  <configuration>
                    <sources>
                      <source>target/generated-sources/java</source>
                      <source>alice/in/wonderland</source>
                    </sources>
                  </configuration>
                </execution>
              </executions>
            </plugin>
          </plugins>
        </build>
      </project>
      

      编辑:您在 build-helper-plugin 中提到了错误的路径

      我知道虽然您使用的是构建助手插件,但您使用的路径错误

       --- build-helper-maven-plugin:1.9.1:add-source (add-source) @ project1 ---
      [INFO] Source directory: C:\Users\user1\git\project1\src\main\generated added.
      

      你应该使用&lt;source&gt;target/generated-sources/java&lt;/source&gt;而不是src\main\generated

      【讨论】:

      • 我玩过这个插件,但它似乎根本没有做任何事情。输出显示添加了附加路径,但仍然无法编译。
      • 我也测试了多个路径,因此src/main/generatedtarget/generated-sources/java
      • @ssc-hrep3 能否给出maven的完整stacktrace?
      【解决方案6】:

      对我来说,它不起作用,因为它与已设置注释处理器的 maven-compiler-plugin 冲突。只是删除了 apt-maven-plugin 的使用,并在 maven-compiler-plugin 中添加了它的注解处理器。

          <build>
              <plugins>
      <!--            related to issues:-->
      <!--                - https://github.com/querydsl/querydsl/issues/2654 -->
      <!--                - https://github.com/querydsl/querydsl/issues/2242 -->
      <!--            Using apt-maven-plugin conflicts with other annotation processors (like mapStruct) -->
                  <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-compiler-plugin</artifactId>
                      <version>3.8.1</version>
                      <configuration>
                          <annotationProcessorPaths>
                              <path>
                                  <groupId>org.mapstruct</groupId>
                                  <artifactId>mapstruct-processor</artifactId>
                                  <version>${org.mapstruct.version}</version>
                              </path>
                              <path>
                                  <groupId>com.querydsl</groupId>
                                  <artifactId>querydsl-apt</artifactId>
                                  <version>5.0.0</version>
                                  <classifier>jpa</classifier>
                              </path>
                              <path>
                                  <groupId>jakarta.persistence</groupId>
                                  <artifactId>jakarta.persistence-api</artifactId>
                                  <version>2.2.3</version>
                              </path>
                              <path>
                                  <groupId>javax.annotation</groupId>
                                  <artifactId>javax.annotation-api</artifactId>
                                  <version>1.3.2</version>
                              </path>
                              <!-- other annotation processors -->
                          </annotationProcessorPaths>
                      </configuration>
                  </plugin>
      <!--            <plugin>-->
      <!--                <groupId>com.mysema.maven</groupId>-->
      <!--                <artifactId>apt-maven-plugin</artifactId>-->
      <!--                <version>1.1.3</version>-->
      <!--                <executions>-->
      <!--                    <execution>-->
      <!--                        <goals>-->
      <!--                            <goal>process</goal>-->
      <!--                        </goals>-->
      <!--                        <configuration>-->
      <!--                            <outputDirectory>target/generated-sources</outputDirectory>-->
      <!--                            <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>-->
      <!--                        </configuration>-->
      <!--                    </execution>-->
      <!--                </executions>-->
      <!--            </plugin>-->
              </plugins>
          </build>
      

      但是在 maven-compiler-plugin 中有一个 issue 使用 querydsl 注释处理器。您必须添加 jakarta.persistence-api 和 javax.annotation-api。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-31
        • 1970-01-01
        • 2011-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多