Skip to content

JetBrains/kotlin-compiler-server

Repository files navigation

Kotlin compiler server

official JetBrains project 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

With Docker

To build the app inside a Docker container, run the following command from the project directory:

$ ./docker-image-build.sh

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(args: Array<String>) {\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. 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)