Last week I wrote a post on running a Java class as a subprocess. That post was triggered by my need to run a class from within a test without prebuilding a Jar. The only difference between what I wrote in that post and what actually happened was the language. I used Kotlin to write that test. Not Java. Therefore, I have decided to write this follow up post that builds upon what I previously wrote and focuses on starting a Kotlin subprocess instead of a Java subprocess.
Let’s start with an equivalent implementation of the
exec from Running a Java class as a subprocess:
Short explanation since I covered everything else in my previous post.
The path to the Java executable is retrieved and stored in
javaBin. Using this along with the passed in
jvmArgs and the process’s classpath a command is created and executed by the
ProcessBuilder. The class is now successfully running as a subprocess.
The code above is pretty much a copy and paste of the Java implementation. The differences are the order of the function parameters. I decided to switch
jvmArgs around so I can make full use of their default values. This is based on the assumption that you are more likely to provide
args instead of
jvmArgs. It isn’t really that much of a concern when running from Kotlin since you can name the parameters when calling the function. But, if any Java code needs to call this function then the order of the parameters might be helpful (as well as adding on
Below are some ways of calling
A noticeable difference when writing in Kotlin instead of Java is the number of ways that you can define a
main function. This is due to Kotlin providing many different routes to create a static function.
The function I provided above will run a
main function in the two following scenarios:
Inside a companion object and annotated with
Inside an object and annotated with
Another way to create a static function in Kotlin is to define it outside of a class:
A name needs to be provided so Java knows what to do with it. Executing the
main function in this snippet is one situation where this is needed. Unfortunately, the
exec function won’t work in this situation, since the
MyProcess class doesn’t actually exist. Preventing it from compiling. Funnily enough, calling
MyProcess from Java code will compile without any changes.
To resolve the compilation error found in the Kotlin version,
exec’s parameters need to change very slightly:
This change sidesteps the compilation error the original
exec function presents. But, this comes with the downside of not really being type-safe and might lead to a few errors here and there where an invalid string is passed in. As you can see below:
Something about this change really rustles my jimmies. Therefore providing both overloads is probably the sanest thing to do.
To wrap up, although most of what I have to say about executing Kotlin classes as subprocesses was already covered in Running a Java class as a subprocess. There are a few differences due to Kotlin’s flexibility. A
main function in Kotlin can be defined in multiple ways and unfortunately, one of one those does not get along with
exec function that the rest are happy with. Luckily the solution is a small code change that can work well if there are overloads for both
Class class names.
If you enjoyed this post or found it helpful (or both) then please feel free to follow me on Twitter at @LankyDanDev and remember to share with anyone else who might find this useful!
Opinions expressed by Java Code Geeks contributors are their own.