SDKMAN! is a very useful tool to manage versions of so-called software development kits. There are a lot of SDKs supported by SDKMAN!: Java, Groovy, Kotlin, Scala, Gradle, Maven, Leiningen, Micronaut, Grails, Vert.x, JBake, AsciidoctorJ and more. When we look at Java we can use a simple install java <version>
command from the command-line to install a version of Java on our computer. SDKMAN! will take care of downloading the Java version and setting all the correct system variables to use that Java version. With the use
command we can switch between version in the current shell we are working in. But we can even automatically switch to a specific installed Java version when we enter a directory. This is very useful when we have to work on multiple projects on our computer and each project requires a specific Java version to be used.
To support automatic switching of a Java version we must first run the env init
command in the directory of our project. This creates a new file .sdkmanrc
in the directory. The file contains the Java version that was active when we invoked the env init
command. It is a text file so we can change the Java version in the file, or regenerate the file by running the env init
command again, but with a different active Java version.
Continue reading →
To find the maximum or minimum value for numeric values we can use the max
and min
function. The functions accept one or more numeric arguments and the value that is maximum or minimum is returned. If the numbers are already in a sequence we can use apply max
or apply min
. If the values are not numbers we can use the max-key
or min-key
functions. These functions take as first argument a function that returns a number. So we can get the value that has the maximum or minimum return value for the function we pass as first argument.
In the next exmaple code we use the max
, min
, max-key
and min-key
functions:
Continue reading →
In a previous post we learned how to replace a file in an archive with Gradle.
In this blog post we use Maven to achieve the same goal.
With Maven we first have to extract the contents of the archive and then assemble a new archive where we use a file replacement to replace an original file from the archive.
To extract the contents we use the task unzip
with the maven-antrun-plugin.
To create a new archive we use the maven-assembly-plugin.
The destination directory of the extracted contents is the input fileset for the assembly definition together with the files we want to overwrite.
The end result is a new archive with replaced files.
In the following pom.xml
we configure the maven-antrun-plugin and maven-assembly-plugin:
Continue reading →
Sometimes we might need to replace one or more files in an existing archive file. The archive file could be a zip, jar, war or other archive. Without Gradle we would unpack the archive file, copy our new file into the destination directory of the unpacked archive and archive the directory again. To achieve this with Gradle we can simply create a single task of type Zip
. To get the content of the original archive we can use the project.zipTree
method. We leave out the file we want to replace and define the new file as replacement. As extra safeguard we can let the tsak fail if duplicate files are in the archive, because of our replacement.
The following code shows an example of a task to replace a README
file in an archive sample.zip
using Groovy and Kotlin DSL. First the Groovy DSL:
Continue reading →
In Clojure we can take or drop elements from a collection based on a predicate using the functions take-while
and drop-while
. With the function take-while
we take elements as long as the predicate returns true
. Once the predicate returns false
the function stops returning elements. Using the function drop-while
we skip elements in the collection if the predicate returns true
. If the predicate returns false
the remaining elements in the collection are returned.
In the following example we use take-while
and drop-while
with different collection types:
Continue reading →
The map data structure is used a lot in Clojure. When we want to use Java objects in our Clojure code we can convert the Java object to a map with the bean
function. This function will use reflection to get all the properties of the Java object and converts each property with the property value to a key with value in the resulting map. The bean
function will not recursively convert nested objects to a map, only the top-level properties are turned into key value pairs.
We see several examples of using the bean
function in the following code snippet:
Continue reading →
It is very easy to work with Java classes in Clojure. If we want to create a new object based on a Java class and invoke methods to initialize the object directly we can use the doto
macro. The first argument is an expression to create a new object and the rest of the arguments are functions to invoke methods on the newly created object. The object returned from the first argument is passed as first argument to the method invocations. The doto
function returns the object that is created with the first argument.
In the following example code we use the doto
function in several cases:
Continue reading →
The clojure.string
namespace contains a lot of useful functions to work with string values. The escape
function can be used to replace characters in a string with another character. The function accepts as first argument the string value and the second argument is a map. The map has characters as key that need to be replaced followed by the value it is replaced with. For example the map {\a 1 \b 2}
replaces the character a
with 1
and the character b
with 2
.
In the following example code we use the escape
function in several cases:
Continue reading →
When we use a function as argument for the map
function that returns a collection we would get nested collections. If we want to turn the result into a single collection we can concatenate the elements from the collections by applying the concat
function, but we can do this directly with the function mapcat
. The function mapcat
takes as first argument a function (that returns a collection) and one or more collections as next arguments.
In the following examples we see several uses of mapcat
:
Continue reading →
When we are working with sets in Clojure we can use some useful functions from the clojure.set
namespace. In a previous post we learned how we can get the difference of several sets. To get the union of several input sets we use the union
function of the clojure.set
namespace. The function returns a new set that is the union of unique elements from the input sets. A nil
value is ignored by the union
function.
In the following example code we use union
:
Continue reading →
If we want to get the values from a set that are not part of one or more other sets we must use the difference
function in the clojure.set
namespace. The function returns a set with all values from the first set that are different from values in other sets.
In the following example we use the difference
with several sets:
Continue reading →