When I tried to write an equivalent of a Java try-with-resources statement in Kotlin, it didn't work for me.
I tried different variations of the following:
try (writer = OutputStreamWriter(r.getOutputStream())) {
// ...
}
But neither works. Does anyone know what should be used instead?
Apparently Kotlin grammar doesn't include such a construct, but maybe I'm missing something. It defines the grammar for a try block as follows:
try : "try" block catchBlock* finallyBlock?;
There is a use function in kotlin-stdlib (src).
How to use it:
OutputStreamWriter(r.getOutputStream()).use {
// `it` is your OutputStreamWriter
it.write('a')
}
TL;DR: No special syntax, just a function
Kotlin, as opposed to Java, does not have a special syntax for this. Instead, try-with-resources, is offered as the standard library function use.
FileInputStream("filename").use { fis -> //or implicit `it`
//use stream here
}
The use implementations
#InlineOnly
public inline fun <T : Closeable?, R> T.use(block: (T) -> R): R {
var closed = false
try {
return block(this)
} catch (e: Exception) {
closed = true
try {
this?.close()
} catch (closeException: Exception) {
}
throw e
} finally {
if (!closed) {
this?.close()
}
}
}
This function is defined as a generic extension on all Closeable? types. Closeable is Java's interface that allows try-with-resources as of Java SE7.
The function takes a function literal block which gets executed in a try. Same as with try-with-resources in Java, the Closeable gets closed in a finally.
Also failures happening inside block lead to close executions, where possible exceptions are literally "suppressed" by just ignoring them. This is different from try-with-resources, because such exceptions can be requested in Java‘s solution.
How to use it
The use extension is available on any Closeable type, i.e. streams, readers and so on.
FileInputStream("filename").use {
//use your stream by referring to `it` or explicitly give a name.
}
The part in curly brackets is what becomes block in use (a lambda is passed as an argument here). After the block is done, you can be sure that FileInputStream has been closed.
Edit: The following response is still valid for Kotlin 1.0.x. For Kotlin 1.1, there is support a standard library that targets Java 8 to support closable resource pattern.
For other classes that do not support the "use" function, I have done the following homemade try-with-resources:
package info.macias.kotlin
inline fun <T:AutoCloseable,R> trywr(closeable: T, block: (T) -> R): R {
try {
return block(closeable);
} finally {
closeable.close()
}
}
Then you can use it the following way:
fun countEvents(sc: EventSearchCriteria?): Long {
return trywr(connection.prepareStatement("SELECT COUNT(*) FROM event")) {
var rs = it.executeQuery()
rs.next()
rs.getLong(1)
}
}
I will highly recommend to use AutoCloseable for classes.
AutoCloseable object is called automatically when exiting a
try-with-resources block for which the object has been declared in the
resource specification header.
Example:
class Resource : AutoCloseable {
fun op1() = println("op1")
override fun close() = println("close up.")
}
in main function:
Resource().use {
it.op1()
}
Output:
> op1
close up.
Since this StackOverflow post is near the top of the current search results for "kotlin closeable example," and yet none of the other answers (nor the official docs) clearly explain how to extend Closeable (a.k.a. java.io.Closeable), I thought I'd add an example of how to make your own class that extends Closeable. It goes like this:
import java.io.Closeable
class MyServer : Closeable {
override fun close() {
println("hello world")
}
}
And then to use it:
fun main() {
val s = MyServer()
s.use {
println("begin")
}
println("end")
}
See this example in the Kotlin Playground here.
Related
So I'm making regexes for collections (all quantifiers are possessive). It looks like this (keep in mind the example is overly simplified for readability's sake):
val mayBeAPerson: Boolean = "totally not a person"
.toList()
.matches { // this: PatternScope
one { it.isUpperCase() } // execution of lambda could end after this method
moreThan(0) { it.isLetter() }
one { it == ' ' }
lessThan(2) { // this: PatternScope
one { it.isUpperCase() }
one { it == '.' }
one { it == ' ' }
}
one { it.isUpperCase() }
moreThan(0) { it.isLetter() }
}
As you can see, execution of lambda passed to matches could end after first one, as the predicate passed to it doesn't match first character in List. And it indeed does end. However, my solution is the opposite of elegant, as it uses throwing an exception in one and catching it in matches.
fun List<Char>.matches(build: PatternScope.() -> Unit) = try {
val scope = PatternScope(iterator())
scope.build() // may throw MatchFailed
!scope.iterator.hasNext()
} catch (_: MatchFailed) {
false
}
class PatternScope(private val iterator: Iterator<Char>) {
inline fun one(predicate: (element: Char) -> Boolean) {
if (!iterator.hasNext() || !predicate(iterator.next())) {
throw MatchFailed("match failed")
}
}
.
. etc
.
}
It totally works, but I can't help but wonder: is there a better way? I do know throwing exceptions like this is just a fancy GOTO, and I could wrap all the methods of PatternScope in ifs, like this:
class PatternScope(private val iterator: Iterator<Char>) {
private var matchFailed = false
inline fun one(predicate: (element: Char) -> Boolean) {
if (!matchFailed) {
if (!iterator.hasNext() || !predicate(iterator.next())) {
matchFailed = true
}
}
}
inline fun moreThan(n: Int, predicate: (element: Char) -> Boolean) {
if (!matchFailed) {
// logic
}
}
.
. etc
.
}
Is it more elegant though? Now I'm invoking all the functions in lambda passed to matches, and I like it even less to be honest.
My real question is: is there even better way to do it? Some magic solution to return from lambda I don't even have real access to? Some non-local returns, but from functions lambda hasn't even see yet?
Can I return from lambda by invoking some function inside its body?
Edit
Just to clarify, let's say we have a lambda:
val lambda: () -> Unit = {
someMethod() // this should return from lambda (in some cases)
someOtherMethod() // this shouldn't be invoked
}
How should the body of someMethod look like, so that someOtherMethod does not even execute when the lambda is invoked? Is there any other way but making someMethod throw an exception and wrapping lambda in try-catch block like this:
try {
lambda() // throws
} catch (_: SomeThrowableIdk) { }
I don't see a better way, but please prove me wrong.
I assume you're actually using #PublishedApi since you have a private iterator and public inline functions that access it.
Since Kotlin doesn't have checked exceptions, it is against Kotlin convention to throw Exceptions for things that are not actually errors in the program (bugs). Your first approach feels a little hacky for this reason. Since your API has public inline functions, there's no way to totally encapsulate the exceptions. You could switch to non-inline functions and storing the steps in a collection to be run internally, but this is surely more runtime overhead than the inline functions or your second approach with if statements.
Your second approach is more like a typical builder, so I don't see the problem with it. Since your functions are inline, it's not like your compiled code has a bunch of unnecessary function calls. Just if statements. You could however add a helper function to clean up your code at all the sub-functions, though I'm not sure if this can extend to the complexity of your actual class:
class PatternScope(#PublishedApi internal val iterator: Iterator<Char>) {
#PublishedApi internal var matchFailed = false
#PublishedApi internal inline fun nextRequire(require: () -> Boolean) {
matchFailed = matchFailed || !require()
}
inline fun one(predicate: (element: Char) -> Boolean) = nextRequire {
iterator.hasNext() && predicate(iterator.next())
}
}
There's no way to do what you described in your edit. Non-local returns work only with lambdas. To support something like what you describe, Kotlin would need syntax for a special kind of function that has the ability to return from the function that calls it. A function like this would have to have a new kind of signature that also declares the return type of the type of function that is permitted to call it. There simply is no such syntax or function type like that in Kotlin.
I have a Flux of strings that should be converted to a Flux of dto. Parsing can be finished with an error and by the business rules I just need to skip such entries
If I use "Kotlin's" null - I got NPE because by design reactor doesn't accept nulls in .map
fun toDtoFlux(source:Flux<String>):Flux<Dto>{
source.map(Parser::parse)
.filter(it!=null)
}
object Parser{
fun parse(line:String):Dto?{
..
}
}
I can use Optional. But it is not a Kotlin way.
fun toDtoFlux(source:Flux<String>):Flux<Dto>{
source.map(Parser::parse)
.filter(Optional.isPresent)
.map(Optional::get)
}
object Parser{
fun parse(line:String):Optional<Dto>{
..
}
}
What is the most idiomatic way to handle such cases in Kotlin?
You can create an extension function:
fun <T, U> Flux<T>.mapNotNull(mapper: (T) -> U?): Flux<U> =
this.flatMap { Mono.justOrEmpty(mapper(it)) }
Then you can use it like this:
fun main() {
Flux.just("a", "b", "c")
.mapNotNull { someNullableMapFunction(it) }
.doOnNext { println(it) } // prints "a" and "c"
.blockLast()
}
fun someNullableMapFunction(it: String): String? {
if (it == "b") {
return null
}
return it
}
UPDATE
Based on Simon's comment extension function implementation might be more idiomatic (and performant?) in Reactor this way:
fun <T, U> Flux<T>.mapNotNull(mapper: (T) -> U?): Flux<U> =
this.handle { item, sink -> mapper(item)?.let { sink.next(it) } }
The solutions I see :
Using Reactor API
I'd suggest you to use Reactor API to address such case, and make your parser return a Mono. The empty Mono represents the absence of result. With that, you can use flatMap instead of chaining map/filter/map.
It may seem a little overkill like that, but it will allow any parser implementation to do async stuff in the future if needed (fetching information from third-party service, waiting validation from user, etc.).
And it also provide a powerful API to manage parsing errors, as you can define backoff/custom error policies on parsing result.
That would change your example like that :
fun interface Parser {
fun parse(record: String): Mono<Dto>;
}
fun Parser.toDtoFlux(source:Flux<String>): Flux<Dto> {
source.flatMap(this::parse)
}
Using sealed class
Kotlin offers other ways of managing result options, inspired by functional programming. One way is to use sealed classes to desing a set of common cases to handle upon parsing. It allows to model rich results, giving parser users multiple choices to handle errors.
sealed class ParseResult
class Success(val value: Dto) : ParseResult
class Failure(val reason : Exception) : ParseResult
object EmptyRecord : ParseResult
fun interface Parser {
fun parse(raw: String) : ParseResult
}
fun Parser.toDtoFlux(source:Flux<String>): Flux<Dto> {
return source.map(this::parse)
.flatMap { when (it) {
is Success -> Mono.just(it.value)
is Failure -> Mono.error(it.reason) // Or Mono.empty if you don't care
is EmptyRecord -> Mono.empty()
}}
}
I'd like to write a parametrized test in Kotlin. Depending on input parameters, the tested function should throw custom exception or it should succeed if everything is ok. I'm using JUnit Jupiter 5.3.2.
This is simplified version of what I have now (there are multiple input parameters in fact). It works, but it feels a little ugly as I need to include the tested method call twice:
companion object {
#JvmStatic
fun paramSource(): Stream<Arguments> = Stream.of(
Arguments.of(1, true),
Arguments.of(2, false),
Arguments.of(3, true)
)
}
#ParameterizedTest
#MethodSource("paramSource")
open fun testMyServiceMethod(param: Int, shouldThrow: Boolean) {
if (!shouldThrow) {
// here the exception should not be thrown, so test will fail if it will be thrown
myService.myMethodThrowingException(param)
} else {
assertThrows<MyCustomException>{
myService.myMethodThrowingException(param)
}
}
}
Is there any better approach on this?
You can easily encapsulate this:
inline fun <reified E : Exception> assertThrowsIf(shouldThrow: Boolean, block: () -> Unit) {
if (!shouldThrow) {
block()
} else {
assertThrows<E>(block)
}
}
Usage:
#ParameterizedTest
#MethodSource("paramSource")
open fun testMyServiceMethod(param: Int, shouldThrow: Boolean) {
assertThrowsIf<MyCustomException>(shouldThrow) {
myService.myMethodThrowingException(param)
}
}
As Neo pointed out, this wasn't a good idea. Right solution in this case would be to create two separate tests - one for each case of the original test.
Tests should include as little logic as possible. They should be simple and straightforward.
I am new to Kotlin and I want to do the following:
Annotate some functions with an annotation e.g "Executable"
At runtime, get all the functions with this annotation
Inspect a property on the annotation and if it matches a condition, invoke the function
I have the following code
annotation class Executable(val name : String)
#Executable("doSomething")
fun stepDoSomething (param1 : String) {
println("I am a step that does something! I print $param1")
}
However, I am unclear on how to retrieve all functions with the Executable annotation at runtime and inspect them.
Thank you for your help!
To accomplish this, you will need to use a classpath scanner, such as ClassGraph. Classpath scanners offer APIs to find classes based on various criteria, such as what package they’re in, what interface they implement, or what annotations they have. In the case of ClassGraph, the ScanResult has a getClassesWithMethodAnnotation(String name) method. Once you have all of those classes, you can use ordinary reflection to find which method(s) in those classes have the specific annotation you’re looking for and inspect the properties of the annotations. Here is a good overview of how to create an annotation and inspect it using reflection.
Here is my implementation based on (very helpful) Matthew Pope's answer:
import io.github.classgraph.ClassGraph
import kotlin.reflect.KClass
import kotlin.reflect.KFunction
import kotlin.reflect.jvm.kotlinFunction
#Image(filename = "image-1.svg")
fun foo() {
println("in foo")
}
#Image(filename = "image-2.svg")
fun bar() {
println("in bar")
}
#Throws(Exception::class)
fun getAllAnnotatedWith(annotation: KClass<out Annotation>): List<KFunction<*>> {
val `package` = annotation.java.`package`.name
val annotationName = annotation.java.canonicalName
return ClassGraph()
.enableAllInfo()
.acceptPackages(`package`)
.scan().use { scanResult ->
scanResult.getClassesWithMethodAnnotation(annotationName).flatMap { routeClassInfo ->
routeClassInfo.methodInfo.filter{ function ->
function.hasAnnotation(annotation.java) }.mapNotNull { method ->
method.loadClassAndGetMethod().kotlinFunction
// if parameter needed:
// method.getAnnotationInfo(routeAnnotation).parameterValues.map { it.value }
}
}
}
}
fun main(args: Array<String>) {
getAllAnnotatedWith(Image::class)
.forEach { function ->
function.call()
}
}
I'm trying to perfect myself in Kotlin with functional programming. And then I did this:
I was tired of the way I write try - catch, and created the following function:
package com.learning.functionalway
fun <T> tryCatch(t: T?, excpetion: (Throwable)): T? = try {
t
} catch (e: Exception) {
throw excpetion
}
And I used it like this:
#Service
class ProductService(val repository: IProductRepository, val repositoryS: IStockRepository) : IService<Product, ProductModel> {
override fun find(id: Long) = tryCatch(
repository.find(id),
DataNotFound("Product not found"))
other methods ..
}
And my exception that I deal in the "Exception Handler"
class DataNotFound(message: String?) : Exception(message) {
}
Is this a correct way I used to modify the way I use try - catch?
Or are there better ways to do it?
Your solution is not a "more functional" way of doing error handling but rather just arguably a slight improvement in try-catch syntax.
If you truly want to embrace functional programming, I'd recommend you to check out Arrow. The standard Kotlin library is not enough for advanced functional programming concepts (such as error handling) and Arrow fills that gap.
You can read their documentation on how to do proper error handling.
If you fancy a talk about it, I'd recommend you to check out this video (topic of error handling starts here) which is about Kotlin and functional programming.
One way to remake the try-catch syntax to make it more functional is like this:
sealed class Try<out Output> {
class Some<Output>(val output: Output) : Try<Output>()
class None(val exception: Exception) : Try<Nothing>()
companion object {
operator fun <Output> invoke(toTry: () -> Output) = try {
Some(toTry())
} catch (e: Exception) {
None(e)
}
}
val value get() = when(this) {
is Some -> output
is None -> null
}
infix fun catch(onException: (Exception) -> Unit): Output? = when (this) {
is Some -> output
is None -> {
onException(exception)
null
}
}
}
class ProductService(val repository: IProductRepository, val repositoryS: IStockRepository) : IService<Product, ProductModel> {
override fun find(id: Long): Product? = Try {
repository.find(id)
} catch { exception ->
println("Error trying to get product $exception")
}
//other methods ..
}
The key advantage here is that unlike in the original syntax you can do things by parts. So if you have a lot of tries to do and want to handle all the results at the end, with this syntax you can.