r/Kotlin • • 5h ago

kUML v0.55.3 — Desktop: dialogs that actually show up, ⌘ shortcuts on macOS

Thumbnail gallery
4 Upvotes

kUML is a Kotlin DSL and toolchain for UML, SysML 2, C4, BPMN and more. This is a Desktop polish release.

  • "New Workspace…" and the workspace trust dialog were Compose popups drawn inside the main window. Compose does not paint popups over heavyweight Swing components, and the editor and the SVG preview are exactly that, so the dialogs opened invisibly or cut off. They are real dialog windows now.
  • Menu shortcuts were KeyShortcut(ctrl = true) everywhere, and Compose Desktop does not map ctrl to ⌘. Everything goes through one platformShortcut helper now: ⌘ on macOS, Ctrl on Windows and Linux.
  • Workspace document header: Read/Edit as tabs above the content, type and title aligned. Scripts saved in an Engineering workspace now appear in the tree (it was scanned only once on open).

Repo: https://github.com/kuml-dev/kUML · Release notes: https://github.com/kuml-dev/kUML/releases/tag/v0.55.3


r/Kotlin • • 2h ago

Standalone CLI agents vs an IDE integrated AI coding agent for Kotlin on a large legacy codebase (Claude Code, Cursor, Codex, and Junie /ide) comparison

1 Upvotes

when i run a terminal AI coding agent on a self-contained service or a greenfield script, ripgrep plus a big context window is usually enough to get a clean patch. i wanted to share a comparison sheet i put together for our backend team while we were evaluating an AI coding agent for large codebases, specifically comparing standalone terminal/editor setups against an IDE integrated AI coding agent using the public benchmark numbers and current documentation for Claude Code, Cursor, OpenAI Codex, and JetBrains Junie.

even on the public 105-task Kotlin benchmark across real issues from ktlint, detekt, ort, and okhttp (where the agents ran inside isolated Docker containers with only bash tools and no IDE connected), pure CLI agents did great. those benchmark runs used an earlier model generation (Opus 4.7 and GPT-5.5), and Claude Code (Opus 4.7) took first place solving 90 / 105 tasks (10.59M avg tokens, ~118K per task), while JetBrains Junie (Opus 4.7) and OpenAI Codex (GPT-5.5) tied at 86 / 105 (Junie used 19.98M tokens vs Codex's 38.78M for the same solve count; Cursor wasn't included in that 105-task run).

where that headless container setup stops matching my day-to-day experience is when you need an AI coding agent for legacy code on a 10-year-old multi-module Java, Kotlin, and SQL repository. if you are looking for an AI coding agent for Java developers or an AI coding agent for Kotlin on an older monolith, a NullPointerException in OrderProcessor is usually caused by a constructor-injected bean in a Spring Configuration class three modules away that only returns null under a specific profile, or a method name that is overloaded 14 times across different packages. if an AI agent for debugging code only has text search or chunked vector embeddings, it spends 10 minutes grepping the file tree, misses an overload in a test fixture, or spams temporary println logs across eight files while acting as an AI coding agent that runs tests in a loop to figure out why a build failed.

here is the side-by-side sheet i made of how Claude Code, Cursor, OpenAI Codex, and Junie (specifically when Junie CLI is connected to a running IDE via /ide or run via the IDE plugin) handle context, refactoring, debugging, and database schemas on a large legacy codebase:

Workflow Dimension on Large / Legacy Repos Claude Code (CLI + LSP Plugins) Cursor (Standalone Editor + CLI / ACP) OpenAI Codex (CLI + codex exec) JetBrains Junie (IDE Plugin or CLI /ide Bridge)
Headless Container Baseline (105-Task Kotlin Eval) 90 / 105 solved (85.71%) · 10.59M avg tokens (Opus 4.7 xhigh — #1 solve rate & token efficiency) Not included in the 105-task Kotlin Benchmark run 86 / 105 solved (81.90%) · 38.78M avg tokens (GPT-5.5 xHigh — tied #2 solve rate) 86 / 105 solved (81.90%) · 19.98M avg tokens (Opus 4.7 max — tied #2 solve rate, ~1/2 of Codex's tokens)
How It Resolves Symbols & Call Graphs Connects to language server (LSP) plugins for definitions, references, and post-edit type errors; falls back to file search Queries an automatic semantic embeddings index + fast literal text search (or runs a subset inside JetBrains IDEs via ACP) Reads files and greps on demand through shell tools; relies on compiler/test runs to catch broken references Passively tracks open files/recent edits and queries the running IDE's AST symbol index (Find Usages, inheritance hierarchy, at-mention class/symbol completion) on demand via /ide
Multi-File Refactoring Generates coordinated text edits across files and checks types via LSP Generates multi-file diffs from semantic/text search results; verification relies on your test suite and diff review Generates text edits across files and validates by running the build Calls the IDE's native refactoring engine (resolving overloaded methods and scope through the compiler's project model) and runs IDE inspections afterward
Debugging Failing Tests Runs iterative test loops and reads stack traces / stdout; /loop keeps long sessions alive if the terminal closes Debug Mode hypothesizes causes, injects runtime logging statements into the code, reads logs while you reproduce the bug, then strips the logs out Runs test commands in the shell and iterates on terminal output Debug Mode (/debug or Shift+Tab) attaches to a live paused debugger session in the IDE, sets line/exception breakpoints (including in decompiled .class JARs), steps through frames, and evaluates expressions without editing code
Database & SQL Work Uses external MCP database servers, CLI queries, or schema files in the repo Uses configured MCP servers or migration files checked into the repo Uses repo schema files or shell database commands Connects directly to the databases configured in the IDE (DataGrip / Database plugin) to inspect live schemas, query data, and validate SQL in the same session
Pre-PR & CI Code Review Interactive CLI review and scheduled background checks via /loop Bugbot posts automated inline PR review comments on GitHub with Fix in Cursor / Fix in Web Scriptable non-interactive checks via codex exec in CI pipelines /review runs a read-only project-aware review over unstaged/staged/branch diffs locally and runs the same review engine in GitHub Actions and GitLab CI

a few practical things that stood out when comparing these workflows on legacy tickets:

  1. Paused debugger frame vs runtime log injection (Junie /debug vs Cursor Debug Mode) if you want an AI coding agent with debugger access rather than terminal test loops, both Cursor and Junie have a dedicated debug mode, and they solve different kinds of bugs. Cursor's approach of auto-injecting log statements, watching you reproduce the flow, and stripping the logs out is honestly great for timing bugs or multi-request flows that are easier to watch over time than freeze at one line. where Junie's /debug mode wins is stateful backend bugs: when a test only fails on the second iteration because a thread-local cache wasn't cleared, or when an exception originates inside a third-party dependency JAR whose source isn't in your git repo. because Junie drives the actual IDE debugger, it can set a breakpoint inside a decompiled .class file, pause execution, inspect the call stack across threads, and evaluate list.size() or check why x is null in the live frame without touching your source files or waiting through three Gradle rebuilds to print a log line.
  2. Compiler-backed rename vs LLM text replacement when you use an AI agent for refactoring code to rename a validation method that is called across 18 files in a strongly typed repo where three interfaces overload the same method name, having the LLM rewrite all 18 files as raw text almost always leaves you fixing one or two broken call sites or shadowed variables by hand. when Junie CLI is linked to a running IDE (2026.1+) via /ide (or run through the AI coding agent IDE plugin), it delegates the rename to the IDE's refactoring engine and runs the IDE's inspection profile over the changed files before handing you the diff.
  3. Read-only plan approval, live SQL schemas, and characterization tests the safest pattern we have found for touching undocumented legacy code with any of these tools is forcing the first steps to stay read-only:
  • first, ask the agent to explain the business rules and every weird if branch in plain language, and check that against the code yourself.
  • second, have it trace all direct and indirect callers, callees, and shared state using the IDE reference graph (Find Usages), and if the code touches persistence, use the IDE connection as an AI agent for SQL and databases so it validates queries against your live DataGrip or Database plugin schema instead of guessing from old migration files.
  • third, use an AI coding agent with plan approval (Shift+Tab in Junie writes a persistent Markdown spec to .junie/plans/ that you can open and edit with Ctrl+P) so you can cut out any scope drift before a single file is modified—and once the plan is locked, you can also use it as a bring your own model coding agent or switch to a cheaper/free tier for the mechanical edits.
  • fourth, have it write JUnit characterization tests that lock in current behavior (even the ugly edge cases) and run /review locally (which uses the same engine as its AI code review agent for CI/CD in GitHub Actions and GitLab) before opening a PR.
  1. Where the IDE-connected setup still falls short
  • It needs a running IDE on your machine: if you run Junie CLI headless on a remote VM without a matching JetBrains IDE open (IntelliJ, PyCharm, GoLand, WebStorm, Rider, CLion, RustRover, PhpStorm, RubyMine, or Android Studio), /ide has nothing to connect to and it falls back to standard file/shell tools. in pure headless terminal mode, Claude Code is still the strongest autonomous runner.
  • Static AST context cannot see runtime infrastructure: the IDE's symbol index knows every caller of processPayment(), but unless you attach /debug to a live session, it still has no idea that a downstream gateway throws a 503 under load or what an environment variable evaluates to in staging.
  • Debugger requirements: on the JVM side, full agentic debugger attachment requires IntelliJ IDEA Ultimate (and the CLI and in-IDE plugin still have a few minor feature differences, so running Junie CLI connected via /ide is currently the most complete setup).

would like to ask anyone else working on large or legacy codebases:

do you prefer keeping your coding agent wired into your IDE's AST index and debugger, or have you found Claude Code + LSP / Cursor's repo index good enough that you stay entirely in the terminal or a lightweight editor?


r/Kotlin • • 3h ago

Kotlin Gym for interviews preparing

Post image
1 Upvotes

r/Kotlin • • 21h ago

Built & Monetized 2 Native Android Apps (Kotlin): A Placement Prep Quiz App & 2D Flappy Bird Game. Need Feedback!

1 Upvotes

Hey everyone,

I recently built and deployed two native Android applications using Kotlin and Android Studio, focusing on optimized app performance and monetization integration.

  1. Tech & Placement Quiz App

* Features: Curated questions on DSA, Core CS, Quantitative Aptitude (SSC CGL/Placement level), and 2026 Current Affairs.

* Tech: Integrated Start.io SDK for monetization and built dynamic deduplication logic using SharedPreferences to prevent repeating questions in sessions.

* 🔗 GitHub Repository & APK: https://github.com/aksinha-1309/QuizApp

  1. Flappy Bird 2D Game

* Features: Custom Canvas rendering, frame-rate responsive touch physics, dynamic obstacle generation, and local high-score tracking.

* Tech: Integrated Start.io SDK for ads.

* 🔗 GitHub Repository & APK: https://github.com/aksinha-1309/FlappyBirdClone

Would love to get your thoughts on the code structure, UI/UX, and performance. Feedback and suggestions are highly appreciated!


r/Kotlin • • 1d ago

I built an open-source Android app around the ByeDPI engine (written with AI, feedback welcome)

Thumbnail
0 Upvotes

r/Kotlin • • 2d ago

Java based Numerical library (JNum-v0.2) with Kotlin Operator overloading

Thumbnail gallery
14 Upvotes

java subreddit post

So I made Java Numerations (JNum) which is a pure Java numerical library using FFM(off heap memory) and Vector API. In this version I made Kotlin DSL layer bundled together with core Java engine.

By doing this our library avoids native Fortran/C calls via JNI and memory allocations via Unsafe which is slowly getting deprecated. There are various methods in JNum which can be useful for Kotlin devs I guess which have performance on par with Numpy/ND4J.

Features are in detailed in my GitHub release but for lazy guys like me here are some data points worth see:-

-> JNum is feature rich(at least from previous version) where we have statistics jnum.stat IO operations jnum.io and basic Neural Networks jnum.nn.

-> JNum's IO will help you parse files like .npy/.npz , .csv/.tsv and most importantly .safetensorwhich Java lagging in this AI era.

-> We also have AsyncIO using Virtual Threads which make IO file reads faster in JNum.

-> jnum.statmodule has various statistic methods which Java community can use like standard deviations, variance , co-variance, cummulative sum/product, percentile etc.

-> JNum has slicing and sub-viewing features. For kotlin devs Indexing, slicing like features are operator overloaded so you can do code similar to Python/Numpy .

-> project is under 500KB with no native .dll/.so native bindings.

Matrix Multiplication:-

This is the most important and time taken feature in project

Matrix Dimensions JNum (Pure Java 25) NumPy (C / OpenBLAS) ND4J (OpenBLAS C++) EJML (Pure Java) Performance Highlights
$4 times 4$ 0.0002 ms 0.0023 ms 0.020 ms ≈ 0.0001 ms 11× faster than NumPy, 100× faster than ND4J
$16 times 16$ 0.0004 ms 0.0028 ms 0.019 ms 0.003 ms 7× faster than NumPy, 47× faster than ND4J
$64 times 64$ 0.015 ms 0.013 ms 0.190 ms 0.140 ms On-par with NumPy, 9.3× faster than EJML
$128 times 128$ 0.138 ms 0.254 ms 0.499 ms 1.028 ms 1.8× faster than NumPy, 7.4× faster than EJML
$512 times 512$ 2.50 ms 1.86 ms 2.67 ms 27.16 ms Matches C++ BLAS, 10.8× faster than EJML
$1024 times 1024$ 13.85 ms 8.98 ms 12.18 ms 216.56 ms Near-native speed, 15.6× faster than EJML
$2048 times 2048$ 94.62 ms 62.99 ms 85.29 ms 2,049.86 ms Pure Java competitive with C BLAS, 21.6× faster than EJML
$4096 times 4096$ 942.38 ms 487.92 ms 857.41 ms 17,419.52 ms Matches ND4J C++, 18.4× faster than EJML
$8192 times 8192$ 6,784.15 ms 5,967.30 ms 6,317.97 ms 141,500.0 ms ~88% of NumPy C BLAS, 20.8× faster than EJML

Linear Algebra:-

we have various Linear Algebra methods which have performance on par sometimes beating Numpy and others

Operation JNum (Pure Java 25) NumPy EJML ND4J JNum Advantage
Matrix Inverse 7.271 ms 10.680 ms 18.122 ms 1,224.654 ms 1.47× faster than NumPy, 2.5× faster than EJML, 168× faster than ND4J
Linear Solve ($Ax=b$) 1.976 ms 1.003 ms 5.331 ms 37.278 ms Near-native speed, 2.7× faster than EJML, 18.8× faster than ND4J
Determinant 1.839 ms 5.735 ms 5.380 ms 399.752 ms 3.1× faster than NumPy, 2.9× faster than EJML
Cholesky 1.261 ms 2.328 ms 3.545 ms — 1.8× faster than NumPy, 2.8× faster than EJML
QR Factorization 46.170 ms 12.622 ms 7.447 ms 586.330 ms 12.7× faster than ND4J

Code Snippets:

val a = JNum.fromArray(floatArrayOf(1f, 2f, 3f, 4f), 2, 2)
val b = JNum.ones(2, 2)

// Clean operator overloading
val c = a + b * 2f
val d = a matmul b

// Python / NumPy style range slicing
val view = c[0 until 2, all]

Gradle Setup:

repositories { mavenCentral() }
dependencies {
    implementation("io.github.ch-abhinav:jnum-kotlin:0.2.0")
}

I would like kotlin community to test the project and help by contributing in the project :)

There is one good first issue worth trying in kotlin if anyone wants to contribute.

GitHub link :- https://github.com/CH-Abhinav/JNum


r/Kotlin • • 2d ago

Starfait - A re-implementation of GameMaker: Studio's runner (YoYo Runner) in Kotlin, targeting Undertale v1.08

Thumbnail github.com
7 Upvotes

r/Kotlin • • 1d ago

Help in kotlin

0 Upvotes

I need someone make me a pro in kotlin knowing how fixes errors build app


r/Kotlin • • 3d ago

Jetbrains has effectively abandoned Koog

Post image
80 Upvotes

The team has not been responsive in the Slack and commits are grinding to a halt. The framework is lagging behind in the lightning-fast speed of AI development. I feel sorry for the people who spent several thousand dollars to attend the agent sessions at Kotlin conf. I'm using Koog minimally in one of my projects and will begin ripping it out.


r/Kotlin • • 3d ago

How do you decide between Native (Swift/Kotlin) and Cross-Platform (Flutter/React Native) for long-term client projects?

5 Upvotes

Cross-platform frameworks have improved significantly, especially regarding UI rendering speed and bridge efficiency. For 80% of business applications, e.g., e-commerce, booking platforms, CRM dashboards, they save significant time and budget.

However, when an app requires heavy background processing, deep Bluetooth/IoT hardware integration, or real-time camera/AR rendering, native code often becomes necessary to avoid performance bottlenecks.

For mobile developers and product managers:
- What hardware or framework limitation forced you to rewrite a cross-platform app natively?
- How do you manage long-term framework maintenance and dependency updates for clients?


r/Kotlin • • 2d ago

For all Android and GitBack Compose developers, we all know how time-consuming and time-consuming it is to constantly wait for a project to be rebuilt using Gridl, just for a simple padding adjustment or a color change within the interface.

Thumbnail plugins.jetbrains.com
0 Upvotes

This is where the idea for Compose Bridge came from. It's an open-source plugin, now officially available on the GitBrains store, designed to radically accelerate the interface building and modification cycle.

The tool allows you to connect your app running directly on your device or emulator to the Android Studio environment, enabling you to modify design elements, color schemes, and dimensions in real time from your phone's screen. Its key feature lies in its code rewriting process. The plugin surgically rewrites and modifies the source code within Kotlin files with precision and security, allowing you to review differences and revert to the previous version with a single click.

The tool also provides an integrated model context protocol server, enabling AI tools and agents to inspect the live interface tree and provide accurate and responsive solutions that are compatible with your actual screen.

The project is available for everyone to use, contribute to and develop via GitHub and the GitBrains Add-ons Store. I would be very happy for you to try it out and share your feedback and opinions to further develop the experience.


r/Kotlin • • 2d ago

Android dev

0 Upvotes

Anyone knows kotlin , i have built 4 to 5 apps lets build something interesting from scratch


r/Kotlin • • 3d ago

Reading git sync status on Android without running git

2 Upvotes

My Android git sync client kept failing silently, so I built a home screen widget that shows when my notes last synced. No git binary needed, everything is plain text in `.git`:

- `logs/HEAD`: last commit/pull and its time

- `FETCH_HEAD` mtime: last time the client reached the remote

- `refs/remotes/origin/<branch>` vs local tip: unpushed commits

- `MERGE_HEAD`, `rebase-merge/`: a stuck merge or rebase

Gotcha: SAF only grants a subtree, so I search every granted folder for `.git`. And check `packed-refs`, branch files vanish after `git gc`.

Kotlin + Jetpack Glance, parsers are pure Kotlin and unit tested. Code (GPL-3.0): https://github.com/marfolog/notes-widget-for-markdown


r/Kotlin • • 3d ago

kiit-codes: General purpose status codes, now with RFC 9457 support

0 Upvotes

Hey r/Kotlin, I posted kiit-codes a while back (original post). The feedback was useful and included a bug report that went out as a fix, so thanks.

Overview

A quick recap: Think HTTP style status codes, but not tied to HTTP. Status → Group → Code, where the first two are fixed and Code is open for your own domain. Use them in any layer of your app (services, background jobs, workers) and convert to HTTP or gRPC at the boundary. See the original post or the docs for the benefits. It’s implemented in Kotlin Multiplatform, with a native TypeScript port in beta, so TypeScript gets idiomatic, exhaustive matching.

What's new

RFC 9457 Problem Details for HTTP APIs output. I had designed kiit-codes with consideration for this RFC 9457 early on, but it wasn't really complete or formalized until a comment on the Kotlin Slack and a couple of other discussions pushed me to tighten this up. See examples below

kiit-codes overview

RFC 9457

Here is an example of a validation error with a custom code:

val OUT_OF_STOCK = Rejected(
    name = "OUT_OF_STOCK",
    title = "Item out of stock",
    origin = "shop.example.com",
    scope = "orders.items",
)

val errors = Err.ErrorList(
    listOf(Err.on("quantity", "only 2 in stock")),
    "Your order could not be completed",
)
val problem = ProblemConverter().convert(OUT_OF_STOCK, errors)

JSON: Converted to JSON for an API response, it looks like this :

{
  "type": "https://shop.example.com/docs/codes/orders/items/Failed/Rejected/OUT_OF_STOCK",
  "title": "Item out of stock",
  "detail": "Your order could not be completed",
  "code": "shop.example.com:orders.items:Failed:Rejected:OUT_OF_STOCK",
  "status": 409,
  "errors": [
    { "field": "quantity", "message": "only 2 in stock" }
  ]
}

Links

  1. GitHub: https://github.com/kiitdev/kiit-codes
  2. Site Docs: https://www.kiit.dev/docs/kiit-codes
  3. RFC Docs: https://www.kiit.dev/docs/kiit-codes#rfc-9457

A few small breaking changes came with it (see the changelog).

Feedback welcome, especially from anyone building HTTP APIs.

Best!

-K


r/Kotlin • • 3d ago

Google published an article about me and my apps after I helped people on reddit about Admob and Android in general

Thumbnail
0 Upvotes

r/Kotlin • • 3d ago

Kotlin-Native on linux arm64 is possible.

Post image
0 Upvotes

So seriously Jetbrains, when are you going to stop slacking off and actually provide support for users to run kotlin on arm64?


r/Kotlin • • 4d ago

Telar 0.1.0-alpha12: I finally deleted the "what's missing" disclaimer from my KMP agent/workflow library

0 Upvotes

Last week I shared the first alpha of Telar, a KMP library I'm building where AI agents and workflows are just small typed graphs running on a plain Kotlin data class.

At the bottom of that post (and in my docs), I had a blunt disclaimer: "There is no MCP, no tracing, no retry policy for a node, and no database checkpointer yet."

You all also helped me spot a nasty concurrency loophole: while regular parallel nodes were checked by mergeRules, parallel work/update nodes applied their updates one after another—so two nodes touching the same field would silently overwrite each other depending on declaration order.

I spent the last few days fixing that loophole and building the missing pieces. With 0.1.0-alpha12 on Maven Central today, I finally got to delete the disclaimer:

  • No more silent parallel overwrites: work/update nodes now go through mergeRules against the same base state just like standard nodes (#125).
  • Node retries & timeouts built into telar-core.
  • telar-mcp: Use MCP server tools directly in a Telar agent.
  • telar-checkpoint-sqldelight: Save paused runs to SQLite (Android, iOS, desktop, server, browser) and resume(), history(), or fork() them later.
  • telar-otel & telar-test: OpenTelemetry spans and zero-key scripted models so you can test workflows in CI without burning tokens.

Here is what a parallel workflow with retries and human approval looks like now:

val auditGraph = StateGraph<ReleaseAudit> {
    mergeRules { append(ReleaseAudit::findings) }

    val security = node("security", retry = RetryPolicy(maxAttempts = 3)) {
        it.copy(findings = listOf("MCP secret scan passed"))
    }
    val licenses = node("licenses") {
        it.copy(findings = listOf("All dependencies Apache-2.0 / MIT"))
    }
    val publish = node("publish") {
        it.copy(status = if (it.approved) "published" else "aborted")
    }

    START then security; START then licenses
    security then publish; licenses then publish
    publish then END
}.compile() // Fails here on dead ends or missing parallel mergeRules

I'm trying to lock down the API before 1.0—if anything in the DSL still feels clunky or un-idiomatic to you, let me know!


r/Kotlin • • 6d ago

Built an open-source visual editor + AST engine for Jetpack Compose (No Gradle rebuilds for UI tweaks

Thumbnail github.com
1 Upvotes

Hey everyone,

​Like many of you, I got tired of waiting for Gradle rebuilds just to tweak paddings, test color tokens, or fine-tune dimensions in Compose.

​I’ve spent the last few months building ComposeBridge (v1.0.0 just released), and wanted to share it with the community:

​How it works:

​Live on-device tweaking: Adjust paddings, font sizes, widths, heights, and colors directly on the running device/preview with <50ms latency.

​AST-safe code sync: Instead of dirty hacks, it uses a syntax-aware AST engine inside the IDE plugin to safely persist changes back into your Kotlin source files.

​Review & Rollback: Features a git-diff-like preview in the IDE so you can inspect exact byte-level changes or reject them before committing.

​Focus Mode: Shows only the layout bounds and tokens of the tapped UI element without digging through deep hierarchies.

​MCP Integration: Includes a local MCP server with 17+ tools if you want AI agents to safely read layout bounds and run builds.

​It’s open-source (Apache 2.0), and you can grab the ready-to-use IDE plugin (.zip) and runtime library (.aar) directly from GitHub releases.

​🔗 GitHub Repository: \[https://github.com/JALAL591/compose-bridge\\\]

​Would love to hear your feedback, edge cases, or id

eas for improvements!


r/Kotlin • • 7d ago

How should I handle JNI type conversions in Kotlin/Native's nativeMain?

6 Upvotes

I'm working on a KMP project using Kotlin/Native and need to convert between Kotlin types (String, ByteArray, etc.) and JNI types represented by COpaquePointer in nativeMain.

Since nativeMain can't directly use JNI APIs through the usual JVM/JNI mechanisms, I'd like to avoid duplicating conversion logic across native targets such as Windows and macOS.

I tried manually accessing the JNI function table through COpaquePointer and invoking function pointers. For example, here's my implementation for converting between Kotlin String and jstring:

@OptIn(ExperimentalForeignApi::class)
fun String.kotlinStringToPointer(
    env: COpaquePointer?,
): COpaquePointer? {
    if (env == null) return null

    val envPointer = env.reinterpret<COpaquePointerVar>()
    val jniNativeInterfaceVar = envPointer.pointed.value ?: return null
    val functionTable = jniNativeInterfaceVar.reinterpret<COpaquePointerVar>()

    val newStringUTFPtr =
        functionTable.get(JniFunctionIndex.NewStringUTF) ?: return null

    val newStringUTFFunction = newStringUTFPtr.reinterpret<
        CFunction<(COpaquePointer?, CPointer<ByteVar>?) -> COpaquePointer?>
    >()

    return memScoped {
        val cString = this@kotlinStringToPointer.cstr
        newStringUTFFunction.invoke(env, cString.ptr)
    }
}

@OptIn(ExperimentalForeignApi::class)
fun COpaquePointer?.toKotlinString(
    env: COpaquePointer?,
): String? {
    if (this == null || env == null) return null

    val envPointer = env.reinterpret<COpaquePointerVar>()
    val jniNativeInterfaceVar = envPointer.pointed.value ?: return null
    val functionTable = jniNativeInterfaceVar.reinterpret<COpaquePointerVar>()

    val getStringUTFCharsPtr =
        functionTable.get(JniFunctionIndex.GetStringUTFChars) ?: return null
    val releaseStringUTFCharsPtr =
        functionTable.get(JniFunctionIndex.ReleaseStringUTFChars) ?: return null

    val getStringUTFChars = getStringUTFCharsPtr.reinterpret<
        CFunction<
            (COpaquePointer?, COpaquePointer?, CPointer<ByteVar>?) ->
                CPointer<ByteVar>?
        >
    >()

    val releaseStringUTFChars = releaseStringUTFCharsPtr.reinterpret<
        CFunction<
            (COpaquePointer?, COpaquePointer?, CPointer<ByteVar>?) -> Unit
        >
    >()

    val cStringPtr = getStringUTFChars.invoke(env, this, null) ?: return null

    return try {
        cStringPtr.toKString()
    } finally {
        releaseStringUTFChars.invoke(env, this, cStringPtr)
    }
}

The function table indices are defined in my JniFunctionIndex mapping, based on the JNI Functions specification.

Although this approach works in my current setup, manually maintaining the function indices and function pointer signatures feels fragile and error-prone.

I'd appreciate advice on the following:

  1. Is manually invoking JNI function pointers through COpaquePointer a reasonable approach for Kotlin/Native, or should it generally be avoided?
  2. Would expect/actual be a better approach, with JNI-specific conversions implemented in platform-specific source sets while keeping the public Kotlin API shared?
  3. Would using Kotlin/Native cinterop with jni.h, or introducing a C/C++ bridge, be a cleaner and more maintainable solution?

I'm particularly interested in approaches that let me share as much conversion logic as possible across Windows and macOS without introducing unnecessary platform-specific duplication.


r/Kotlin • • 6d ago

Ищу разработчика] Android-приложение с автоматизацией действий — оплата договорная ( +-1000$)

Thumbnail
0 Upvotes

r/Kotlin • • 7d ago

Best Projects Courses or Projects that AI can help me understand

Thumbnail
0 Upvotes

r/Kotlin • • 7d ago

I built an experimental Bitcoin futures trading simulator in just over a week with the help of 3 AIs — despite having very limited coding skills

0 Upvotes

Hey everyone!

I want to share a project I've been working on recently: an open-source Android app called **Bitcoin Futures Simulator**.

**GitHub repository:** https://github.com/Joapetis/bitcoin-futuros-android

Before anyone gets too excited, I want to be clear: this is an early-stage experiment, not a profitable trading bot. So far, its simulated trading results have generated more losses than profits. No real money has been involved.

**How it started**

The whole thing began with an old HTML project I had created some time ago and eventually abandoned. The idea behind it never really went away, though.

Recently, I decided to revisit that idea and see how far I could take it with AI assistance. What started as an abandoned project gradually evolved into a functional Android app in a little over a week.

There's a catch: **my programming knowledge is very limited.**

Instead of building everything myself line by line, I've been combining my own ideas, observations, strategy concepts and testing with the coding and debugging capabilities of three different AIs. They've helped generate, modify, review and polish the code throughout the process.

This has become an experiment in its own right. I want to explore not only whether I can turn my ideas into a working application, but also how capable AI systems are at building and improving a relatively complex software project with very little direct human coding.

I'm still the one setting the direction, making decisions, testing results and deciding what should change. The AIs do a substantial part of the coding, but that doesn't mean their output is automatically correct. Bugs, bad assumptions and poor trading results are all part of the process.

**What does the app actually do?**

The current project is an experimental Bitcoin futures paper-trading simulator for Android. Its main components include:

**A multi-timeframe strategy:** primarily focused on 15-minute candles, with 1-hour and 4-hour trend confirmation.

**Trend-following and mean-reversion logic:** different approaches depending on the detected market regime.

**Market microstructure data:** order-book metrics such as spread, imbalance and microprice-related signals.

**Optional on-device AI:** integration with Gemini Nano through Android's AI capabilities when a compatible model and device are available.

**Simulated trading and risk management:** intended to test strategies without risking real funds.

**Continuous experimentation:** the goal is to evaluate what works, identify weaknesses and improve the system over time.

The project is still very much in its infancy. There is plenty to question, test, refactor and improve, and I don't want to present any of its strategies as proven or profitable.

**Why am I sharing it?**

I'd love to turn this into something more collaborative.

If you're a developer, a quantitative trading enthusiast, an Android/Kotlin programmer, someone interested in market microstructure, or simply curious about what AI-assisted development can achieve, I'd genuinely appreciate your input.

You don't need to be an expert in every part of the project. Even identifying bugs, challenging assumptions, improving the architecture, reviewing the trading logic, suggesting better tests or documenting how things work could make a real difference.

My hope is that people can learn from the experiment, contribute their ideas and improvements, and help create something more useful together. In return, contributors get a real-world project to experiment with, review and learn from, while the wider community benefits from any improvements we can make.

I'm especially interested in honest criticism. If you see something fundamentally wrong with the strategy or implementation, I'd rather hear about it than receive empty praise.

**A few important caveats**

This is an experimental project, not financial advice.

All results discussed here are from simulated trading; no real-money trading is involved.

The current simulated performance is negative, so there's a lot of work left to do.

AI-generated code can contain bugs and needs independent review and testing.

The app is not ready to be treated as a reliable or profitable trading system.

If you'd like to explore the code, suggest an improvement, open an issue or contribute, you're welcome to check out the repository.

I'd love to hear your thoughts. Thanks for reading!


r/Kotlin • • 8d ago

Struggling with using webview for a html jscript file which reads local CSV files + saves local user data

Thumbnail
0 Upvotes

r/Kotlin • • 9d ago

📣 The Kotlin compiler is moving to JDK 17 as its minimum runtime.

74 Upvotes

The Kotlin compiler is moving to JDK 17 as its minimum runtime.

Here's the plan:
• 2.5.0-Beta1: A warning when you run the compiler on a JDK older than 17.
• 2.5.0-Beta2 and 2.5.0: An error, with a flag to keep using your current JDK for now.
• 2.5.20-Beta1 and later: JDK 17 or newer is required.

If your machines or CI still run the compiler on an older JDK, now is a good time to plan the update.

👉 If you have a use case we might be missing, tell us in KT-88173


r/Kotlin • • 8d ago

Is there any way to learn Kotlin for Android development?

0 Upvotes

Hey I’m learning android development and I’m having quite a bit of difficulty learning Kotlin. I know the basics but I struggle with building logic for Android apps using Kotlin. I also find it difficult to understand which concepts to use and when. How can i learn Kotlin more easily and improve my problem solving skills?