5

I want to include the Java Bindings for V8 ("J2V8") in a Java project. The reasons are that (i) the V8 JavaScript engine is much faster then the JavaScript engine shipped with the JRE and (ii) the library I am using is available in JavaScript only and a port to Java is much effort.

The issue is that J2V8 is compiled for different platforms: linux 64bit, macos 64bit, windows 64 bit, windows 32 bit.

I now want to generate different JARs, containing all the dependencies (fat jars):

  • jabref-linux_x86_64.jar
  • jabref-macosx_x86_64.jar
  • jabref-windows_x86_32.jar
  • jabref-windows_x86_64.jar
  • jabref-all.jar - the platform indipendent JAR without v8 engine

I am currently creating fat jars using the shadow plugin.

Note that the project is not an Android project. There, with the Android plugin, it seems to be straight-forward to do that.

The first idea is to introduce configurations and configuration-specific dependencies:

configurations {
    linux_x86_64Compile.extendsFrom compile
    macosx_x86_64Compile.extendsFrom compile
    windows_x86_32Compile.extendsFrom compile
    windows_x86_64Compile.extendsFrom compile
}

dependencies {
    compile configuration: 'linux_x86_64',   group: 'com.eclipsesource.j2v8', name: 'j2v8_linux_x86_x64',  version: '4.6.0'
    compile configuration: 'macosx_x86_64',  group: 'com.eclipsesource.j2v8', name: 'j2v8_macosx_x86_x64', version: '4.6.0'
    compile configuration: 'windows_x86_32', group: 'com.eclipsesource.j2v8', name: 'j2v8_win32_x86',      version: '4.6.0'
    compile configuration: 'windows_x86_64', group: 'com.eclipsesource.j2v8', name: 'j2v8_win32_x86_x64',  version: '4.6.0'
...
}

But now I'm stuck. In pseudocode, I'd like to do:

task releaseSingleJar(dependsOn: "shadowJar", name) {
    doLast {
        copy {
            from("$buildDir/libs/JabRef-${project.version}-fat.jar")
            into("$buildDir/releases/")

            rename { String fileName ->
                fileName.replace('-fat', '-$name')
            }
        }
    }
}

task releaseJars() {
  forEach name in "linux_x86_64", "macosx_x86_64", "windows_x86_32", "windows_x86_64", "all":
     if (name != "all") activate configuration $name
     releaseSingleJar($name)

shadowJar is from the shadow plugin.

Background information

Related questions

The question Using Gradle to manage Java web app with flavors like Android has a similar title, but asks for source directories, whereas I ask for dependencies. Further, I want to generate a fat JAR and there a plain JAR seems to be enough. However, it might be that the solution is similar. A hint was to use the gradle-java-flavours plugin with the main source being JavaFlavoursExtension.groovy.

Following questions are similar to this one. However, the setting is related to Android apps and not to plain Java apps.

koppor
  • 19,079
  • 15
  • 119
  • 161

1 Answers1

1

You might be interested in my gradle-java-flavours plugin which creates source sets, configurations and compile, jar and test tasks for each flavour in a java only project.

eg:

import com.github.jengelman.gradle.plugins.shadow.tasks.*
plugins {
    id 'com.lazan.javaflavours' version '1.2'
    id 'com.github.johnrengelman.shadow' version '1.2.4'
}
def flavours = ['linux_x86_64', 'macosx_x86_64', ...]
javaFlavours {
    flavours.each {
        flavour it
    }
}
dependencies {
    linux_x86_64Compile      'aaa:aaa:1.0'
    linux_x86_64Runtime      'bbb:bbb:1.0'
    macosx_x86_64TestCompile 'ccc:ccc:3.0'
}
flavours.each { String flavour ->
    SourceSet flavourSourceSet = sourceSets.getByName(flavour)
    Configuration flavourRuntime = configurations.getByName("${flavour}Runtime")
    JavaCompile flavourCompileTask = tasks.getByName("compile${flavour.capitalize()}Java")
    Task shadowJarTask = tasks.create(name: "${flavour}ShadowJar", type: ShadowJar) {
        classifier = "${flavour}-all"
        dependsOn flavourCompileTask 
        // todo configure (likely based on Configuration and SourceSet)
    }
    artifacts {
        archives shadowJarTask 
    }
    // wire the task into the DAG
    assemble.dependsOn shadowJarTask
}
lance-java
  • 25,497
  • 4
  • 59
  • 101
  • It is unclear how to combine that with the [shadow plugin](https://github.com/johnrengelman/shadow). Do you think, that's easy? – koppor Apr 18 '17 at 04:49
  • Updated with a possible solution – lance-java Apr 18 '17 at 08:40
  • Thank you for the update. The tasks are there, but I get `compileMacosx_x86_64Java NO-SOURCE`. I really wonder why that appears. The flavoring config should extend the source locations and not replace them? (Current state: https://github.com/JabRef/jabref/blob/use-V8-for-citeproc/build.gradle#L75) – koppor Apr 18 '17 at 09:24
  • The plugin expects `src/$flavour/java` and `src/${flavour}Test/java` directories. Perhaps it should be smarter and should only enable the `JavaCompile` task if the directories exist. You could try `compileMacosx_x86_64Java.enabled = false` or adding the empty directories – lance-java Apr 18 '17 at 09:27
  • 1
    If you don't need all the functionality from the plugin (ie jar, test & compile tasks) then perhaps you are better off just copying the bits you need from [here](https://github.com/uklance/gradle-java-flavours/blob/master/src/main/groovy/com/lazan/javaflavours/JavaFlavoursExtension.groovy#L22) – lance-java Apr 18 '17 at 09:43