22

Is it possible to have build variants based on different source sets for a traditional Java app (NOT an Android project) in IntelliJ?

I'd like to use a feature like productFlavors that comes with the Android gradle plugin, but for a traditional Java application.

Example:

library_red -- HelloImpl.java
library_blue -- HelloImpl.java
library_common -- Hello.java

compiled library_blue -- Hello.class, HelloImpl.class
compiled library_red -- Hello.class, HelloImpl.class
EricSchaefer
  • 25,272
  • 21
  • 67
  • 103
user3904083
  • 331
  • 2
  • 5
  • Here is an answer using maven: https://stackoverflow.com/questions/5162009/building-artifacts-for-multiple-java-architectures-using-maven-anything-better – RobbingDaHood Jan 24 '22 at 18:37

4 Answers4

0

The answer is yes but you will have to use the new Gradle software model which is very much incubating. It will be a road full of pain as you will be a trail blazer as I have learned using it for a C/Cpp project. Here is generally how your build will look like.

plugins {
    id 'jvm-component'
    id 'java-lang'
}

model {
  buildTypes {
    debug
    release
  }
  flavors {
    free
    paid
  }
    components {
        server(JvmLibrarySpec) {
            sources {
                java {
                  if (flavor == flavors.paid) {
                    // do something to your sources
                  }
                  if (builtType == buildTypes.debug) {
                    // do something for debuging
                  }
                    dependencies {
                        library 'core'
                    }
                }
            }
        }

        core(JvmLibrarySpec) {
            dependencies {
                library 'commons'
            }
        }

        commons(JvmLibrarySpec) {
            api {
                dependencies {
                    library 'collections'
                }
            }
        }

        collections(JvmLibrarySpec)
    }
}

Reference: https://docs.gradle.org/current/userguide/java_software.html

Michael Hobbs
  • 1,663
  • 1
  • 15
  • 26
0

We use Gradle multi-module projects for our variant system. There is a core project that contains the common code. Customizations are simply done in subprojects.

subprojects {
   dependencies {
     compile project(':core')
   }
}

The variant subprojects depend on the core and each build individual .war files. Note that in this case we don't override classes from the core project. For code customizations we use Spring and in some cases SPI, but I guess any dependency injection framework can accomplish that. It just forces you to provide explicit extension points in the core which I think is a good thing.

tobiasH
  • 411
  • 5
  • 11
0

Maven allows you to create profiles for different configurations of your project. For example, you can specify different Java versions, dependencies, plugins, etc. for each profile. Profiles can be activated by various criteria, such as environment variables, JDK versions, or command line parameters. You can also use different pom.xml files for the same project, but this is not recommended as it can cause confusion and inconsistency. Profiles are a more flexible and maintainable way to manage your project settings. You can learn more about profiles here: https://maven.apache.org/guides/introduction/introduction-to-profiles.html

yora
  • 19
  • 4
0

I am using maven profiles. It is very flexible and convenient. With a profiles you can define especial properties, dependencies, modules, builds for each profile. Profiles could be activated by environment variables or command line parameters. You could combine your profiles. IntelliJ maven view gives you a convenient way to activate profiles. See below the pom.xml example with profiles.

<?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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>test</artifactId>
  <packaging>pom</packaging>
  <version>1.0-SNAPSHOT</version>

  <profiles>
      <profile>
          <id>blue</id>
          <modules>
              <module>module-1</module>
          </modules>
          <dependencies>
              <dependency>
                  <groupId>org.apache.logging.log4j</groupId>
                  <artifactId>log4j-api</artifactId>
                  <version>2.11.1</version>
              </dependency>
          </dependencies>
      </profile>
      <profile>
          <id>red</id>
          <modules>
              <module>module-2</module>
          </modules>
          <dependencies>
              <dependency>
                  <groupId>org.apache.logging.log4j</groupId>
                  <artifactId>log4j-api</artifactId>
                  <version>2.15.0</version>
              </dependency>
          </dependencies>
      </profile>
  </profiles>

  <modules>
      <module>main</module>
  </modules>

  <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties> </project>
oem
  • 1
  • 1
  • 1