使用jOOQ 3.6+,纯SQL和javac编译器进行慢编译 [英] Slow compilation with jOOQ 3.6+, plain SQL, and the javac compiler

查看:235
本文介绍了使用jOOQ 3.6+,纯SQL和javac编译器进行慢编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

jOOQ用户组报告了以下错误。它似乎是javac编译器中的一个错误,与编译器在使用内部DSL(如 jOOQ)上下文中完成的复杂类型推断相关是。

The following bug was reported to the jOOQ user group. It really seems to be a bug in the javac compiler related to rather "complex" type inference work done by the compiler in the context of using an internal DSL like jOOQ is.

鉴于错误的一般性质,我在Stack Overflow上记录它,以便其他人帮助应用解决方法。在高级别上,由于 JEP 101:广义目标类型推论,它似乎是一个编译器性能回归,在Java 8中引入,并且在过去造成了1-2个问题。

Given the general nature of the bug, I'm documenting it here on Stack Overflow for others to help apply workarounds if they run into it. On a high level, it seems to be a compiler performance regression due to JEP 101: Generalized Target-Type Inference, which was introduced in Java 8 and has caused 1-2 issues in the past.

以下相对无害的类需要大约20秒来编译jdk 1.8.0_60或1.8.0_66在Windows上使用Maven和jOOQ 3.7:

The following relatively harmless class takes around 20 seconds to compile with jdk 1.8.0_60 or 1.8.0_66 on Windows using Maven and jOOQ 3.7:

import static org.jooq.impl.DSL.field;

import org.jooq.SQLDialect;
import org.jooq.impl.DSL;

public class Test {
    public void method() {
        DSL.using(SQLDialect.MYSQL)
           .select()
           .where(DSL.trueCondition())
           .and(field("client.id").eq(field("client_id")))
           .and(field("client.id").eq(field("client_id")))
           .and(field("client.id").eq(field("client_id")))
           .and(field("client.id").eq(field("client_id")))
           .and(field("client.id").eq(field("client_id")))
           .and(field("client.id").eq(field("client_id")))
           .and(field("client.id").eq(field("client_id")))
           .and(field("client.id").eq(field("client_id")))
           .and(field("client.id").eq(field("client_id")))
           .and(field("client.id").eq(field("client_id")))
        ;
    }
}

pom.xml:

<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>compilation-issues</groupId>
    <artifactId>compilation-issues</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq</artifactId>
            <version>3.7.1</version>
        </dependency>
    </dependencies>
</project>



未出现此问题时的配置:




  • 使用jOOQ 3.5(任何早于3.6.0的版本)

  • 使用jOOQ生成类而不是上述plain SQLAPI

  • 使用Java 7

  • 使用Eclipse编译器

  • Configurations when this issue doesn't appear:

    • Using jOOQ 3.5 (anything prior to 3.6.0)
    • Using jOOQ with generated classes rather than the above "plain SQL" API
    • Using Java 7
    • Using the Eclipse compiler
    • 推荐答案

      说明



      在jOOQ 3.6(当此问题第一次出现时), DSL.field c $ c> API看到22个新的重载,以不同的 Row 类型作为参数:

      • DSL.field(Row1<T1>)
      • DSL.field(Row2<T1, T2>)
      • DSL.field(Row3<T1, T2, T3>)
      • ...

      看起来,对于上面这个特定的API使用,新的重载会导致很多麻烦,当javac编译器试图找到所有可能的过载中最具体的过载。以下解决方法即时编译:

      It appears that with this particular API usage above, the new overloads cause a lot of trouble when the javac compiler tries to find the most specific overload among all the possible overloads. The following workaround compiles instantly:

      正在修正版本 3.9.0 3.8.1 3.7.4 , a href =https://github.com/jOOQ/jOOQ/issues/5236 =nofollow> 3.6.5 ,再次从公共API中删除这些方法,并提供重命名的替代品不会导致任何重载问题。

      A fix is under way for releases 3.9.0, 3.8.1, 3.7.4, 3.6.5, removing these methods again from the public API, and providing a renamed substitute that does not cause any overloading issues.

      import static org.jooq.impl.DSL.field;
      
      import org.jooq.Field;
      import org.jooq.SQLDialect;
      import org.jooq.impl.DSL;
      
      public class Test {
          public void method() {
              Field<Object> f1 = field("client.id");
              Field<Object> f2 = field("client_id");
              DSL.using(SQLDialect.MYSQL)
                 .select()
                 .where(DSL.trueCondition())
                 .and(f1.eq(f2))
                 .and(f1.eq(f2))
                 .and(f1.eq(f2))
                 .and(f1.eq(f2))
                 .and(f1.eq(f2))
                 .and(f1.eq(f2))
                 .and(f1.eq(f2))
                 .and(f1.eq(f2))
                 .and(f1.eq(f2))
                 .and(f1.eq(f2))
              ;
          }
      }
      



      2。在和()方法的上下文中完全阻止目标类型推断



      2. Preventing target type inference in the context of the and() method entirely

      import static org.jooq.impl.DSL.field;
      
      import org.jooq.Condition;
      import org.jooq.SQLDialect;
      import org.jooq.impl.DSL;
      
      public class Test {
          public void method() {
              Condition condition = field("client.id").eq(field("client_id"));
              DSL.using(SQLDialect.MYSQL)
                 .select()
                 .where(DSL.trueCondition())
                 .and(condition)
                 .and(condition)
                 .and(condition)
                 .and(condition)
                 .and(condition)
                 .and(condition)
                 .and(condition)
                 .and(condition)
                 .and(condition)
                 .and(condition)
              ;
          }
      }
      



      更多信息


      b $ b

      这实际上是在Stack Overflow之前报告的:

      More info

      This has actually been reported on Stack Overflow before:

      • Troubleshoot slow compilation
      • http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8086048

      并且已经在jOOQ用户组上进行了讨论:

      And it has been discussed also on the jOOQ user group:

      • https://groups.google.com/forum/#!topic/jooq-user/vuaG9d9krDk
      • https://groups.google.com/forum/#!topic/jooq-user/grv6Wu_sFtA

      这篇关于使用jOOQ 3.6+,纯SQL和javac编译器进行慢编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆