Posts Tagged ‘JetBrains’
[KotlinConf2024] Why We Can’t Have Nice Things in Kotlin: Library Challenges
Vsevolod Tolstopyatov, a Kotlin libraries team member at JetBrains, entertained KotlinConf2024 with a witty exploration of why Kotlin’s standard libraries evolve slowly. From Turkish locale bugs breaking compilers to time zone quirks skipping entire days, Vsevolod revealed the hidden complexities of API design. Through anecdotes like Twitter polls on naming and a friend’s missed alarm, he highlighted how human language, historical quirks, and real-world constraints challenge library development, urging developers to appreciate the slow, thoughtful process behind robust APIs.
Human Language: The Turkish I Debacle
Kotlin’s string functions, like toUpperCase and toLowerCase, rely on system locales, leading to unexpected issues. Vsevolod recounted a bug where code compiled in Turkey failed due to the Turkish dotted and dotless I. Uppercasing an English lowercase i in Turkish yields a dotted uppercase İ, breaking method names like intArray. This forced the deprecation of locale-dependent functions, replaced with uppercase and lowercase using a root locale. The lesson: human languages’ diversity demands careful API design to avoid breaking code across cultures.
Naming Woes: The Capitalize Conundrum
Naming APIs is deceptively hard. Vsevolod shared how the deprecated capitalize function lacked a clear replacement because “capitalize” means different things to different developers. Twitter polls revealed no consensus, and other languages like Python and Ruby use capitalize inconsistently. With all good names taken or ambiguous, Kotlin’s team struggles to craft intuitive APIs without confusing users. This naming challenge slows library updates, as new functions risk misinterpretation or overlap with existing conventions.
Time Zones: Samoa’s Missing Day
Time zone complexities plague datetime APIs. Vsevolod described a case in Samoa, which skipped December 30, 2011, to align with Australia’s time zone, jumping from UTC-10 to UTC+14. A simple date addition (e.g., December 29 + 2 days) yields inconsistent hours due to the missing day. Adding time zone parameters fixes this but complicates APIs, especially on devices crossing time zone boundaries, like aircraft. These real-world quirks force Kotlin to balance simplicity with correctness, often at the cost of elegance.
Daylight Saving Time: Bug Hunting’s Legacy
Daylight saving time (DST) adds further headaches. Vsevolod traced DST to George Hudson, a 19th-century entomologist who proposed time shifts to hunt bugs in New Zealand. During DST transitions, times like 2:30 AM may not exist (spring forward) or occur twice (fall back), breaking datetime calculations. An anecdote about Vsevolod’s friend Vlad, whose smart home set a 9:30 AM alarm instead of 8:30 AM during a DST shift, underscored the need for explicit API parameters to handle ambiguous times, sacrificing simplicity.
API Design: Slow and Steady Wins
Vsevolod concluded that Kotlin’s libraries evolve slowly to avoid mistakes. Rushed APIs lead to bugs, like Vlad’s missed alarm, requiring years of maintenance. Thoughtful design, considering edge cases like locales, time zones, and DST, ensures reliability but delays releases. Twitter polls and community feedback help, but the real world’s complexity—political, historical, and cultural—demands patience. By prioritizing robustness, Kotlin’s team crafts APIs that won’t “get anyone fired,” even if it means fewer “nice things” per release.
Links:
[KotlinConf2024] Exploring Exposed: Kotlin’s Database Solution
At KotlinConf2024, Chantal Loncle, a JetBrains Exposed team member, introduced Exposed, an open-source Kotlin library simplifying database access. Since its 2016 debut as a JetBrains internal tool, Exposed has grown into a versatile abstraction layer, supporting multiple databases with type-safe SQL and minimal boilerplate. Chantal guided attendees through configuring connections, defining schemas, manipulating data via DSL, DAO, and plain SQL, and extending functionality with custom features, showcasing Exposed’s flexibility for Kotlin developers.
Why Exposed? Solving Database Pain Points
Exposed addresses common database access challenges, offering a balance between control and abstraction. Chantal explained that developers often need to map Kotlin objects to database records without complex SQL or frameworks requiring annotations. Exposed supports this by providing type-safe interactions, reducing boilerplate, and abstracting database differences. Its cuttlefish mascot reflects its adaptability, enabling database-agnostic apps. Whether needing high-level abstraction or low-level SQL control, Exposed’s consistent API caters to diverse needs, as seen in its growing popularity, ranking sixth among JetBrains’ GitHub repositories.
Setting Up Database Connections
Connecting to a database with Exposed is straightforward yet flexible. Chantal demonstrated the databaseConnect function, which accepts a connection URL or data source and relies on JDBC drivers. This function doesn’t establish a connection immediately but configures details for later use. Developers can set parameters via a config builder for specific database needs or create multiple connections by storing instances. This approach ensures Exposed handles underlying database variations, allowing developers to focus on application logic rather than connection management.
Transactions: The Heart of Data Operations
Transactions are central to Exposed’s data manipulation. Chantal illustrated how the transaction function wraps operations like schema creation or data inserts, accepting a database instance or defaulting to a registered one. For multiple connections, developers can set a default database or override settings per transaction. Transactions ensure atomicity, committing or rolling back changes, and Exposed’s transaction manager simplifies resource handling. This design supports both simple and complex workflows, with utility functions like SchemaUtils.create generating SQL tailored to the target database.
Defining Schemas with Table Objects
Schema definition in Exposed revolves around the Table class, which maps Kotlin data classes to database tables. Chantal used a docking bay app example, tracking ships and planets. For a Planets table, developers register columns (e.g., auto-incrementing Long for IDs, String for names) and constraints like primary keys. For a Ships table, a foreign key references Planets, establishing a one-to-many relationship. Exposed’s SchemaUtils handles table creation or updates, checking existing schemas to generate necessary SQL, ensuring compatibility across databases like PostgreSQL or MySQL.
Data Manipulation: DSL and DAO Approaches
Exposed offers two data manipulation approaches: domain-specific language (DSL) and data access object (DAO). Chantal showcased DSL’s SQL-like syntax, where extension functions like insert or selectAll on table objects build type-safe queries. For example, inserting a ship involves assigning column values, with autogenerated keys accessible post-insertion. The DAO approach, less verbose, maps records to entity classes, abstracting SQL further. Developers call new on entities instead of insert, manipulating fields directly. Both methods, switchable via configuration, support complex queries, joins, and updates, catering to different preferences.
Plain SQL and Extensibility
For developers needing direct SQL control, Exposed’s exec function runs raw SQL strings, as Chantal demonstrated with a stored function to calculate maximum planet distances. Beyond core functionality, Exposed shines in extensibility. Statement interceptors allow custom logic, like logging deletions, at specific lifecycle points. Entity hooks in DAO mode achieve similar customization. Custom column types, such as a PostgreSQL IntRange for pricing, extend Exposed to unsupported data types. These features, supported by open classes, empower developers to tailor Exposed to unique requirements, enhancing its versatility.
Future of Exposed: Roadmap and Community
Exposed’s roadmap reflects its community-driven evolution, with 43 new contributors in 2023 halving the GitHub issue backlog. Chantal highlighted plans for a stable 1.0 release, improved documentation with tutorials, and migration support via integration with tools like Flyway. IDE tooling will autogenerate table and entity classes, reducing boilerplate, while R2DBC support will enable non-blocking database operations. Community feedback remains vital, as seen in Q&A discussions on migration scripts, ensuring Exposed continues to meet developer needs across diverse applications.
Links:
[KotlinConf2024] Lifecycles, Coroutines, and Scopes: Structuring Kotlin
At KotlinConf2024, Alejandro Serrano Mena, a JetBrains language evolution researcher, delivered a re-recorded talk on structured concurrency, illuminating how coroutine scopes bridge Kotlin’s concurrency model with framework lifecycles. Exploring Compose, Ktor, and Arrow libraries, Alejandro demonstrated how scopes ensure intuitive job cancellation and supervision. From view model scopes in Compose to request scopes in Ktor and resource management in Arrow, the talk revealed the elegance of scope-based designs, empowering developers to manage complex lifecycles effortlessly.
Structured Concurrency: A Kotlin Cornerstone
Structured concurrency, a pillar of Kotlin’s coroutine library, organizes jobs within parent-child hierarchies, simplifying cancellation and exception handling. Alejandro explained that unlike thread-based concurrency, where manual tracking is error-prone, scopes make concurrency a local concern. Jobs launched within a CoroutineScope are tied to its lifecycle, ensuring all tasks complete or cancel together. This model separates logical tasks (what to do) from execution (how to run), enabling lightweight job scheduling without full threads, as seen in dispatchers like Dispatchers.IO.
Coroutine Scopes: Parents and Children
A CoroutineScope acts as a parent, hosting jobs created via launch (fire-and-forget) or async (result-producing). Alejandro illustrated this with a database-and-cache example, where a root job spawns tasks like saveToDatabase and saveToCache, each with subtasks. Cancellation propagates downward—if the root cancels, all children stop. Exceptions bubble up, triggering default cancellation of siblings unless a SupervisorJob or CoroutineExceptionHandler intervenes. Scopes wait for all children to complete, ensuring no dangling tasks, a key feature for frameworks like Ktor.
Compose: View Model Scopes in Action
In Jetpack Compose, view model scopes tie coroutines to UI lifecycles. Alejandro showcased a counter app, where a ViewModel manages state and launches tasks, like fetching weather data, within its viewModelScope. This scope survives Android events like screen rotations but cancels when the activity is destroyed, preventing job leaks. Shared view models across screens maintain state during navigation, while screen-specific view models clear tasks when their composable exits, balancing persistence and cleanup in multiplatform UI development.
Ktor: Scopes for Requests and Applications
Ktor, a Kotlin HTTP framework, leverages coroutine scopes for server-side logic. Alejandro demonstrated a simple Ktor app with GET and WebSocket routes, each tied to distinct scopes. The PipelineContext scope governs individual requests, while the Application scope spans the server’s lifecycle. Launching tasks in the request scope ensures they complete or cancel with the request, enabling fast responses. Application-scoped tasks, like cache updates, persist beyond requests, offering flexibility but requiring careful cancellation to avoid lingering jobs.
Arrow: Beyond Coroutines with Resource and Saga Scopes
The Arrow library extends scope concepts beyond coroutines. Alejandro highlighted resource scopes, which manage lifecycles of database connections or HTTP clients, ensuring automatic disposal via install or autoCloseable. Saga scopes orchestrate distributed transactions, pairing actions (e.g., increment) with compensating actions (e.g., decrement). Unlike coroutine scopes, which cancel on exceptions, saga scopes execute compensations in reverse, ensuring consistent states across services. These patterns showcase scopes as a versatile abstraction for lifecycle-aware programming.
Dispatching: Scheduling with Flexibility
Coroutine scopes delegate execution to dispatchers, separating task logic from scheduling. Alejandro noted that default dispatchers inherit from parent scopes, but developers can specify Dispatchers.IO for I/O-intensive tasks or Dispatchers.Main for UI updates. This decoupling allows schedulers to optimize thread usage while respecting structured concurrency rules, like cancellation propagation. By choosing appropriate dispatchers, developers fine-tune performance without altering the logical structure of their concurrent code.
Conclusion: Think Where You Launch
Alejandro’s key takeaway—“think where you launch”—urges developers to consider scope placement. Whether in Compose’s view models, Ktor’s request handlers, or Arrow’s resource blocks, scopes simplify lifecycle management, making cancellation and cleanup intuitive. By structuring applications around scopes, Kotlin developers harness concurrency with confidence, ensuring robust, maintainable code across diverse frameworks.
Links:
[KotlinConf2024] Kotlin 2.0 and Beyond: Evolving Language Features
Michail Zarečenskij, Kotlin’s lead language designer, captivated KotlinConf2024 with a deep dive into Kotlin 2.0’s advancements and future features. The K2 compiler, central to Kotlin 2.0, introduces a frontend intermediate representation (FEIR) and a new control flow engine, enhancing code consistency and smart casts. Michail outlined upcoming features like guarded conditions, context parameters, and union types for errors, addressing modern development challenges. Through code examples and audience Q&A, he showcased Kotlin’s evolution, ensuring it remains concise, safe, and expressive for millions of developers.
Kotlin’s Evolutionary Journey
Since its 1.0 release eight years ago, Kotlin has grown significantly, adding features like coroutines, functional interfaces, and multiplatform support post-launch. Michail highlighted gradual introductions, such as trailing commas and exhaustive when statements, alongside bug fixes for smart casts and type inference. Beyond language, Kotlin targets JVM, Native, and Web, with scripting, Android, and server-side capabilities. Supported by IntelliJ and Fleet plugins, Compose compiler plugins, and libraries like Serialization, Kotlin’s ecosystem thrives on community-driven open-source contributions, setting the stage for K2’s transformative impact.
The K2 Compiler: A Robust Foundation
The K2 compiler, powering Kotlin 2.0, addresses limitations of the original compiler, which struggled with unexpected features like multiplatform requirements. Michail explained K2’s redesigned architecture, enabling faster language evolution and multiplatform plugin support. Unlike the tightly coupled original, K2 separates compiler and IDE logic, simplifying maintenance. With over 80 features, including build tool enhancements, K2 prioritizes performance, cutting compilation times, and correctness, fixing longstanding issues. Tested on 10M lines of code, K2 ensures stability, making it a cornerstone for future language advancements.
Frontend Intermediate Representation: Consistent Code
K2’s frontend intermediate representation (FEIR) transforms complex language constructs into simpler forms earlier in compilation, ensuring consistent analysis. Michail demonstrated with a mutable list increment example, where K2 resolves operator and conversion issues that tripped the old compiler. By desugaring expressions, FEIR handles nullable operators and delegate properties robustly, supporting intricate combinations of operators and extensions. This consistency empowers developers to compose features confidently, reducing errors in scenarios like nullable assignments or generic type operations, strengthening Kotlin’s expressiveness.
Control Flow Engine: Smarter Analysis
The new control flow engine in K2 enhances code execution analysis, detecting unreachable code and potential bugs. Michail showcased improved smart casts, such as local variables contributing to type safety. For example, extracting a nullability check to a variable now supports smart casts, unlike the old compiler. Inline functions gain implicit “call-in-place” contracts, enabling smart casts in lambdas. Logical operator smart casts, like merging types after an “or” check, further refine type inference, making Kotlin’s type system more intuitive and reducing manual casts.
Enhanced Smart Casts in Kotlin 2.0
Smart casts, a Kotlin hallmark, see significant upgrades in 2.0. Michail presented examples where K2 applies smart casts across nullability checks, type checks, and inline function lambdas. For instance, checking a variable’s type and nullability now triggers dual smart casts in appropriate blocks. Logical “or” operations infer supertypes, enabling method calls without explicit casting. These enhancements reduce cognitive load, letting developers focus on logic rather than type management. Compatibility with existing smart casts and contracts ensures a seamless transition, boosting code safety.
Guarded Conditions: Concise Control Flow
Set for beta in Kotlin 2.1, guarded conditions in when expressions eliminate restrictive single-check limitations. Michail illustrated with a UI-rendering example, where repeated variable checks cluttered code. Guarded conditions allow additional “if” clauses in when branches, reducing repetition and nesting. Context-sensitive resolution, planned for Kotlin 2.2, further simplifies sealed type handling by omitting base class names when types are known. These features streamline control flow, enhancing readability and maintainability, especially in complex UI or data-processing logic.
Context Parameters: Flexible APIs
Context parameters, moving to beta in Kotlin 2.2, enhance API design by allowing multiple receivers. Michail demonstrated with an autoclose scope, where context parameters enable extension functions within specific scopes, improving IDE autocompletion. This addresses limitations in single-receiver functions, making APIs more extensible and discoverable. By moving receivers to a context section, developers gain flexibility in defining operations, aligning with Kotlin’s focus on expressive, type-safe APIs. The feature’s popularity in experimental form underscores its potential to reshape library design.
Union Types for Errors: Robust Error Handling
Michail previewed union types for errors, targeting error and exception handling without general union types due to type checker complexity. In a sequence search example, union types distinguish “not found” from “null” results, eliminating extra variables and unchecked casts. Planned for future releases, this feature introduces a dedicated error type category with a “throw” method, compatible with exceptions. Smart casts automatically apply, streamlining error handling. Q&A clarified that multicatch support, akin to Java, is a goal, enhancing Kotlin’s robustness in production code.
Links:
[KotlinConf2024] KotlinConf2024 Keynote: Powering the Future with Kotlin 2.0
KotlinConf2024, hosted in Copenhagen, welcomed 2,000 attendees and thousands online, kicking off with a vibrant keynote celebrating Kotlin’s evolution. Igor Tolstoy, Kotlin Project Lead at JetBrains, unveiled Kotlin 2.0, powered by the K2 compiler, promising double compilation speeds and robust multiplatform capabilities. Joined by speakers from Meta, Google, Amazon, and JetBrains, the keynote showcased Kotlin’s adoption in 20M lines of code at Meta, Google’s multiplatform push, and Amazon’s AWS SDK. From Compose Multiplatform to AI-driven tools, the event underscored Kotlin’s role in modern development, fueled by a thriving ecosystem.
A Global Stage for Kotlin Innovation
KotlinConf2024 buzzed with energy, uniting 2,000 in-person attendees, online viewers, and 71 global events across 37 countries. The conference featured five parallel sessions, lightning talks, a coach challenge, and code labs by Touchlab. A lively party with a live band and quiz, plus a closing panel, kept spirits high. Attendees donned T-shirts with words like “love,” “code,” and “nothing,” encouraged to form phrases for social media with #KotlinConf. Sponsors, including American Express, powered the event, with their booths bustling in the exhibit hall. The KotlinConf app, built with Compose Multiplatform, guided attendees, urging them to vote on sessions to shape future lineups.
Kotlin 2.0: The K2 Compiler Revolution
Igor Tolstoy introduced Kotlin 2.0, a milestone driven by the K2 compiler. This rewrite delivers a 2x compilation speed boost, slashing wait times for builds. Tested across 10M lines of code from 40 JetBrains and community projects, K2 ensures stability, with 18,000 developers and companies like Meta adopting early versions. The IntelliJ K2 mode, nearing beta, accelerates code highlighting by 1.8x, set to become default in IntelliJ 24.3. Avoiding major syntax changes, K2 fixes longstanding issues, enhancing code consistency and enabling faster language evolution without breaking existing projects.
Meta’s Kotlin Journey: Scaling Android
Eve Maler, an Android engineer from Meta, shared their Kotlin adoption, now spanning 20M lines of code. Since embracing Kotlin-first development three years ago, Meta reduced code by 10%, boosting reliability and developer preference. K2’s incremental compilation cut build times by up to 20%, with 95% of modules now using K2. Tools like IntelliJ’s J2K converter automate Java-to-Kotlin transitions, converting tens of thousands of lines weekly. Meta’s frameworks, including Litho and Dex optimizations, fully support Kotlin, paving the way for a mono-language Android experience, enhancing developer productivity.
Google’s Multiplatform Commitment
Jeffrey van Gogh from Google highlighted their investment in Kotlin, with 33M lines of code internally, doubling since 2023. Kotlin 2.0’s stability thrilled Google, who contributed compiler fixes and ported tools like Android Lint and Compose plugins to K2. The Compose compiler plugin now ships with Kotlin distributions, simplifying updates. Google announced official Android support for Kotlin Multiplatform (KMP) at Google I/O, enabling shared business logic across mobile, web, and desktop. Jetpack libraries like Room and DataStore now support KMP, with Android Studio integrating native KMP tooling, signaling a hybrid model balancing native and shared code.
Compose Multiplatform: Cross-Platform UI
Sebastian Aigner and Ekaterina Petrova celebrated Compose Multiplatform’s stability on Android and desktop, with iOS nearing beta and web in alpha. Used in thousands of apps, including McDonald’s, Compose reduced crashes and unified teams by sharing business logic. New APIs, like Jetpack Navigation and type-safe resources, enhance cross-platform development. iOS-specific improvements, such as VoiceOver integration and refined scroll physics, ensure native experiences. Web support leverages Kotlin/Wasm for high-performance browser apps. Compose’s flexibility lets developers choose how much code to share, from logic to full UI, meeting users across platforms.
Tooling Evolution: Amper and Fleet
JetBrains introduced Amper, a new build tool simplifying multiplatform project setup with minimal configuration. A Kotlin JVM project requires just one line, with dependencies easily added. Amper integrates with IntelliJ and Android Studio, offering quick fixes for project creation. Fleet, a preview multiplatform IDE, unifies Kotlin and Swift development, supporting Xcode projects and cross-language debugging. These tools automate environment checks, provide UI previews, and integrate JetBrains’ AI Assistant for code generation, streamlining workflows and lowering barriers for KMP adoption.
Ecosystem Growth: Libraries and AWS
The Kotlin ecosystem thrives, with a 50% rise in open-source multiplatform solutions. Libraries like Ktor, Serialization, and DateTime gain multiplatform APIs, while new additions like Kandy (data visualization) and DataFrame (data processing) expand capabilities. Amazon’s Julia detailed their AWS SDK for Kotlin, now generally available, built on Smithy for idiomatic APIs. Supporting hundreds of services, including Amazon Bedrock, the SDK leverages coroutines for pagination and streams. Amazon’s internal Kotlin use surged 6x, with teams like Prime Video reporting higher quality and productivity.
AI-Powered Development with JetBrains
Svetlana Isakova closed with JetBrains’ AI Assistant, written in Kotlin and integrated into IntelliJ and Fleet. It offers context-aware code completion, refactoring, and explanations, understanding project structures and dependencies. A Kotlin-specific language model, trained on open-source repositories, powers precise code generation, outperforming larger models in benchmarks. Available in IntelliJ 24.2, it supports multi-line completion and custom contexts. For enterprises, an on-premises version ensures compliance. Open-sourced datasets on Hugging Face further Kotlin’s AI advancements, equipping developers for the AI-driven future.
Links:
[KotlinConf2023] Video Game Hacking with Kotlin/Native: A Low-Level Adventure with Ignat Beresnev
At KotlinConf’23, Ignat Beresnev, a member of the Kotlin team at JetBrains and a core contributor to Dokka, stepped onto the stage with an unexpected topic: using Kotlin/Native for video game hacking. Far from a gimmick, his talk offered a solid foundation in low-level memory manipulation techniques, revealing how Kotlin/Native can be a surprisingly practical tool for creating trainers, bots, and various forms of game hacks. Drawing on examples such as modding Grand Theft Auto, the session aimed to demystify game hacking and present it as an accessible and technically rich domain for Kotlin developers.
Ignat began by recounting his personal journey into game modification, which started years earlier with a self-imposed challenge to write a World of Warcraft bot in Java. While technically successful, the attempt exposed the limitations of Java when it comes to low-level system access. Rediscovering the problem through the lens of Kotlin/Native, he found a much better fit: a language that retained Kotlin’s expressiveness while unlocking native-level capabilities required for deep interaction with operating system APIs.
Understanding Game Internals and Memory Manipulation
The core premise of game hacking, Ignat explained, lies in understanding how games store and manage state. Just like any other program, a game keeps its data—such as player health, in-game currency, or positional coordinates—in memory. If you can discover where a particular value is stored, you can read it, monitor it, or even modify it in real time. He illustrated this with a relatable scenario: if a character in a game has 100 units of currency, then somewhere in memory exists a variable holding that value. The trick is finding it.
To pinpoint such a memory address, one typically uses a memory scanning tool like Cheat Engine. The process involves searching the memory space for a known value—say, 100—then performing an in-game action that changes it, such as spending money. The search is then repeated for the new value (e.g., 80), gradually narrowing down the list of candidate addresses until the correct one is isolated.
Once the memory address is identified, Kotlin/Native can be used to read from or write to that memory location by interfacing directly with native Windows API functions. Ignat detailed this workflow by first obtaining a handle to the target process using functions like OpenProcess, which grants the required permissions to access another process’s memory. He pointed out how abstract and opaque some of the types in C APIs can be—such as HANDLE, which is essentially a pointer behind the scenes—but noted that Kotlin/Native handles these seamlessly through its C interop layer.
To read memory, one would use ReadProcessMemory, specifying the process handle, the target memory address, a buffer to receive the data, and additional arguments to track the number of bytes read. Kotlin/Native’s support for functions like allocArray and cValuesOf simplifies this otherwise complex operation. Writing memory involves a nearly identical process, this time using the WriteProcessMemory function to inject new values into specific memory locations.
Ignat added a humorous aside, noting how tricky it can be to locate something like a string literal in a game’s memory. Nonetheless, he successfully demonstrated a live example, changing an on-screen number in a lightweight game to prove the concept in action.
DLL Injection and Function Invocation
While reading and writing memory opens up powerful capabilities, more advanced techniques allow even deeper integration with the target game. One such technique is DLL injection. This method involves writing a Dynamic Link Library and tricking the game process into loading it. Once loaded, the DLL gains access to the same memory and execution privileges as the game itself, effectively becoming part of its runtime.
Ignat outlined the injection process step by step. First, the target process must be located and a handle acquired. Next, the injector allocates memory in the target’s address space to store the path of the DLL. This path is written into the allocated space, after which the program looks up the address of the LoadLibrary function in kernel32.dll. Since this system library is mapped at the same location across processes, it provides a reliable anchor point. Finally, CreateRemoteThread is used to spawn a new thread inside the game process that calls LoadLibrary, thereby loading the malicious DLL and executing its code.
Once injected, the DLL has full access to call the game’s internal functions—if their memory addresses and calling conventions are known. Ignat demonstrated this by referencing documentation from a modding community for GTA: San Andreas, which includes reverse-engineered addresses and function signatures for in-game routines like CreateCar. By defining a function pointer in Kotlin/Native that matches the signature and calling it through the injected DLL, one can trigger effects like spawning vehicles at will. Of course, this requires careful adherence to calling conventions, such as stdcall, and a deep understanding of binary interfaces.
Beyond Games: Broader Applications
While the talk focused on game modification, Ignat was clear in emphasizing that these techniques extend far beyond entertainment. The same approaches can be used to patch bugs in native libraries, build plugins for applications not originally designed for extensibility, gather usage metrics from legacy software, or automate GUI interactions. What Kotlin/Native brings to the table is the rare combination of modern Kotlin syntax with native-level system access, making it a uniquely powerful tool for developers interested in systems programming, reverse engineering, or unconventional automation.
By the end of the session, Ignat had shown not just how to hack a game, but how to think like a systems programmer using Kotlin/Native. It was a fascinating, fun, and deeply technical presentation that pushed the boundaries of what most Kotlin developers might expect from their tooling—and opened the door to new realms of possibility.
Links:
[KotlinConf2023] KotlinConf’23 Closing Panel: Community Questions and Future Insights
KotlinConf’23 concluded with its traditional Closing Panel, an open forum where attendees could pose their burning questions to a diverse group of experts from the Kotlin community, including key figures from JetBrains and Google. The panel, moderated by Hadi Hariri, featured prominent names such as Roman Elizarov, Egor Tolstoy, Maxim Shafirov (CEO of JetBrains), Svetlana Isakova, Pamela Hill, Sebastian Aigner (all JetBrains), Grace Kloba, Kevin Galligan, David Blanc, Wenbo, Jeffrey van Gogh (all Google), Jake Wharton (Cash App), and Zac Sweers (Slack), among others.
The session was lively, covering a wide range of topics from language features and tooling to ecosystem development and the future of Kotlin across different platforms.
Kotlin’s Ambitions and Language Evolution
One of the initial questions addressed Kotlin’s overarching goal, humorously framed as whether Kotlin aims to “get rid of other programming languages”. Roman Elizarov quipped they only want to get rid of “bad ones,” while Egor Tolstoy clarified that Kotlin’s focus is primarily on application development (services, desktop, web, mobile) rather than systems programming.
Regarding Kotlin 2.0 and the possibility of removing features, the panel indicated a strong preference for maintaining backward compatibility. However, if a feature were to be considered for removal, it would likely be something with a clearly superior alternative, such as potentially older ways of doing things if newer, more robust mechanisms (like K2 compiler plugins replacing older KAPT mechanisms, hypothetically) became the standard. The discussion also touched on the desire for a unified, official Kotlin style guide and formatter to reduce community fragmentation around tooling, though Zac Sweers noted that even with an official tool, community alternatives would likely persist.
Multiplatform, Compose, and Ecosystem
A significant portion of the Q&A revolved around Kotlin Multiplatform (KMP) and Compose Multiplatform.
* Dart Interoperability: Questions arose about interoperability between Kotlin/Native (especially for Compose on iOS which uses Skia) and Dart/Flutter. While direct, deep interoperability wasn’t presented as a primary focus, the general sentiment was that both ecosystems are strong, and developers choose based on their needs. The panel emphasized that Compose for iOS aims for a native feel and deep integration with iOS platform features.
* Compose UI for iOS and Material Design: A recurring concern was whether Compose UI on iOS would feel “too Material Design” and not native enough for iOS users. Panelists from JetBrains and Google acknowledged this, stressing ongoing efforts to ensure Compose components on iOS adhere to Cupertino (iOS native) design principles and feel natural on the platform. Jake Wharton added that making Kotlin APIs feel idiomatic to iOS developers is crucial for adoption.
* Future of KMP: The panel expressed strong optimism for KMP’s future, highlighting its stability and growing library support. They see KMP becoming the default way to build applications when targeting multiple platforms with Kotlin. The focus is on making KMP robust and ensuring a great developer experience across all supported targets.
Performance, Tooling, and Emerging Areas
- Build Times: Concerns about Kotlin/Native build times, especially for iOS, were acknowledged. The team is continuously working on improving compiler performance and reducing build times, with K2 expected to bring further optimizations.
- Project Loom and Coroutines: Roman Elizarov reiterated points from his earlier talk, stating that Loom is excellent for migrating existing blocking Java code, while Kotlin Coroutines offer finer-grained control and structured concurrency, especially beneficial for UI and complex asynchronous workflows. They are not mutually exclusive and can coexist.
- Kotlin in Gaming: While not a primary focus historically, the panel acknowledged growing interest and some community libraries for game development with Kotlin. The potential for KMP in this area was also noted.
- Documentation: The importance of clear, comprehensive, and up-to-date documentation was a recurring theme, with the panel acknowledging it as an ongoing effort.
- AI and Kotlin: When asked about AI taking developers’ jobs, Zac Sweers offered a pragmatic take: AI won’t take your job, but someone who knows how to use AI effectively might. The panel highlighted that Kotlin is well-suited for building AI tools and applications.
The panel concluded with the exciting reveal of Kotlin’s reimagined mascot, Kodee (spelled K-O-D-E-E), a cute, modern character designed to represent the language and its community. Pins of Kodee were made available to attendees, adding a fun, tangible takeaway to the conference’s close.
Links:
[KotlinConf2023] Compose Multiplatform on iOS: Sharing UIs Across Ecosystems with Sebastian Aigner and Nikita Lipsky
At KotlinConf’23, Sebastian Aigner (Developer Advocate at JetBrains) and Nikita Lipsky (Software Developer for Kotlin at JetBrains) presented an exciting overview of Compose Multiplatform, focusing on its then-Alpha support for iOS. Their session detailed how this JetBrains initiative enables developers to write their user interface once in Kotlin and deploy it across Android, iOS, desktop, and web, fostering significant code sharing and development efficiency. The official documentation for Compose Multiplatform offers further insights.
The presentation began by recapping the classic Kotlin Multiplatform (KMP) use case, which allows sharing of business logic while retaining access to platform-specific APIs. Compose Multiplatform builds upon this by providing a solution for sharing the UI layer itself, addressing scenarios where building and maintaining separate native UIs for each platform is not feasible due to time, resources, or the desire for rapid market entry. While the talk focused on iOS and Android, the speakers emphasized that Compose Multiplatform also supports desktop (stabilized in late 2021) and web targets.
Architecture and Jetpack Compose Foundations
A key point underscored by Sebastian and Nikita was that Compose Multiplatform is built upon Jetpack Compose, Google’s modern declarative UI toolkit for Android, which is 100% Kotlin. This means developers familiar with Jetpack Compose can leverage their existing knowledge and skills to build UIs for iOS and other platforms. The JetBrains team collaborates closely with Google, regularly upstreaming changes to the Jetpack Compose repositories.
Nikita Lipsky delved into the architecture, explaining that official Jetpack Compose itself is already a Kotlin Multiplatform project at its core, with its lowest levels defining Kotlin Multiplatform sources. The composable function concept is an extension to the Kotlin language requiring compiler support, and the entire Compose system is managed by the Compose Runtime. For iOS, Compose Multiplatform renders UI elements by drawing directly onto a CAPI (Canvas API) provided by Skiko, a graphics library that abstracts over Skia (for Android and desktop) and CoreGraphics (for iOS). This allows for consistent rendering across platforms.
Live Demos and iOS Integration
The session featured live demonstrations showcasing the capabilities of Compose Multiplatform on iOS. Sebastian Aigner walked through a sample application, highlighting how standard Jetpack Compose code for UI elements, state management (using remember), layouts (like Column), and modifiers can be shared and run on iOS simulators and devices. He demonstrated features like text input, button interactions, and even integration with iOS-specific functionalities like the share sheet, emphasizing the goal of seamless interoperability.
The speakers also discussed the importance of providing solid accessibility integrations and ensuring smooth performance, even on high-refresh-rate displays, which is an ongoing area of focus for the Kotlin/Native and Compose Multiplatform teams. Interoperability with existing iOS UI code (SwiftUI and UIKit) was also presented as a key feature, allowing for gradual adoption. Developers can embed Compose Multiplatform views within existing SwiftUI applications or, conversely, embed native iOS views within a Compose Multiplatform UI. This flexibility is crucial for teams looking to integrate Compose into their established projects incrementally.
Getting Started and Future Outlook
Sebastian and Nikita provided clear guidance on how developers can start experimenting with Compose Multiplatform for iOS. They pointed to project templates, sample applications available on the Compose Multiplatform GitHub repository (including to-do list apps and code viewers), and updated KMP production samples that now include branches with Compose-based UI implementations. The new memory manager in Kotlin/Native was also mentioned as a significant improvement, simplifying multi-threaded programming for all Kotlin targets, including iOS.
While acknowledging that the iOS target was in Alpha and some areas were still works in progress, the overall message was one of excitement and a call to action for the community. They encouraged developers to explore the technology, provide feedback, and contribute to its evolution. The vision is a future where developers can agree on a delightful way to write UIs for all their target platforms using Kotlin.
Links:
[KotlinConf2023] KotlinConf’23 Keynote: The Future of Kotlin is Bright and Multiplatform
KotlinConf’23 kicked off with an energizing keynote, marking a much-anticipated return to an in-person format in Amsterdam. Hosted by Hadi Hariri of JetBrains, the session brought together key figures from both JetBrains and Google, including Roman Elizarov, Svetlana Isakova, Egor Tolstoy, and Grace Kloba (VP Engineering for Android Developer Experience at Google), to share exciting updates and future directions for the Kotlin language and its ecosystem. The conference also featured a global reach with KotlinConf Global events in 41 countries. The main announcements from the keynote are also available in a blog post on the Kotlin blog.
The keynote celebrated Kotlin’s impressive growth, with statistics highlighting its widespread adoption, particularly in Android development where it’s the most popular language, used in over 95% of the top 1000 Android apps. A major focus was the upcoming Kotlin 2.0, centered around the new K2 compiler, which promises significant performance improvements, stability, and a foundation for future language evolution. The K2 compiler is nearing completion and is set to be released as Kotlin 2.0. The IntelliJ IDEA plugin will also adopt the K2 frontend, aligning with IntelliJ releases.
The Evolution of Kotlin: K2 Compiler and Language Features
The K2 compiler was a central theme of the keynote, marking a major milestone for Kotlin. This new compiler front-end, which also powers the IDE, is designed to be faster, more stable, and enable the development of new language features and tooling capabilities more rapidly. Kotlin 2.0, built on K2, is expected to bring these benefits to all Kotlin developers, enhancing both compiler performance and IDE responsiveness.
Looking beyond Kotlin 2.0, the speakers provided a glimpse into potential future language features that are under consideration. These included:
* Static Extensions: Allowing extension functions to be resolved statically, potentially improving performance and clarity.
* Collection Literals: Introducing a more concise syntax for creating collections, like using square brackets for lists, with efficient implementations.
* Name-Based Destructuring: Offering a more flexible way to destructure objects based on property names rather than just position.
* Context Receivers: A powerful feature for providing contextual information to functions in a more implicit and structured manner. This feature, however, is being approached carefully to ensure it aligns well with Kotlin’s principles.
* Explicit Fields: Providing more control over backing fields for properties.
The team emphasized a careful approach to evolving the language, ensuring new features are well-designed and maintainable. Compiler plugins were also highlighted as an avenue for extending Kotlin’s capabilities.
Kotlin in the Ecosystem: Google’s Investment and Multiplatform Growth
Grace Kloba from Google took the stage to reiterate Google’s strong commitment to Kotlin. She shared insights into Google’s investments in the Kotlin ecosystem, including the development of Kotlin Symbol Processing (KSP) and the continued focus on making Kotlin the default choice for Android development. Google officially supported Kotlin for Android development by early 2017. The Kotlin DSL is now the default for Gradle build scripts in Android Studio, enhancing developer experience with features like semantic highlighting and code completion. Google also actively contributes to the Kotlin Foundation and encourages the community to participate through programs like the Kotlin Foundation Grants Program, which focuses on supporting multiplatform libraries and frameworks.
Kotlin Multiplatform (KMP) was another major highlight, showcasing its growing maturity and adoption. The vision for KMP is to allow developers to share code across various platforms—Android, iOS, desktop, web, and server-side—while retaining the ability to write platform-specific code when needed. The keynote celebrated the increasing number of multiplatform libraries and tools, including KMM Bridge, that simplify KMP development. The future of KMP looks bright, with efforts to further improve the developer experience and expand its capabilities.
Compose Multiplatform and Emerging Technologies
The keynote also showcased the advancements in Compose Multiplatform, JetBrains’ declarative UI framework for building cross-platform user interfaces. A significant announcement was the alpha release of Compose Multiplatform for iOS, enabling developers to write their UI once in Kotlin and deploy it on both Android and iOS, and even desktop and web. This opens up new possibilities for code sharing and faster development cycles for mobile applications.
Finally, the team touched upon Kotlin’s expansion into emerging technologies like WebAssembly (Wasm). JetBrains is developing a new compiler backend for Kotlin targeting WebAssembly with its garbage collection proposal, aiming for high-performance Kotlin code in the browser. Experiments with running Compose applications in the browser using WebAssembly were also mentioned, hinting at a future where Kotlin could offer a unified development experience across an even wider range of platforms. The keynote concluded with an invitation for the community to dive deeper into these topics during the conference and to continue contributing to Kotlin’s vibrant ecosystem.
Links:
[KotlinConf2019] Exploring the Power of Kotlin/JS
Sebastian Aigner, a developer advocate at JetBrains, captivated KotlinConf2019 with his deep dive into Kotlin/JS, the JavaScript target for Kotlin. With a passion for web development, Sebastian showcased how recent advancements make Kotlin/JS a compelling choice for building web applications. From streamlined tooling to seamless JavaScript interoperability, he outlined the current state and future potential of Kotlin/JS, inspiring both newcomers and seasoned developers to leverage Kotlin’s paradigms in the browser.
Simplifying Development with the New Gradle Plugin
Kotlin/JS has evolved significantly, with the new Kotlin/JS Gradle plugin emerging as the cornerstone for browser and Node.js development. Sebastian explained that this plugin unifies previously fragmented approaches, replacing deprecated plugins like kotlin2js and kotlin-frontend. Its uniform Gradle DSL simplifies project setup, offering sensible defaults for Webpack bundling without requiring extensive configuration. For developers transitioning to multi-platform projects, the plugin’s compatibility with the Kotlin multi-platform DSL minimizes changes, enabling seamless integration of additional targets. By automating JavaScript environment setup, including yarn and package.json, the plugin empowers Kotlin developers to focus on coding rather than managing complex JavaScript tooling.
Mastering Dependency Management with npm
The JavaScript ecosystem, with over a million npm packages, offers unparalleled flexibility, and Kotlin/JS integrates effortlessly with this vast library. Sebastian highlighted how the Gradle plugin manages npm dependencies directly, automatically updating package.json when dependencies like React or styled-components are added. This eliminates the need for separate JavaScript environment setup, saving time, especially on non-standard platforms like Windows. Developers can import Kotlin libraries (e.g., coroutines, serialization) alongside JavaScript packages, with Gradle handling the JavaScript-specific versions. This unified approach bridges the gap between Kotlin’s structured ecosystem and JavaScript’s dynamic world, making dependency management intuitive even for those new to JavaScript.
Bridging Kotlin and TypeScript with Dukat
Interoperating with JavaScript’s dynamic typing can be challenging, but Sebastian introduced Dukat, an experimental tool that converts TypeScript declaration files into Kotlin external declarations. By leveraging TypeScript’s de facto standard for type definitions, Dukat enables type-safe access to npm packages, such as left-pad or react-minimal-pie-chart. While manual external declarations require tedious annotation, Dukat automates this process, generating headers for packages with TypeScript support or community-contributed definitions. Sebastian encouraged early adoption to provide feedback, noting that Dukat already powers browser and Node.js API wrappers. This tool promises to simplify integration with JavaScript libraries, reducing the friction of crossing the static-dynamic typing divide.
Enhancing Testing and Debugging with Source Maps
Testing and debugging are critical for robust applications, and Kotlin/JS delivers with integrated tools. Sebastian demonstrated how the Gradle plugin supports platform-specific test runners like Karma, allowing tests to run across browsers (e.g., Firefox, headless Chrome). Source maps, automatically generated since Kotlin 1.3.60, provide detailed stack traces for Node.js and interactive debugging in browser DevTools. Developers can set breakpoints in Kotlin code, inspect variables, and trace errors directly in Chrome’s console, as shown in Sebastian’s pong game demo. Gradle test reports further enhance diagnostics, offering HTML-based insights into test failures, making Kotlin/JS development as robust as its JVM counterpart.
Optimizing with the IR Backend
The upcoming Intermediate Representation (IR) backend marks a significant leap for Kotlin/JS. Sebastian outlined its benefits, including aggressive code size optimizations through dead code elimination. Unlike the current backend, which may ship the entire standard library, the IR backend, combined with Google Closure Compiler, reduces zipped file sizes dramatically—down to 30 KB from 3.9 MB in some cases. Faster compilation speeds, especially for incremental builds, enhance developer productivity, particularly in continuous build scenarios with Webpack’s dev server. The IR backend also supports platform-agnostic compiler plugins, simplifying multi-platform development. Sebastian noted that pre-alpha IR support in Kotlin 1.3.70 requires manual exports due to its closed-world assumption, urging developers to explore early releases.
Looking Ahead: WebAssembly and Framework Support
Sebastian concluded with a glimpse into Kotlin/JS’s future, highlighting potential support for ECMAScript 6 modules and frameworks like Angular and Vue.js. While JetBrains provides React wrappers, extending first-class support to other frameworks requires addressing their unique tooling and compilers. The IR backend also opens doors to WebAssembly, enabling Kotlin to target browsers more efficiently. Though no timelines were promised, these explorations reflect JetBrains’ commitment to aligning Kotlin/JS with modern web trends. Sebastian’s call to action—trying the Code Quiz app at the Kotlin booth and contributing to Dukat—emphasized community involvement in shaping Kotlin/JS’s evolution.