Client library for communicating with the Kotlin compilation daemon, enabling remote compilation services and incremental compilation workflows.
—
Remote input/output stream handling for daemon communication, enabling data transfer between client and daemon processes. These servers provide RMI-based stream abstractions for sending and receiving data across process boundaries.
Server implementation for remote input stream handling, allowing the daemon to read data from client-side input streams.
/**
* Remote input stream server for daemon communication
* @param in The input stream to wrap and expose remotely
* @param port RMI port for service communication (default: any free port)
*/
class RemoteInputStreamServer(
val `in`: InputStream,
port: Int = SOCKET_ANY_FREE_PORT
) : RemoteInputStream, UnicastRemoteObject(
port,
LoopbackNetworkInterface.clientLoopbackSocketFactory,
LoopbackNetworkInterface.serverLoopbackSocketFactory
)/**
* Close the underlying input stream
*/
override fun close()
/**
* Read up to specified number of bytes from the stream
* @param length Maximum number of bytes to read
* @return Byte array containing read data (may be shorter than requested)
*/
override fun read(length: Int): ByteArray
/**
* Read a single byte from the stream
* @return The byte value as an integer, or -1 if end of stream
*/
override fun read(): IntUsage Example:
import org.jetbrains.kotlin.daemon.client.RemoteInputStreamServer
import java.io.ByteArrayInputStream
import java.io.FileInputStream
// Create from file
val fileStream = FileInputStream("input.txt")
val remoteFileStream = RemoteInputStreamServer(fileStream)
// Create from byte array
val data = "Hello, Kotlin Daemon!".toByteArray()
val byteArrayStream = ByteArrayInputStream(data)
val remoteByteStream = RemoteInputStreamServer(byteArrayStream, port = 0)
// Use in daemon communication
try {
// Read single bytes
var byte = remoteByteStream.read()
while (byte != -1) {
print(byte.toChar())
byte = remoteByteStream.read()
}
// Read chunks
val buffer = remoteByteStream.read(1024)
println("Read ${buffer.size} bytes: ${String(buffer)}")
} finally {
remoteByteStream.close()
}Server implementation for remote output stream handling, allowing the daemon to write data to client-side output streams.
/**
* Remote output stream server for daemon communication
* @param out The output stream to wrap and expose remotely
* @param port RMI port for service communication (default: any free port)
*/
class RemoteOutputStreamServer(
val out: OutputStream,
port: Int = SOCKET_ANY_FREE_PORT
) : RemoteOutputStream, UnicastRemoteObject(
port,
LoopbackNetworkInterface.clientLoopbackSocketFactory,
LoopbackNetworkInterface.serverLoopbackSocketFactory
)/**
* Close the underlying output stream
*/
override fun close()
/**
* Write byte array data to the stream
* @param data Byte array to write
* @param offset Starting offset in the data array
* @param length Number of bytes to write
*/
override fun write(data: ByteArray, offset: Int, length: Int)
/**
* Write a single byte to the stream
* @param dataByte The byte value to write
*/
override fun write(dataByte: Int)Usage Example:
import org.jetbrains.kotlin.daemon.client.RemoteOutputStreamServer
import java.io.ByteArrayOutputStream
import java.io.FileOutputStream
// Create from file
val fileStream = FileOutputStream("output.txt")
val remoteFileStream = RemoteOutputStreamServer(fileStream)
// Create from byte array
val byteArrayStream = ByteArrayOutputStream()
val remoteByteStream = RemoteOutputStreamServer(byteArrayStream, port = 0)
try {
// Write single bytes
val message = "Hello, Kotlin!"
message.forEach { char ->
remoteByteStream.write(char.code)
}
// Write byte arrays
val data = "\nSecond line".toByteArray()
remoteByteStream.write(data, 0, data.size)
// Get written data (for ByteArrayOutputStream)
val writtenData = byteArrayStream.toByteArray()
println("Written: ${String(writtenData)}")
} finally {
remoteByteStream.close()
}import org.jetbrains.kotlin.daemon.client.*
import java.io.*
class FileTransferService {
fun transferFile(sourceFile: File, targetFile: File) {
val inputStream = FileInputStream(sourceFile)
val outputStream = FileOutputStream(targetFile)
val remoteInput = RemoteInputStreamServer(inputStream)
val remoteOutput = RemoteOutputStreamServer(outputStream)
try {
// Transfer data in chunks
val buffer = ByteArray(8192)
var totalBytes = 0
while (true) {
val chunk = remoteInput.read(buffer.size)
if (chunk.isEmpty()) break
remoteOutput.write(chunk, 0, chunk.size)
totalBytes += chunk.size
}
println("Transferred $totalBytes bytes from ${sourceFile.name} to ${targetFile.name}")
} finally {
remoteInput.close()
remoteOutput.close()
}
}
}
// Usage
val transferService = FileTransferService()
transferService.transferFile(File("source.txt"), File("target.txt"))import org.jetbrains.kotlin.daemon.client.*
import java.io.*
class StreamCommunication {
private val inputBuffer = ByteArrayInputStream("Command data".toByteArray())
private val outputBuffer = ByteArrayOutputStream()
fun setupCommunication(): Pair<RemoteInputStreamServer, RemoteOutputStreamServer> {
val remoteInput = RemoteInputStreamServer(inputBuffer)
val remoteOutput = RemoteOutputStreamServer(outputBuffer)
return remoteInput to remoteOutput
}
fun sendCommand(command: String) {
val data = command.toByteArray()
val inputStream = ByteArrayInputStream(data)
val remoteInput = RemoteInputStreamServer(inputStream)
try {
// Simulate reading command
val readData = remoteInput.read(data.size)
println("Command sent: ${String(readData)}")
} finally {
remoteInput.close()
}
}
fun receiveResponse(): String {
val response = outputBuffer.toByteArray()
return String(response)
}
}
val communication = StreamCommunication()
val (input, output) = communication.setupCommunication()
// Send data through streams
communication.sendCommand("compile MyClass.kt")
val response = communication.receiveResponse()
println("Response: $response")class BufferedStreamServer {
fun createBufferedInput(data: ByteArray, bufferSize: Int = 1024): RemoteInputStreamServer {
val bufferedStream = BufferedInputStream(
ByteArrayInputStream(data),
bufferSize
)
return RemoteInputStreamServer(bufferedStream)
}
fun createBufferedOutput(output: OutputStream, bufferSize: Int = 1024): RemoteOutputStreamServer {
val bufferedStream = BufferedOutputStream(output, bufferSize)
return RemoteOutputStreamServer(bufferedStream)
}
fun processData(inputData: ByteArray): ByteArray {
val outputStream = ByteArrayOutputStream()
val remoteInput = createBufferedInput(inputData)
val remoteOutput = createBufferedOutput(outputStream)
try {
// Process data in chunks
while (true) {
val chunk = remoteInput.read(512)
if (chunk.isEmpty()) break
// Transform data (example: uppercase)
val transformedChunk = String(chunk).uppercase().toByteArray()
remoteOutput.write(transformedChunk, 0, transformedChunk.size)
}
return outputStream.toByteArray()
} finally {
remoteInput.close()
remoteOutput.close()
}
}
}
val server = BufferedStreamServer()
val input = "hello, world!".toByteArray()
val output = server.processData(input)
println("Processed: ${String(output)}") // "HELLO, WORLD!"class StreamResourceManager {
private val activeStreams = mutableListOf<AutoCloseable>()
fun createManagedInputStream(inputStream: InputStream): RemoteInputStreamServer {
val remoteStream = RemoteInputStreamServer(inputStream)
activeStreams.add(remoteStream)
return remoteStream
}
fun createManagedOutputStream(outputStream: OutputStream): RemoteOutputStreamServer {
val remoteStream = RemoteOutputStreamServer(outputStream)
activeStreams.add(remoteStream)
return remoteStream
}
fun closeAllStreams() {
activeStreams.forEach { stream ->
try {
stream.close()
} catch (e: Exception) {
println("Error closing stream: ${e.message}")
}
}
activeStreams.clear()
}
fun withManagedStreams(block: (StreamResourceManager) -> Unit) {
try {
block(this)
} finally {
closeAllStreams()
}
}
}
// Usage with automatic resource management
StreamResourceManager().withManagedStreams { manager ->
val input = manager.createManagedInputStream(
FileInputStream("input.txt")
)
val output = manager.createManagedOutputStream(
FileOutputStream("output.txt")
)
// Use streams...
val data = input.read(1024)
output.write(data, 0, data.size)
// Streams are automatically closed
}Install with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-kotlin--kotlin-daemon-client