简体   繁体   中英

Gradle Flavors For War Files

I'm attempting to build debug and release war files using different java code - much in the same way that Android build flavors work. Basically I want to wrap a logger around my DataSource using either P6Spy or datasource-proxy during development, but definitely don't want to ship either in the release build. I'd prefer to do this in code, rather than at the datasource definition in the app server.

My build.gradle looks something like this:

apply plugin: 'java'
apply plugin: 'war'

configurations {
  // debug
  debugImplementation.extendsFrom implementation
  debugRuntimeOnly.extendsFrom runtimeOnly
  debugCompileOnly.extendsFrom compileOnly

  // release
  releaseImplementation.extendsFrom implementation
  releaseRuntimeOnly.extendsFrom runtimeOnly
  releaseCompileOnly.extendsFrom compileOnly
}

sourceSets {
  debug {
    java {
      compileClassPath += main.compileClasspath
      runtimeClassPath += main.runtimeClasspath
      srcDirs = ['src/debug/java','src/main/java']
    }
  }
  release {
    java {
      compileClassPath += main.compileClasspath
      runtimeClassPath += main.runtimeClasspath
      srcDirs = ['src/release/java','src/main/java']
    }
  }
}

dependencies {
   debugImplementation 'logging:artifact'
}

task debugWar(type: War, group: "Build") {
    from sourceSets.debug.output
    classifier = 'debug'
}

I have the database management class in both src/release/java and src/release/debug (I haven't applied the wrapper yet, just trying to get everything to compile).

This kind of works - well, at least, compileDebugJava and compileDebugRelease works. However the compileClasses and compileJava tasks fail - and that's to be expected, the code has dependencies on the class that needs to vary.

However it appears that compileJava is called from the debugWar task, and I haven't been able to figure out how to remove that dependency, or to get it to just call the debugCompileJava task instead of the compileJava .

Unfortunately I'm not in a situation where I can use DI, or to modify the code to use an interface.

There's also the issue of IDE integration. It looks like most IDEs want to use compileClasses. Since that fails, the IDE integration starts to break. What would be ideal, is would be to use all the Debug tasks as the default.

I've tried having the release version of the class in the main code, and just having an debug version in the debug code, but that results in a duplicate class error. This woul

Is there any way to get this to do what I want, or something close to it?

There are a quite a few hoops I had to go through to get a working configuration, but a working configuration I have.

First, to avoid the default compile/process resources tasks from failing, I set the java and resources srcDirs to nothing. Then I discovered the war plugin doesn't care about what you have configured in your sourceSets - it's always going to use the same folders for things - so debug and release builds/resources share the same build paths. And the war plugin also won't pick up from your dependencies, so to get the debugImplemenation for one of the JDBC wrappers, I had to include a "debug" configuration

sourceSets {

    // override the main, telling gradle main has no sources.
    main {
        java { srcDirs = [] }
        resources { srcDirs = [] }
    }

    // debug builds
    debug {
        java {
            compileClasspath += main.output
            runtimeClasspath += main.output
            //  combine code from main and debug java code
            srcDirs = ['src/debug/java', 'src/main/java']
        }
        // combine resources
        resources {
            srcDirs = ['src/debug/resources', 'src/main/resources']
        }
        // override the resources and classes output, for compatibility with the war plugin
        output.resourcesDir = 'build/resources/main'
        output.classesDir = 'build/classes/java/main'
    }

    // release builds
    release {
        java {
            compileClasspath += main.output
            runtimeClasspath += main.output
            //  combine code from main and release java code
            srcDirs = ['src/release/java', 'src/main/java']
        }
        // combine resources
        resources {
            srcDirs = ['src/release/resources', 'src/main/resources']
        }
        // override the resources and classes output, for compatibility with the war plugin
        output.resourcesDir = 'build/resources/main'
        output.classesDir = 'build/classes/java/main'
    }
}

task debugWar(type: War, group: 'Build') {
    classifier 'SNAPSHOT'
    from sourceSets.debug.output
    // add the debug dependencies
    classpath configurations.debug    
}

task releaseWar(type: War, group: 'Build') {
    from sourceSets.release.output    
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM