Saturday, January 5, 2019

Versioning Scala Classes

Target audience: Beginner
Estimated reading time: 4'

Versioning stands as a prevalent hurdle in the commercial software development landscape. In Java or Scala, the class loader is frequently leveraged to accommodate multiple iterations of a library, executable, or framework.
In this article, we introduce a straightforward versioning approach employing a class loader and a jar file pinpointed through its URL.


Follow me on LinkedIn

Note: The code associated with this article is written using Scala 2.11.8


Simple implementation

A library can be easily versioned by creating multiple jar files, one for each version. Let's select a simple case for each a library is self-contained in a jar file with two versions
  • ArrayIndex1.jar
  • ArrayIndex2.jar
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.net.{URL, URLClassLoader}
import java.io.File
import java.lang.reflect.Method

val cl1 = new URLClassLoader( 
    Array[URL](new File("ArrayIndex1.jar").toURL),   
    Thread.currentThread().getContextClassLoader()
)
 
val cl2 = new URLClassLoader( 
    Array[URL](new File("ArrayIndex2.jar").toURL),  
    Thread.currentThread().getContextClassLoader()
)
  
val compatibleClass: Class[_] = 
    if( version > 0.9) 
       cl1.loadClass("ArrayIndex") 
    else 
       cl2.loadClass("ArrayIndex")

val obj = compatibleClass.newInstance
val methods = compatibleClass.getMethods
println(s"${methods.map( _.getName).mkString(",")}")

The first step consists of loading the two versions of the library through their URL by converting each jar file names to a URL. This feat is accomplished by instantiating the class loaders: In this particular case, the class loader is undefined by its URL with the type URLClassLoader (line 5 & 9). The jar files are loaded within the current thread (line 7 & 11): A more efficient approach would consists of creating a future to load the classes asynchronously.
The class to be used in this case depends on the variable version (line 15). Once the appropriate class is loaded, its instance and method are ready available to the client be invoked.

Thank you for reading this article. For more information ...

References

---------------------------
Patrick Nicolas has over 25 years of experience in software and data engineering, architecture design and end-to-end deployment and support with extensive knowledge in machine learning. 
He has been director of data engineering at Aideo Technologies since 2017 and he is the author of "Scala for Machine Learning" Packt Publishing ISBN 978-1-78712-238-3