Skip to content

xebia-functional/kotlin-compiler-server

Β 
Β 

Repository files navigation

Kotlin compiler server

Build Status Java CI TC status Kotlin GitHub license

A REST server for compiling and executing Kotlin code. The server provides the API for Kotlin Playground library.

How to start 🏁

Simple Spring Boot application

Download Kotlin dependencies and build an executor before starting the server:

$ ./gradlew build -x test 

Start the Spring Boot project. The main class: com.compiler.server.CompilerApplication

From Docker Hub

View images on Docker Hub.

docker pull prendota/kotlin-compiler-server

From Amazon lambda

Based on aws-serverless-container.

$ ./gradlew buildLambda

Getting .zip file from build/distributions.

Lambda handler: com.compiler.server.lambdas.StreamLambdaHandler::handleRequest.

Publish your Lambda function: you can follow the instructions in AWS Lambda's documentation on how to package your function for deployment.

From Kotless

Add Kotless and remove aws-serverless-container =)

API Documentation πŸ“ƒ

Execute Kotlin code on JVM

curl -X POST \
  http://localhost:8080/api/compiler/run \
  -H 'Content-Type: application/json' \
  -d '{
    "args": "1 2 3",
    "files": [
        {
            "name": "File.kt",
            "text": "fun main() {\n    println(\"123\")\n}"
        }
    ]
}'

Translate Kotlin code to JavaScript code

curl -X POST \
    http://localhost:8080/api/compiler/translate \
    -H 'Content-Type: application/json' \
    -d '{
      "args": "1 2 3",
      "files": [
        {
          "name": "File.kt",
          "text": "fun main() {\n    println(args[0])\n }"
        }
      ]
}'

Run Kotlin tests

curl -X POST \
  http://localhost:8080/api/compiler/test \
  -H 'Content-Type: application/json' \
  -d '{
  "files": [
    {
      "name": "File.kt",
      "text": "fun start(): String = \"OK\""
    },
    {
      "name": "test0.kt",
      "text": "import org.junit.Assert\nimport org.junit.Test\n\nclass TestStart {\n    @Test fun testOk() {\n        Assert.assertEquals(\"OK\", start())\n    }\n}"
    },
    {
      "name": "test1.kt",
      "text": "package koans.util\n\nfun String.toMessage() = \"The function '\''$this'\'' is implemented incorrectly\"\n\nfun String.toMessageInEquals() = toMessage().inEquals()\n\nfun String.inEquals() = this"
    }
  ]
}'

Get code completions for a specified place in code

curl -X POST \
  'http://localhost:8080/api/compiler/complete?line=2&ch=15' \
  -H 'Content-Type: application/json' \
  -d '{
  "files": [
    {
      "name": "File.kt",
      "text": "fun main() {\n    val sinusoid = \"sinusoid\"\n    val s = sin\n}"
    }
  ]
}'

Get code analysis results

curl -X POST \
  http://localhost:8080/api/compiler/highlight \
  -H 'Content-Type: application/json' \
  -d '{
  "files": [
    {
      "name": "File.kt",
      "text": "fun main() {\n    println(\"Hello, world!!!\")ass\n    val random = Random\n}"
    }
  ]
}'

Get the current Kotlin version

curl -X GET http://localhost:8080/versions

The server also supports an API for the Kotlin Playground library.

How to add your dependencies to kotlin compiler πŸ“š

Just put whatever you need as dependencies to build.gradle.kts via a task called kotlinDependency:

 kotlinDependency "your dependency"

NOTE: If the library you're adding uses reflection, accesses the file system, or performs any other type of security-sensitive operations, don't forget to configure the executors.policy . Click here for more information about Java Security Policy.

How to set Java Security Policy in executors.policy

If you want to configure a custom dependency, use the marker @LIB_DIR@:

grant codeBase "file:%%LIB_DIR%%/junit-4.12.jar"{
  permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
  permission java.lang.RuntimePermission "setIO";
  permission java.io.FilePermission "<<ALL FILES>>", "read";
  permission java.lang.RuntimePermission "accessDeclaredMembers";
};

CORS configuration

Set the environment variables

ENV Default value
ACCESS_CONTROL_ALLOW_ORIGIN_VALUE *
ACCESS_CONTROL_ALLOW_HEADER_VALUE *

Configure logging

We use prod spring active profile to stream logs as JSON format. You can set the spring profile by supplying -Dspring.profiles.active=prod or set env variable SPRING_PROFILES_ACTIVE to prod value.

Unsuccessful execution logs

In case of an unsuccessful execution in the standard output will be the event with INFO level:

{
  "date_time": "31/Aug/2021:11:49:45 +03:00",
  "@version": "1",
  "message": "Code execution is complete.",
  "logger_name": "com.compiler.server.service.KotlinProjectExecutor",
  "thread_name": "http-nio-8080-exec-1",
  "level": "INFO",
  "level_value": 20000,
  "hasErrors": true,
  "confType": "JAVA",
  "kotlinVersion": "$koltinVersion"
}

Kotlin release guide πŸš€

  1. Update the kotlin version in gradle.properties
  2. Update the kotlin version in build.gradle.kts
  3. Update the kotlin version in Dockerfile
  4. Make sure everything is going well via the task:
$ ./gradlew build
  1. Save branch with the name of the kotlin version. Pattern: /^[0-9.]+$/ (optional)
  2. Bump version on GitHub releases (optional)

About

Server for executing kotlin code

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Kotlin 99.7%
  • Dockerfile 0.3%