Monday, November 15, 2021

Kotlin - Getting Started With Scripting


CONTEXT


So Kotlin is picking up nicely, and has been doing well. Mainly starting as some sort of alternative to Java by targeting the JVM making it interoperable with Java. So Java developers can move to Kotlin slowly, they don't have to migrate to Kotlin right away. The other great thing about Kotlin is the fact that you can compile it to Javascript making it target Javascript nicely and finally Kotlin can run natively. So this makes Kotlin a very powerful language.


It's really great, I mean Google has made it an official Android Development language, so this means we have an alternative to Java when working with Android Apps. Further more Gradle has picked up on Kotlin as an alternative to Groovy. We now also have KMM ( Kotlin Multiplatform Mobile ) so this makes it fit into the Flutter and Ionic where you can develop an App for both iOS and Android using Kotlin. So you write once and then compile for both platforms.


So I see Kotlin as the new Groovy language. So another thing about Kotlin is that you can use it as a Scripting Language. So yes, you can replace your Bash & Python scripts especially for more complex operations you want to run. Bash is can be hard to read and maintain. Python is great plus it's an interpreted language meaning you don't need to compile it like Kotlin Scripts. Just know that there's an alternative to Python / Groovy / Bash / Typescript and many other scripting languages.


So out of the box if you have set up Kotlin, you can already run the .kts files using the command kotlinc -script YourScript.kts <args>. The pain point here is that Kotlin will always have to compile the script and packaging into a .jar before running the script you intended to run.


It would be nice to have some small framework or enhancements to the existing Kotlin Scripting Engine that can help us cache these compiled scripts and make it more portable so that we don't always to go through that step mentioned above. That's why I would like to introduce you to KScript, enhancements made to the existing Kotlin Script Engine written by Holger Brandl.
  • Caching of the compiled jar files so that when you run the same script without changing the script
  • Dependencies uses the power of maven to pull some custom and third party dependencies.
  • Sourcing / Inclusion of other Kotlin Scripts.

So obviously these features are not news for people who have worked with other scripting languages, but it's good to note some of the features included.



GETTING STARTED

In order to get started you will need the following tools up and running on your machine :

  • Kotlin because it's the core language of you scripting in this case.
  • Maven because one of the nice features with Kotlin is that you can pull in dependencies.
  • Kscript which is the underlying Kotlin scripting enhancements framework.

I don't know about you but, I set up my environment using SDK Man! It's simple like that you can check it out on the net or look at my article, Managing Multiple Sotware Development Kits Using SDK Man! article


INSTALLING KOTLIN

At the time I am writing this article, the latest version is 1.5.31 so here goes :

sdk install kotlin 1.5.31



INSTALLING MAVEN

If you don't already have maven then : 


sdk install maven 3.8.2



INSTALLING KSCRIPT / KOTLIN SCRIPT

If you don't already have maven then : 


sdk install kscript 3.1.0



TEST DRIVE


QUICK SCRIPT

Open up your favourite IDE or text editor and let's write some Kotlin to test drive it.



#!/usr/bin/env kscript
/** * @author: Thabo Lebogang Matjuda * @since: 2021-05-23 * @email: <a href="mailto:tl.matjuda@gmail.com">Personal GMail</a> */ // Variables section here. val scriptUser = args[0] val functionMessage = getMessageText( scriptUser) // Print out some results println( functionMessage) /** * Takes a String value as an argument and returns text. * This returned text is a string interpolated message with your argument. */ fun getMessageText( callerName: String): String { return "Hello there $callerName" }



And there you have it. The first line is standard with some scripting languages like Bash, we just pointing out the which engine this script should use in this case it's the kscript engine Kscript expects a standard args collection just like with Java's public static void man (String[] args) {} method. So we are just pulling one parameter at index zero which Just like Java. I included a function getMessageText in here just to showcase that we can do that in the script file. As you can see if we also have string interpolation where we don't have to concatenate the parameter $callerName. The function takes in a String parameter and also returns a string, there's some TypeScript looking syntax there as well. Really nothing fancy here. 


TESTING THE SCRIPT

Go ahead on your terminal and run it like you would run a PowerShell or Bash script :



./ITTestDrive.kts Thabo



I saved my script as ITTestDrive.kts so you can save yours as anything you want. Nothing hectic there. Also notice that I am running mine with my name as the parameter. Another way or running the script is : 


kscript /where/ever/your/script/IsPlaced.kts
# For Example with our case kscript ITTestDrive.kts Thabo




Kscript Execution Example


So execute your script and you will notice that the first run is taking a bit long and that's because your script is being compiled and packaged into an executable .jar file. If you run the same script again without changing the code then it will be faster because now your script has been compiled before and Kscript can see that there are no new changes, meaning it does not need to re-compile your script. So now you wonder where this compiled .jar is saved, well in that case check a folder ${HOME}/.kscript inside your home directory, that being. You will then notice a jar file in there. That's your new script! If you wish to clean up on these cached file from time to time you can use the command :



# Clearing the Kscript Cache
kscript --clear-cache



You can see now how all this works, unlike Python and Bash, you can see there's a drawback of compilation time, if this compilation does not bother you then go for the Kscript and have fun. 



Kscript Cache



CONCLUSION

That's it! Well done you have written your first Kotlin Script and yea, may be we can look into more Kotlin Goodies in the future and have some more fun. Let me know what you think, Cheers!






Spring Boot App As A Unix Service ( Systemd )

 

CONTEXT

When thinking of the modern way of delivering software then tools like Docker & Kubernetes come into mind. If you are in the open source world working with languages like Java where you can package your entire web application into a .jar file and then that can later be “Dockerized“ aka “Containerized“.


This is all good and there are hordes of documentation and articles that support that this is great, but what happens when you are in the space where docker is not “in yet“? You have this .jar application but cannot really containerize it because the infrastructure is not there yet.


In this article we will be learning about an alternative, which is to install your “Containerizatble“ application as a Unix Service using Systemd.



ASSUMPTIONS

  • You have a packaged app, in .jar format.
  • This packaged app is executable.
  • Your target Linux server has java installed.
  • Your target Linux server has systemd installed and enabled. ( this is mostly a standard now with most Linux Distros )



GETTING DOWN TO IT

So then let’s go for it, the main thing here is the Unit & Service definition which will be configured inside a .service file. This .service file should be placed inside the systemd default folder : /etc/systemd/system. Let’s go ahead and create a service file, you can can name it whatever you want, I prefer to give it the same name as my actual app or something close but, to show that you don’t need to keep it the same, I will have the names different. 


Let’s have a look at some of the elements in my case. My app file name is tpserve-1.0.0.jar and I created a .service file named toob-serve.service. These files are in the path /root/toob. Let’s have a look the following image. 


My Linux Service Files



SERVICE FILE

You can either create the .service file directly inside the /etc/systemd/system folder or create it somewhere else then copy it over when you are done. I chose to create is somewhere else then copy it later to the /etc/systemd/system directory. So let’s look at my simple .service file and evaluate what's happening. In my case I have : 


Systemd Service Configuration


For copying purposes : 


[Unit]
Description=TOOB Services
After=syslog.target

[Service]
User=root
ExecStart=/root/toob/tpserve-1.0.0.jar
SuccessExitStatus=143

Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target


[UNIT] 

Description is used to describe the unit that will be executing this service. In my case you can see there I just have “TOOB Services” then we can later see easily in the logs that this unit will be referred to as “TOOB Services” this makes it easy to know which service you are looking at.


After is mainly to start that it must start of the the syslog.target which is part of the core OS processes that kick in when the machine boots up. So it’s just a safer way of making sure we boot up after the more important OS processes.


[SERVICE] 

User tells us more about the user we want to use when running this service. Generally it’s good and more secure to create a specific app user and assign that user to run the app. In my case I am just using root to showcase systemd services in Linux.


ExecStart runs the target service that we want to bootstrap and manage using systemd. In my case I want to execute my .jar app. So you can use this ExecStart to run any app you want to run. It even be a bash script if you like. Anything that’s executable that is. Another important thing to note is that I am using absolute paths because systemd only works with absolute paths.


SuccessExitStatus takes a list of exit status definitions that, when returned by the main service process, will be considered successful termination, for example : 



 SuccessExitStatus=1 2 8 SIGKILL


… ensures that exit codes 1, 2, 8 and the termination signal SIGKILL are considered clean service terminations. Also not really required for a basic Service Config! 


Restart yes we want our service to restart if anything has happened. So this is a nice way of restarting without manual interaction. So it’s cool if if the database service went down for like 3 seconds. 


RestartSec is all about how long we should before we automatically restart. That’s all there is to it. 


[INSTALL] 

WantedBy tells systemd that this service should be started as part of normal system start-up, whether or not a local GUI is active. There’s really no dependency on the OS UI loading. 



INSTALLING SERVICE 

We now have our service configuration done in the .service file and are ready to install it and manage it using systemd. To install it let’s copy our .service to /etc/systemd/system, in my case I am copying my toob-serve.service file : 


Service Installation



SERVICE RELOAD

We have installed this service but systemd does not know about because it does not automatically reload new services, unless may be you restart the OS. So we have to reload / refresh the systemd daemon. To reload or refresh it run : 


 sudo systemctl daemon-reload


Let’s also enable the service one shot : 

 sudo systemctl toob-serve


SERVICE STATUS CHECK

Now that we have installed the service and reloaded, systemd knows about it. We can verify that the service has been installed by running the status check :


 sudo systemctl toob-serve


Systemd Service Status Check



Notice that I didn’t have to specify the .service part this is because systemd now knows about it and can tell that we are referring to that file. You will also notice that we can refer to our service easily in the logs by looking at the description that we defined, “TOOB Services“. So at this stage we know that :

  • Our service is installed

  • Our service is enabled

  • Our service is currently not running, so it’s inactive (dead)

Happiness so far and we can continue with the next steps. 



SERVICE START

Let’s give our system a kick start and check it out : 

 sudo systemctl start toob-serve


SERVICE LOGS CHECK

If you have configured your logs directory inside your app then you can also verify by checking the file wherever you have configured it. Otherwise another case is that you have not configured your app to create a separate log file so then if we haven't configured anything special, our Spring Boot application should write its logs to stdout. Now also keep in mind that our application is now running as a daemon, which means that we aren't able to view the stdout of the application anymore. This is where a utility like JourneyCtl comes in. 


We can check the logs using history check : 

 journalctl -u toob-serve

The command from above will drop us into a view with which we'll be able to view all the logs of the application since it has been deployed, with various options for filtering and more.


Or we can tail live logs, similar to tail -f this can be achieved with : 

We can check the logs using history check : 

 journalctl -u toob-serve -f

Now this command will help us with with info about the last log lines written by our application, it will also monitor the new log lines to come.


JournalCtl Logs



So there you have it. The main thing is now complete. You know how to install your Spring Boot app as a Linux service using systemd. We are not done as yet, let’s look at the last bits and pieces, like how to stop your service or even two birds with one stone where you can run a restart which will stop and start once.


SERVICE STOP

To stop your service you can run : 

 sudo systemctl stop toob-serve


Systemd Service Stop


As simple as that, your service will be stopped and you can spot it by the defined description as shown in the image above.


SERVICE RESTART

Yes, you guessed it, to restart your service you just need to : 

 sudo systemctl restart toob-serve



SERVICE UNINSTALL

So you now want to uninstall your service, at this point you need to use a couple of commands. I prefer doing it in a certain order to make sure that things are done properly. My flow of things would be to first stop the service with the systemd stop command. Then I would disable it, which is the opposite of enabling it like we did in the article earlier, something like : 


 sudo systemctl disable toob-serve


I would then remove the .services file and then perform a services reload like we did earlier and you should have a hint on the console that the service has been removed : 


Systemd Removed Service Log




CONCLUSION

That’s all I have for you on setting up your Spring Boot app as a linux service using systemd. This is not the only one I have learned that some Linux Distros like Ubuntu come with Upstart. And that that systemd is more of a successor to System V. And there are a few more, so we were just learning about systemd. If you are curious about more systemdservice configuration options you can check out this exhaustive list of them here. I hope this helps you out. 


Let me know what you think, let’s also discuss more to learn more. Cheers! 





Thursday, October 14, 2021

Managing Multiple Sotware Development Kits Using Scoop On Windows

 

Background


I think we can see this is part two of the article I wrote, Managing Multiple Software Development Kits Using SDK Man!. Even though one can set up SDK Man on Windows OS, it's a bit more involved compared to setting it up on a Unix based OS out of the box. I mentioned that one would need to work with Cygwin, with the link specified in that article. So please note I am not saying it's impossible, I would just like to share something that I think can be easier on Windows OS. 

So as you know there are various package managers to managing OS packages and SDKs, i.e. Homebrew & Macports for Mac OS, Apt-Get on some Linux Distros. With Winnows OS it is a bit tricky but, I love the idea that there's something that was inspired by Homebrew for Mac OS which is called Scoop

Scoop allows one to manage Tools, Software Development Kits and Packages. Please read up on my previous article I wrote and mentioned above, it will give you an idea on what I am trying to highlight in this article. I this article it's more about Windows OS.



Let's Get Started!

To setup Scoop you will need Powershell 5 and later, I am using Powershell 7. Open up your Powershell terminal to install Scoop, with the following command : 

# Installing Scoop
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')



Scoop Installation


As shown in the image above, an indication that Scoop has been installed successfully. At times you may get an error especially if it's the first time you are using Powershell on that machine. I think some permissions need to be enabled since they are disabled out the box. If you try running the installation command as shown above and you get an error then run the following command to enable Powershell

# Permissions to enable Powershell
Set-ExecutionPolicy RemoteSigned -scope CurrentUser
 
So that's it, you have setup Scoop on your machine! 

 

 

Down To Work

To setup Scoop you will need Powershell 5 and later. Open up your Powershell terminal to install Scoop, with the following command : 
 

  • You have installed Scoop and there are no SDKs or packages installed. So you can check that out by  running :

    # List installed SDKs / Tools / Packages
    scoop list
     

Scoop List


  • Now you want to install something like Gradle. Double check first that you don't have Gradle on your machine :

    # Check Gradle version
    gradle -version
     

Gradle Version



  • You are happy that Gradle is not installed and want to now install it, so because you want the latest version of Gradle you don't specify the version in your command, also noted that depending on your internet speed this may be either quick or slow. Scoop will try to download your Gradle and also work on extracting it. 

    # Check Gradle version
    scoop install gradle


Scoop Gradle Installation


Yay! Gradle installed successfully, notice we are now dealing with version 7.2, which is the latest at the time of this article. 
 
 
  • Now you can run two commands to validate that Gradle is really installed. You can run the same gradle -version command we ran above or run a scoop command to list installed Gradles on your machine.

    # List Installed Gradles On Machine
    scoop list gradle


Scoop List Gradle


  • Say you don't want the latest Gradle because you inherited a project that uses an earlier version 6.9. Then you would do it this way by specifying the version after the "@" symbol.

    # Install Specific Version Of Gradle
    scoop install gradle@6.9

Scoop Install Specific Gradle Version



  • The installation is done and your current version is set to Gradle 7.2 if you run the gradle -version or gradle -v command. At this point you are ready to use Gradle 6.9 so let's change the machine gradle version.

    # Set Specific Gradle Version
    scoop reset gradle@6.9

Scoop Setting Specific Gradle Version



Gradle Version Validation



You can see that your version has now changed. Meaning the "reset" command worked. So it's an easy way of switching across multiple versions of the same tool or SDK.

 
  • You want to run a check on versions intalled on your machine just to be clear.

    # Get Info On Gradle On The Machine
    scoop info gradle


Scoop Info Gradle



  • Now you feel that the latest version is of Gradle ( 7.2 ) is not necessary at this point and you would like to remove it. So at the moment there's a ticket GitHub #3733 logged to add this feature. Something that's much like the "reset" with specified version. At the moment you will have to remove the version manually in your scoop directory. These directories are similar to SDK Man folders, there are minor differences with regards to the structure and folder names and yes, you spotted the folder names in the info command screenshot above. To verify that Gradle 7.2 is gone you can just try to switch to it via Scoop

    # Get Info On Gradle On The Machine
    scoop reset gradle@7.2



    Scoop Reset To Removed Version

 
There you have it. Checking the Gradle version should give you 6.9 now since you recently reset to it and then you removed 7.2. Let's keep a close eye to see if this "uninstall" will be added soon.


 

Above & Beyond

Scoop is a powerful tool that brings that Homebrew feel to Windows OS. There's more you can do with it than manging SDK. You can download add Curl you can add Git plugings like with have with ZShell's Oh My ZSH! for Unix platforms. You can add SSH to you machine for quick SSH Commands on your Powershell window and many more. 
 
Also note that just like in the previous article, you now know where the folders are and can point your IDE to them. I hope that if you are using Windows OS then you will find this tool really helpful. 


Thanks for reading and pleaes leave comments in the section below. Until next time!