Loading a JNI library in scala - scala

I am trying to load a JNI library that is needed by a third-party library that I am using. Since the library only needs to be loaded once, I tried to put the loading in the companion class. I thought this would work:
import com.example.Solver
object MyClass {
System.loadLibrary("jnilibrary")
}
class MyClass {
import MyClass._
implicit val solver = new Solver()
}
This throws an UnsatisfiedLinkError in the Solver class initializer (Solver.<clinit>), apparently because the JNI library is not yet loaded.
Changing the class to
class MyClass {
System.loadLibrary("jnilibrary")
implicit val solver = new Solver()
}
works, so I do have the library in the correct place. Moving the System.loadLibrary to after the solver declaration causes it to fail the same way as when I try to load the library in the companion class.
I theorized that it was trying to resolve the types before running the initializers, so I tried moving the library loading to a base class. I hoped that would mean base class (which loads the library) was fully initialized before the derived class (which loads the class) started to initialize.
object Base {
System.loadLibrary("jnilibrary")
}
class Base {
import Base._
}
class MyClass extends Base {
implicit val solver = new Solver()
}
This also fails.
I can obviously load the library in the class, but that is redundant. It probably does not slow things down much (assuming that loadLibrary will not reload an already loaded library) but is less clean than I would like.
Is there a way to get this to work with the companion object?

As Alex Cohn pointed out, the solution is
class MyClass {
MyClass
implicit val solver = new Solver()
}

Related

Run "static call" in object before class instantiation Scala

I want to run some code in the body of an scala companion object before the class is instantiated. The idea is to register a bunch of object in a Set. Here is the code
trait Delegate {
def make: Ins
}
//EDIT: Changed constructor to private
//class Ins
class Ins private()
//this is the companion object that will be registered with the InsDelegate
object Ins extends Delegate{
//here is the code that do the registration but doesn't run
InsDelegate.register(this)
override def make: Ins = {
println("This is an Ins")
new Ins()
}
}
Here is the code for the InsDelegate
object InsDelegate {
private val objectSet = new mutable.HashSet[Delegate]()
def register(obj: Delegate): Unit = objectSet.add(obj)
def getRegisteredObj: Set[Delegate] = objectSet.toSet
}
When I run this test, nothing gets printed.
object test extends App {
InsDelegate.getRegisteredObj.foreach(_.make)
}
The code that register the companion object doesn't run. I know that unlike java, in order to run the companion object code you need to instantiate the class of the object. How do I accomplish what I am trying to do???
Scala objects are lazy, so they're only constructed when first used. In your example, the test application never creates any instances, so object Ins is never constructed.
Your code should work, but you would need to create an instance of class Ins in your test code:
object test extends App {
val temp = Ins.make()
InsDelegate.getRegisteredObj.foreach(_.make)
}
Incidentally, the convention for functions with side-effects (Delegate.make) is to take parentheses; a version without parentheses indicates that the function has no side-effects, which make clearly has (registering the Ins object, creating a new Ins element).
Another Scala convention is to name factory methods apply, rather than make. If you did that, you could create new Ins class instances using Ins(), instead of Ins.make(). (Ins() is interpreted to be the same as Ins.apply().)
Update: Forgot to mention this: if you want to register Ins without creating any instances first, you will need to reference it in some way. This quickly leads to ugly solutions along the lines of:
object Ins extends Delegate{
InsDelegate.register(this)
// Dummy method to get object to register itself.
def register(): Unit = {}
override def make: Ins = {
println("This is an Ins")
new Ins()
}
}
object InsDelegate {
private val objectSet = new mutable.HashSet[Delegate]()
def register(obj: Delegate): Unit = objectSet.add(obj)
def getRegisteredObj: Set[Delegate] = objectSet.toSet
// Create delegate objects...
Ins.register()
}
However, if we're going to go to that much trouble, we might as well forego registration and add objects in the InsDelegate object:
object Ins extends Delegate{
override def make: Ins = {
println("This is an Ins")
new Ins()
}
}
object InsDelegate {
// Set of delegate objects available. Note: this is public, replaces getRegisteredObj.
val objectSet: Set[Delegate] = Set(Ins)
}
The downside is that Delegate objects no longer register themselves, but that's a blessing in disguise as you can now test delegate creation separately from testing InsDelegate.
I know that unlike java, in order to run the companion object code you need to instantiate the class of the object
Actually, your Java code would have the same result. What you need to do in both cases is to load the class, and instantiating it is just one way to do it. You can also use Class.forName, ClassLoader.loadClass, load any class which uses it somewhere in a signature... One very well-known case is (or was, before JDBC 4.0) loading JDBC drivers.
Unfortunately, in Scala the class you need to load is actually Ins$ (the class of the companion object) and instantiating Ins (or loading it in some other way) isn't necessarily enough.

Scala object that extends Java class

An old trick I used in my previous Java projects was to create e.g. a FileUtils class that offered helper functions for common file operations needed by my project and not covered by e.g. org.apache.commons.io.FileUtils. Therefore my custom FileUtils would extend org.apache.commons.io.FileUtils and offer all their functions as well.
Now I try to do the same in Scala but the apache helper functions are not seen through my FileUtils Scala object, what is wrong here?
import org.apache.commons.io.{ FileUtils => ApacheFileUtils }
object FileUtils extends ApacheFileUtils {
// ... additional helper methods
}
val content = FileUtils.readFileToString(new File("/tmp/whatever.txt"))
here the compiler complains that readFileToString is not a member of my Scala FileUtils but it is of ApacheFileUtils and I extend from it ...
The Scala equivalent of a class with static methods is an object, so in Scala terms, the static components of FileUtils are seen as
object FileUtils {
def readFile(s:String) = ???
...
}
And in Scala, you can't extend an object. This is illegal:
object A
object B extends A // A is not a type
Therefore object FileUtils extends ApacheFileUtils only gives you access to the class-level definitions of ApacheFileUtils (that except for the base Object methods like equals and hashCode, you have none)
You might find that Scala offers more elegant ways of providing extensions. Have a look at the 'pimp up my library' pattern for good starting point.
To apply this pattern to your example:
// definition of your "pimped" methods
import java.io.File
class RichFile(file:File) {
def readToString():String = ???
}
// companion object defines implicit conversion
object RichFile {
implicit def fileToRichFile(f:File):RichFile = new RichFile(f)
}
// Usage
import RichFile._
val content = new File("/tmp/whatever.txt").readToString

Best Practice to Load Class in Scala

I'm new to Scala (and functional programming as well) and I'm developing a plugin based application to learn and study.
I've cretead a trait to be the interface of a plugin. So when my app starts, it will load all the classes that implement this trait.
trait Plugin {
def init(config: Properties)
def execute(parameters: Map[String, Array[String]])
}
In my learning of Scala, I've read that if I want to program in functional way, I should avoid using var. Here's my problem:
The init method will be called after the class being loaded. And probably I will want to use the values from the config parameter in the execute method.
How to store this without using a var? Is there a better practice to do what I want here?
Thanks
There is more to programming in a functional way than just avoiding vars. One key concept is also to prefer immutable objects. In that respect your Plugin API is already breaking functional principles as both methods are only executed for their side-effects. With such an API using vars inside the implementation does not make a difference.
For an immutable plugin instance you could split plugin creation:
trait PluginFactory {
def createPlugin (config: Properties): Plugin
}
trait Plugin {
def execute ...
}
Example:
class MyPluginFactory extends MyPlugin {
def createPlugin (config: Properties): Plugin = {
val someValue = ... // extract from config
new MyPlugin(someValue)
}
}
class MyPlugin (someValue: String) extends Plugin {
def execute ... // using someConfig
}
You can use a val! It's basically the same thing, but the value of a val field cannot be modified later on. If you were using a class, you could write:
For example:
class Plugin(val config: Properties) {
def init {
// do init stuff...
}
def execute = // ...
}
Unfortunately, a trait cannot have class parameters. If you want to have a config field in your trait, you wont be able to set its value immediately, so it will have to be a var.

How do I mock static function (Object function, not class function) in scala

Object A {
def a = { something}
}
// I've import A, but still have error message: not found: type A
val x = mock[A]
You don't. Not only A is not a type or class -- it is an instance -- but it is an instance of a singleton (A.type).
What you do instead is put your methods on a trait, and make the object extend it. Then, you mock the trait instead of mocking the object.
You may find this email thread instructive.
Whilst pure mocking of the object is not possible with any tool yet, the thread above does have a few options for you. All of which involve changing your design to some degree.

If I know the class name of an object, how to get it and invoke its method?

I have a trait, named Init:
package test
trait Init {
def init(): Any
}
There are some classes and an object, extends this trait:
package test
object Config extends Init {
def init() = { loadFromFile(...) }
}
class InitDb extends Init {
def init() = { initdb() }
}
When app has started, I will find all classes and objects which extends Init, and invoke their init method.
package test
object App {
def main(args: Array[String]) {
val classNames: List[String] = findAllNamesOfSubclassOf[Init]
println(classNames) // -> List(test.Config$, test.InitDb)
classNames foreach { name =>
Class.forName(name).newInstance().asInstanceOf[Init].init() // ***
}
}
}
Please note the "*" line. For test.InitDb, it's OK. But for test.Config$, when newInstance(), it throws an exception said we can't access its private method.
My problem is, how to get that object, and run its init method?
There's usually little point to doing this in Scala. Just put some code in the body of any object and it'll be executed when that object is first initialised, saving you the nasty performance hit of pre-initialising everything.
In general though, finding all subclasses of a particular type requires a full classpath scan. There are a few libraries to do this, but one of the more common is Apache's commons-discover
However... This is dynamic code, it uses reflection, and it's really NOT idiomatic. Scala has sharper tools than that, so please don't try and swing the blunt ones with such violence!
I don't totally agree with Kevin. There are some exceptions. For example I wrote a Scala desktop app. I split the core and the modules into two parts. At startup time the core loads all modules into GUI. At that time the core just gets the name of modules, it doesn't need to initialize something. Then I put all module's init code in an init() function. That function will be called when user executes the module.
#Freewind: About reflection in Scala, it's absolutely the same in Java. Just please note that the methods from Java which are used with reflection, are used for Java objects - not Scala. I'm sorry for my English. I mean those methods can not work with Scala object, trait.
For example:
var classLoader = new java.net.URLClassLoader(
Array(new File("module.jar").toURI.toURL),
/*
* need to specify parent, so we have all class instances
* in current context
*/
this.getClass.getClassLoader)
var clazz = classLoader.loadClass("test.InitDb")
if (classOf[Init].isAssignableFrom(clazz))
var an_init = clazz.newInstance.asInstanceOf[Init];
But you can not do it the opposite way:
if (clazz.isAssignableFrom(classOf[Init]))
Because Init is a trait, and Java method isAssignableFrom(Class) doesn't know trait.
I'm not sure if my question is useful for you, but here it is.