- Visual Studio Code Kotlin Mac
- Install Kotlin Mac
- Visual Studio Code Kotlin Unresolved Reference
- Visual Studio Code Kotlin Windows
This codelab is part of the Kotlin Bootcamp for Programmers course. You'll get the most value out of this course if you work through the codelabs in sequence. Depending on your knowledge, you may be able to skim some sections. This course is geared towards programmers who know an object-oriented language, and want to learn Kotlin.
Visual Studio Code Kotlin Mac
This course is geared towards programmers who know an object-oriented language and want to learn more about Kotlin. If you are familiar with C#, some of the features of Kotlin will be familiar. If you are familiar primarily with the Java programming language, you may be amazed at how much more concise and readable your code can be.
Since 2017, Google has officially supported Kotlin for developing Android apps. Read the announcement on the Android Developers Blog. This course content is a prerequisite of Android Kotlin Fundamentals.
What you'll learn
- How to work with the Kotlin REPL (Read-Eval-Print Loop) interactive shell
- The basic syntax of Kotlin code
- Install the Java Development Kit (JDK) and the IntelliJ IDEA, and become familiar with some Kotlin features.
Kotlin is a new, modern programming language created by programmers, for programmers. It's focused on clarity, conciseness, and code safety.
Mature platform
Kotlin has been around since 2011, and was released as open source in 2012. It reached version 1.0 in 2016, and since 2017 Kotlin has been an officially supported language for building Android apps. It's included with the IntelliJ IDEA as well as Android Studio 3.0 and later.
To see which version of the JDK you have installed, if any, type javac -version
in a terminal window.
You can see what the latest version of the JDK is on the Java SE Downloads page. If you have the latest version, skip ahead to Install IntelliJ IDEA.
Note: We recommend that you install only the latest JDK and JRE.
JRE or JDK?
The JRE (Java Runtime Environment) is needed for running Java and Kotlin programs. The JDK (Java Development Kit), on the other hand, includes the JRE, plus the development tools that you need for writing and running Java programs. You need the JDK for writing Kotlin programs.
Step 2: Download the JDK
You can download the JDK for free here: http://www.oracle.com/technetwork/java/javase/downloads/index.html
- Click on JDK Download.
- Under Downloads, choose the link for the JDK for your operating system.
- Accept the license agreement.
- Click on the Download button.
.dmg file to launch the install file.- A Finder window appears with an icon of an open box and the name of the
.pkg
file. - Double-click the package icon to launch the installation app, and follow the prompts as they appear.
- You might need to enter the administrator password to continue.
- After the installation is complete, feel free to delete the
.dmg
file to save space.
.pkg
file..dmg
file to save space.jdk-14.0.1_windows-x64_bin.exe
), which installs both the JDK and the JRE. By default, the JDK is installed in the C:Program FilesJavajdk-14.0.1
directory, but it depends on the latest version.PATH environment variable (system variable) for executable programs.- In Settings for Windows, search for
edit environment
in Find a setting. - Select Edit environment variables for your account in the list of matches.
- In the Environment Variables dialog in the User variables section, select Path and click the Edit... button.
- Add the path to the JDK's bin directory, for example,
C:Program FilesJavajdk-14.0.1bin
, after any existing items.
edit environment
in Find a setting.C:Program FilesJavajdk-14.0.1bin
, after any existing items.Note: This was tested for JDK 14 installed on Windows 10. Other versions of the JDK may use different directories, and the steps may be different for other versions of Windows.
Windows users: If you receive an error from either command, confirm you've added the correct path for the JRE.
ideaIC.exe
file that you downloaded.Mac:
- To mount the macOS disk image, double-click the
ideaIC.dmg
file that you downloaded. - Copy IntelliJ IDEA to the Applications folder.
Linux:
- See
Install-Linux-tar.txt
in the downloaded.tar.gz
file.
For more information on how to install and set up IntelliJ IDEA, check out Install IntelliJ IDEA.
Create a Kotlin project so IntelliJ IDEA knows you're working in Kotlin.
- In the Welcome to IntelliJ IDEA window, click Create New Project.
- In the New Project pane, select Kotlin in the left-hand navigation.
- Select Kotlin/JVM (JVM | IDEA in newer versions) in the right panel and click Next.
- Name your project
Hello Kotlin
. - Click Finish.
Now you can access the REPL (Read-Eval-Print Loop), Kotlin's interactive shell. Commands that you type into the REPL are interpreted as soon as you press Control+Enter
(Command+Enter
on a Mac).
- Select Tools > Kotlin > Kotlin REPL to open the REPL.
The first time you run IntelliJ IDEA after installing, it may take a few moments before the Kotlin menu appears under Tools.
- Type or paste the code below into the REPL.
- Press
Control+Enter
(Command+Enter
on a Mac). You should seeHello World
, as shown below. - Take a quick look at this Kotlin code. The
fun
keyword designates a function, followed by the name. As with other programming languages, the parentheses are for function arguments, if any, and the curly braces frame the code for the function. There is no return type because the function doesn't return anything. Also note that there are no semicolons at the ends of lines.
Note: If you're used to putting semicolons at the end of lines, that's OK—Kotlin doesn't mind.
Congratulations! You've written your first Kotlin program.
- Kotlin is similar to other object-oriented programming languages.
- Install the latest JDK for your operating system to use Kotlin.
- Install the IntelliJ IDEA to work with Kotlin.
- In IntelliJ IDEA, start the Kotlin REPL (Tools > Kotlin > Kotlin REPL) to practice in an interactive shell.
- Enter code followed by
Control+Enter
(Command+Enter
on a Mac) to run it. - Here is 'Hello World' in Kotlin:
Kotlin tutorials
The https://play.kotlinlang.org website includes rich tutorials called Kotlin Koans, a web-based interpreter, and a complete set of reference documentation with examples.
IntelliJ IDEA
Documentation for the IntelliJ IDEA can be found on the JetBrains website.
This section lists possible homework assignments for students who are working through this codelab as part of a course led by an instructor. It's up to the instructor to do the following:
- Assign homework if required.
- Communicate to students how to submit homework assignments.
- Grade the homework assignments.
Instructors can use these suggestions as little or as much as they want, and should feel free to assign any other homework they feel is appropriate.
If you're working through this codelab on your own, feel free to use these homework assignments to test your knowledge.
Install Kotlin Mac
Question 1
Which of the following is NOT a benefit of using the Kotlin language?
▢ Kotlin distinguishes between nullable and non-nullable data types.
▢ Kotlin is a supported language for building Android apps.
▢ Kotlin is designed so you can write less code with fewer bugs.
▢ Your code compiles faster in Kotlin.
repl on the command line.
▢ Create a Kotlin project in IntelliJ IDEA, then select Run > Kotlin REPL.
▢ Open IntelliJ IDEA, then select File > Kotlin REPL.
▢ Create a Kotlin project in IntelliJ IDEA, then select Tools > Kotlin > Kotlin REPL.
2. Kotlin Basics
For an overview of the course, including links to other codelabs, see 'Kotlin Bootcamp for Programmers: Welcome to the course.'
MobileNabil Hachicha, Android Engineer, from MongoDB Realm shares their story of creating a pure Kotlin-first SDK for use by developers.
Realm is an open-source, easy-to-use local database that helps mobile developers to build better apps faster. It launched 8 years ago with the release of the Realm Java SDK, and since then we’ve worked to make sure our API is always improving to reflect what mobile developers need.
As Kotlin has grown to become the recommended language for building Android apps, we’ve made iterative improvements to our Realm Java SDK to make sure the API is compatible. But even with various releases over the past few years — via providing helper extension functions to improve using the Realm API with Kotlin — we knew Realm would ultimately benefit from the design and implementation of a pure Kotlin-first SDK for use by developers.
In the post, we take you through what motivated the Realm Engineering team’s decision to build a new SDK from the ground-up, and we share some of the key design principles that guided the development of Realm’s Kotlin Multiplatform SDK.
Background
As usage of Kotlin grew among Android developers, Realm’s engineering team started to use Kotlin in our testing environment. This led to introducing helper functions like Query with generic type; executeTransactionAwait – which runs transactions inside coroutines — and JSR305 annotation to improve the strict null-safety type system with Kotlin.
But even with this work, there were still architectural shifts that were difficult to solve, like users adopting unidirectional dataflows based on immutability. The wider Realm community also asked us to provide a more idiomatic Kotlin API that would enable a type safe query builder, among other API improvements. We knew some of these enhancements would require a fundamental refactoring and we wanted to meet our users’ needs. So Realm’s Engineering team started to design and implement a pure Kotlin first SDK for the mobile ecosystem.
Why a Multiplatform Library?
At the same time we began to lay the foundation of our Kotlin SDK, Kotlin Multiplatform started to mature, and we quickly realized we should build Realm’s new Kotlin SDK as a Multiplatform library. There were surprisingly few multiplatform libraries for the persistence layer, and as a multiplatform mobile database, we knew Realm could help fill this gap for developers. We had an opportunity to allow Kotlin developers to build cross platform applications in the same way that Realm’s developers use our React Native and Xamarin SDKs today.
Challenges
Porting the existing Realm-Java code to work on Multiplatform was an interesting (and challenging) task for Realm’s engineers because we currently use some technologies that are platform dependent.
To define a Realm schema, we use the annotation processor to generate a proxy class and then use the Gradle Transform API to do bytecode weaving with Javassist. Both tools are Kotlin JVM specific and are not compatible with Kotlin/Native.
Similarly, Reflection is only partially supported on Kotlin/Native, so any API design based on dynamic runtime instantiation would simply not work — like the Class.forName or class.newInstance primitives.
And, concurrency and the memory model are fundamentally different between platforms. The Kotlin/JVM has a Garbage Collector, whereas Kotlin/Native relies on reference counting with a cyclic collector.
Visual Studio Code Kotlin Unresolved Reference
To successfully build a multiplatform Kotlin Native SDK for Realm, we’d need to figure out how to re-architect the SDK in a way that would address these challenges.
The Solution
Note from the Kotlin team: Compiler plugins, compiler internal API, and Cleaner API are not stable yet and will likely change in the future.
Compiler Plugin to the Rescue
Realm’s engineering team quickly decided we would need to build our own fully-fledged compiler plug-in because existing options posed too many constraints.
The Kotlin Symbol Processing API is limited to generating new Kotlin code instead of modifying existing classes, meaning it wouldn’t suit our needs. Realm had used the Kotlin Annotation processor (KAPT) in our Kotlin support for the Realm Java SDK, but it didn’t have a native annotation processing system. Instead, the Realm Java SDK generates Java stubs containing all the declarations and annotations without the methods body. It then runs the Java annotation processor on those stubs, which feeds back to KAPT and Kotlin compiler for another round. This makes compilation and refactoring slow, and isn’t available for Kotlin/Native.
At a high level, the Realm compiler plugin‘s main goal is to make defining Realm models as simple as constructing a regular Kotlin class. This is achieved by modifying the Intermediate Representation (IR) of the compiled Kotlin code in order to change the behaviour of the property accessor (getters and setters). Once this is done a developer can now call Realm’s runtime APIs so that read/writing changes the value of the property instead of the backing field. This is done using a Lowering pass on the IR.
The other task of the compiler plugin is to collect all Realm model classes in order to automatically create a schema definition of a Realm. Since the Compiler plugin API was not yet stable and documented (1.4.30 makes JVM IR Beta stable), we reverse engineered the IR code we needed to write in order to obtain the desired generated code.
Here’s what that looks like:
First, we write the Kotlin code we want the compiler to generate in a classic Kotlin/JVM project. Then we add the compiler flag to use IR and to dump the content of the IR.
This will dump a text file containing the IR code generated by the compiler before transforming it into JVM ByteCode. We then use this IR dump to work out what IR API calls we need to use to produce the desired output. We also use kotlin-compile-testing library to unit test the IR output from the Realm compiler plugin that matches the expected IR.
Releasing Native Resources
Under the hood the Realm SDKs use a C++ storage engine. The compiler plugin adds infrastructure to link the Kotlin objects with the underlying C objects by adding a synthetic native pointer property. This holds the value of the C/ C++ pointer, allowing access to the underlying persisted value inside the storage engine.
In order to avoid leaking memory, the native pointer needs to be closed when the original Kotlin object goes out of scope.
Since Kotlin/JVM and Kotlin/Native have different memory models, we decided to use two approaches. For Kotlin/JVM we rely on the same technique we use in the current Realm-Java SDK, which is based on the usage of the reference API to track pointers that need to be cleaned once their original Java counterpart is eligible for GC.
For more information about reference API and phantom reference check out this excellent talk by Bob Lee
Note from the Kotlin team: Cleaner API is not stable yet and will change in the future.
Kotlin/Native doesn’t have a Garbage collector. It uses reference counting with a cycle collector instead. Recently the Kotlin/Native team introduced the Cleaner API. This API can be used similarly to a Finalizer/Destructor block that runs after the encompassing object has been disposed of. We use this API to perform cleanups and free native pointers.
Encapsulating the native pointers in an object with the above deallocation strategies, which hook into the normal memory management, frees us from handling explicit deallocations where we use native pointers.
Native code abstraction
Accessing the custom C++ storage engine used by the Realm SDKs varies between Kotlin/JVM and Kotlin/Native. To simplify this, we added a C layer on top, which makes it easy to use tools like cinterop to interface and generate Kotlin stubs. The C layer also allowed us to avoid writing manual JNI code to access the C++ layer, thanks to SWIG tool that generates the corresponding Java and JNI stubs.
We also leveraged the expect/actual mechanism from Kotlin Multiplatform to build a module that hides the specifics of accessing Cinterop and SWIG layers in a platform agnostic manner. This allowed us to focus the design of the library API in a platform-independent way, and to do it in another module that will become the user facing public API.
This process encourages to think about features — like querying and writing to the database — in a way that’s not platform-specific.
Any platform dependent implementation details — like cleaning up native resources — do use different fundamentals per-platform (Garbage Collector for Kotlin/JVM and the Cleaner API for Kotlin/Native). This is the type of feature that should be kept inside the Native Module Abstraction layer and not be implemented in the public library module.
By isolating these low level constructs in a separate Multiplatform module, we managed to scale the development of the new Kotlin SDK within the Realm team. All the low level building blocks are isolated behind an internal platform agnostic API. This also opens up API contributions from the community without worrying about the inherent complexity of C/C++, Kotlin/Native, or JNI.
Conclusion
Now, we’re proud to say that Realm’s engineering team managed to bootstrap the new Realm Kotlin SDK as a Multiplatform library. We believe that the infrastructure is in place to encourage other authors to build Multiplatform libraries, too.
Of course, as an alpha release, we’re still polishing elements of the solution. Realm engineering has been working in lockstep with the team at JetBrains, and we have full confidence that improvements will land soon.
As we keep working, we’d love your feedback. Try the new Realm Kotlin SDK out at https://github.com/realm/realm-kotlin, and join our discussion around the design of upcoming features here. We want your opinions and suggestions as we keep building.
Visual Studio Code Kotlin Windows
Author: Nabil Hachica, Android Engineer, MongoDB Realm