Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

build multiple jars from a single project source

Tags:

gradle

I'm fairly new to gradle.

I'd like to find out if it is possible to build multiple jars from the same project source. I've browsed previous similar questions, but my situation is a little different. I'd like to compile all the source files twice to produce two different jars, each with different dependencies, and different artifact ids. Conceptually it may be represented as follows:

  • project "FooBase"
    • src/main/java/...
    • depends on library Bar version 1.0.0
    • compiles all source and produces "org.foo/Foo1" (group/artifact)
  • project "Foo2"
    • no source of its own, or may add source
    • depends on library Bar version 2.0.0
    • compiles all source in "FooBase" and its source, and produces "org.foo/Foo2" (group/artifact)

Is this sort of build possible with gradle? What would be the best approach? Thanks!

like image 416
sjlee Avatar asked Mar 21 '13 22:03

sjlee


People also ask

What is multi Release jar?

A multi-release JAR file allows for a single JAR file to support multiple major versions of Java platform releases. For example, a multi-release JAR file can depend on both the Java 8 and Java 9 major platform releases, where some class files depend on APIs in Java 8 and other class files depend on APIs in Java 9.

How do I combine jar files?

Just unzip both jar files, then zip the results into one zip file, and rename this to jar again.

How do I select multiple JAR files in eclipse?

Hold the shift key down while clicking on additional jars to add within the folder. This will allow you to select and add more than one at a time.


1 Answers

One clean way of achieving what you want is to create a multi-project build, with two subprojects (foobase & foo2), where the source sets for foo2 is configured to contain the source sets of foobase in addition to its own sources.

To get different dependencies for the artifacts, you will just need to declare the dependencies section differently in the subprojects.

To test this, I created a multiproject build with one java file in each subproject. To simplify the output here, the root build.gradle file contains everything, including subproject specific customizations. In "real life" though, I always put subproject specific configurations in a build.gradle file at the correct subproject level.

The gradle build file contains

  • Adding source sets from foobase to foo2
  • Different dependencies in the two projects
  • Deployment to a local maven repository (to verify that pom's are created correctly)
  • Optional IDE plugins for IntelliJ IDEA and Eclipse

All in all, I ended up with the following:

Project structure

build.gradle                      => root project build file
settings.gradle                   => specification of included subprojects
foo2\                             => foo2 subproject folder
  src\
    main\
      java\
        Foo2.java                 => Empty class
foobase\                          => foobase subproject folder
  src\
    main\
      java\
        FooBase.java              => Empty class

settings.gradle

include ':foobase', ':foo2'

build.gradle

allprojects {
    apply plugin: 'idea'
    apply plugin: 'eclipse'
    group = 'org.foo'
    version = '1.0'
}

subprojects {
    apply plugin: 'java'
    apply plugin: 'maven'

    repositories {
        mavenCentral()
    }

    uploadArchives {
        it.repositories.mavenDeployer {
            repository(url: "file:///tmp/maven-repo/")
        }
    }
}

project(':foobase') {
    dependencies {
        compile 'log4j:log4j:1.2.13'
    }
}

project(':foo2') {
    dependencies {
        compile 'log4j:log4j:1.2.16'
    }

    sourceSets.main.java.srcDirs        project(':foobase').sourceSets.main.java
    sourceSets.main.resources.srcDirs   project(':foobase').sourceSets.main.resources
    sourceSets.test.java.srcDirs        project(':foobase').sourceSets.test.java
    sourceSets.test.resources.srcDirs   project(':foobase').sourceSets.test.resources
}

Note that I added the source directories for resources and tests as well. You may omit the last three lines if that is not required.

To verify the build:

  • Make sure that the two jar files contains all the wanted classes.
  • Verify that the two deployed maven pom's has the correct dependencies.

In my case:

  • foobase-1.0.jar contains only FooBase.class
  • foo2-1.0.jar contains both FooBase.class and Foo2.class
  • the uploaded foobase-1.0.pom contains a dependency to log4j-1.2.13
  • the uploaded foo2-1.0.pom contains a dependency to log4j-1.2.16
like image 89
Steinar Avatar answered Jan 03 '23 16:01

Steinar