【问题标题】:Filtering a Java class with Gradle使用 Gradle 过滤 Java 类
【发布时间】:2015-05-25 13:52:38
【问题描述】:

我在 src/main/java/com/company/project/Config.java 中有以下类:

public class Config {

  public static final boolean DEBUG = true;

  ...
}

以便在其他类中我可以执行以下操作,知道如果 if() 语句的计算结果为 false,java 编译器将删除它:

import static com.company.project.Config.DEBUG

if (DEBUG) {
  client.sendMessage("something");

  log.debug("something");
}

在 Gradle 中,在不修改原始文件的情况下,在编译时过滤和更改 Config.java 中的 DEBUG 值的最佳方法是什么?

目前我在想:

  1. 创建一个过滤 DEBUG 并将 Config.java 复制到临时位置的任务 updateDebug(type:Copy)
  2. 从源中排除原始 Config.java 文件并包含临时文件
  3. make compileJava.dependsOn updateDebug

以上可能吗? 有没有更好的办法?

【问题讨论】:

  • 不保证编译器会去掉永远为假的 if 分支。
  • @Marco 感谢您的链接,但是为了让编译器能够删除 if() 语句,DEBUG 变量必须在编译时初始化,而不是在运行时初始化
  • 如果您使用任何类型的标准记录器,您为什么关心记录调试消息?如果您不希望它们出现,请将应用程序的日志级别配置为大于 DEBUG(可能是“信息”)。

标签: java regex gradle filtering


【解决方案1】:

回答我自己的问题,给定类 src/main/java/com/company/project/Config.java:

public class Config {

  public static final boolean DEBUG = true;

  ...
}

这是我想出的 Gradle 代码:

//
// Command line: gradle war -Production
//
boolean production = hasProperty("roduction");

//
// Import java regex
//
import java.util.regex.*

//
// Change Config.java DEBUG value based on the build type
//
String filterDebugHelper(String line) {
  Pattern pattern = Pattern.compile("(boolean\\s+DEBUG\\s*=\\s*)(true|false)(\\s*;)");
  Matcher matcher = pattern.matcher(line);
  if (matcher.find()) {
    line = matcher.replaceFirst("\$1"+(production? "false": "true")+"\$3");
  }

  return (line);
}

//
// Filter Config.java and inizialize 'DEBUG' according to the current build type
//
task filterDebug(type: Copy) {
  from ("${projectDir}/src/main/java/com/company/project") {
    include "Config.java"

    filter { String line -> filterDebugHelper(line) }
  }
  into "${buildDir}/tmp/filterJava"
}

//
// Remove from compilation the original Config.java and add the filtered one
//
sourceSets {
  main {
    java {
      srcDirs ("${projectDir}/src/main/java", "${buildDir}/tmp/filterJava")
      exclude ("com/company/project/Config.java")
    }

    resources {
    }
  }
}

//
// Execute 'filterDebug' task before compiling 
//
compileJava {
  dependsOn filterDebug
}

诚然,它有点 hacky,但它确实有效,它为我提供了最有效的解决方案,同时仍然从单一入口点 (build.gradle) 控制开发/生产构建。

【讨论】:

    猜你喜欢
    • 2011-08-30
    • 1970-01-01
    • 2013-12-04
    • 2018-01-27
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    相关资源
    最近更新 更多