Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering a Java class with Gradle

I have the following class in src/main/java/com/company/project/Config.java:

public class Config {

  public static final boolean DEBUG = true;

  ...
}

so that in some other class I can do the following, knowing that the java compiler will strip the if() statement if it evaluates to false:

import static com.company.project.Config.DEBUG

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

  log.debug("something");
}

In Gradle, what is the best way to filter and change DEBUG value in Config.java at compile time without modifying the original file?

So far I'm thinking:

  1. Create a task updateDebug(type:Copy) that filters DEBUG and copies Config.java to a temporary location
  2. Exclude from sourceSets the original Config.java file and include the temporary one
  3. Make compileJava.dependsOn updateDebug

Is the above possible? Is there a better way?

like image 855
Mirco Avatar asked Oct 31 '22 07:10

Mirco


1 Answers

To answer my own question, given the class src/main/java/com/company/project/Config.java:

public class Config {

  public static final boolean DEBUG = true;

  ...
}

this is the Gradle code I came up with:

//
// 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
}

It's admittedly a little hacky but it works, and it gives me the most efficient solution while still controlling development/production builds from a single point of entry (build.gradle).

like image 156
Mirco Avatar answered Nov 13 '22 21:11

Mirco