Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared code between Kotlin server and client projects using Gradle

Tags:

gradle

kotlin

I want to share some of the code between the server (JVM) and the client (JS) using a separate shared project. I've seen a solution using Maven, but I'm not sure how to convert this to a Gradle project. Also, there aren't any examples of shared projects in the official guide. So, how would a minimal build.gradle with such setup look?

like image 859
Czyzby Avatar asked Jan 25 '16 17:01

Czyzby


2 Answers

For completeness, this is the setup I was creating pretty much simultaneously with hotkey:

Main settings.gradle: include 'shared', 'client', 'server'

Main build.gradle:

buildscript {
  ext {
    kotlinVer = '1.0.0-beta-4589'
  }
  repositories {
    mavenCentral()
    maven {
      url 'http://oss.sonatype.org/content/repositories/snapshots'
    }
  }
  dependencies {
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVer"
  }
}

allprojects {
  apply plugin: 'idea'
  group = 'some.company'
  version = '0.0.1'

  ext {
    kotlinVer = '1.0.0-beta-4589'
    // Lib versions go there.
  }
  repositories {
    mavenLocal()
    mavenCentral()
    maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
    maven { url "https://oss.sonatype.org/content/repositories/releases/" }
  }
}

project('shared') {
  apply plugin: 'kotlin'
}

project('server') {
  apply plugin: 'kotlin'
  apply plugin: 'application'

  mainClassName = 'some.company.Main'
  dependencies {
    compile project(':shared')
  }
}

project('client') {
  apply plugin: 'kotlin2js'
  dependencies {
    compile project(':shared')
  }
}

Client build.gradle:

apply plugin: 'kotlin2js'

compileKotlin2Js {
  kotlinOptions.outputFile = "server/src/main/resources/static/js/app.js"
  kotlinOptions.sourceMap = true
}

sourceSets {
  main.kotlin.srcDirs += '../shared/src/main/kotlin'
  // hotkey's solution:
  // main.kotlin.srcDirs += project(':shared').sourceSets.main.kotlin.srcDirs
}

dependencies {
  compile "org.jetbrains.kotlin:kotlin-js-library:$kotlinVer"
}

Server build.gradle:

apply plugin: 'kotlin'

sourceCompatibility = 1.7
targetCompatibility = 1.7

dependencies {
  // Libs go there.
  compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVer"
  testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlinVer"
}

Shared project's build.gradle contains only apply plugin: 'kotlin' and, well, I'm not sure if using shared libraries is straightforward (or necessary, in many cases), so I guess it could even stay empty.

gradle client:build generates JavaScript file in server's static resources folder. gradle idea generates IntelliJ project with correctly linked dependencies and source folders (as long as the default names are used - src/main/kotlin, etc; see official Kotlin Gradle manual for custom source dirs).

like image 162
Czyzby Avatar answered Oct 14 '22 00:10

Czyzby


Building a Kotlin2JS project with dependencies from another Kotlin projects seems to require copying the sources in any way. One way to do it is adding the Kotlin project source dirs to the Kotlin2JS project source set dirs.

This can be done with the following lines in project scope:

sourceSets {  
    main.kotlin.srcDirs += project(':shared').sourceSets.main.kotlin.srcDirs
}

Please see the whole project structure:

root/
  shared/
    src/main/kotlin
    build.gradle
  client/
    src/main/kotlin
  server/
    src/main/kotlin
  build.gradle
  settings.gradle

In settings.gradle:

include 'shared', 'server', 'client'

And in build.gradle:

group 'com.example.multiproject'
version '1.0-SNAPSHOT'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.0-beta-4589"
    }
}

subprojects {
    repositories {
        mavenCentral()
    }
}

project(':client') {
    evaluationDependsOn(':shared')

    apply plugin: 'kotlin2js'
    compileKotlin2Js.kotlinOptions.sourceMap = true
    compileKotlin2Js.kotlinOptions.outputFile = "${projectDir}/web/js/app.js"
    compileKotlin2Js.kotlinOptions.suppressWarnings = true
    compileKotlin2Js.kotlinOptions.verbose = true

    sourceSets {
        main.kotlin.srcDirs += project(':shared').sourceSets.main.kotlin.srcDirs
    }
    dependencies {
        compile 'org.jetbrains.kotlin:kotlin-js-library:1.0.0-beta-4589'
    }
}

project(':server') {
    apply plugin: 'kotlin'
    dependencies {
        compile 'org.jetbrains.kotlin:kotlin-stdlib:1.0.0-beta-4589'
        compile project(':shared')
    }
}

Note that shared project should contain its own build.gradle.

like image 2
hotkey Avatar answered Oct 14 '22 00:10

hotkey