I have a Scala Implicit class from RecordService API, which i wanted to use in Java file.
package object spark {
implicit class RecordServiceContext(ctx: SparkContext) {
def recordServiceTextFile(path: String) : RDD[String] = {
new RecordServiceRDD(ctx).setPath(path)
.map(v => v(0).asInstanceOf[Text].toString)
}
}
}
Now i am trying to import this in a Java file using below import.
import com.cloudera.recordservice.spark.*;
But i am not able to use recordServiceTextFile("path") from sparkContext.
In Scala the import is little different and its working.
Scala 2.10 introduced a new feature called implicit classes. An implicit class is a class marked with the implicit keyword. This keyword makes the class's primary constructor available for implicit conversions when the class is in scope. Implicit classes were proposed in SIP-13.
The implicit parameter in Java is the object that the method belongs to. It's passed by specifying the reference or variable of the object before the name of the method. An implicit parameter is opposite to an explicit parameter, which is passed when specifying the parameter in the parenthesis of a method call.
In Scala, objects and values are treated mostly the same. An implicit object can be thought of as a value which is found in the process of looking up an implicit of its type.
Implicit conversions in Scala are the set of methods that are apply when an object of wrong type is used. It allows the compiler to automatically convert of one type to another. Implicit conversions are applied in two conditions: First, if an expression of type A and S does not match to the expected expression type B.
Here is simple definition of implicit class in package object
package object spark {
implicit class Ext(param: Int) {
def a = param + 1
}
}
and here is how you can use it from java
public class Test {
public static void main(String[] args) {
spark.package$.MODULE$.Ext(123).a();
}
}
so you can basically use RecordServiceContext
as a method that wraps your SparkContext
and adds an extra method that you can call. That is optimization for implicit classes.
That would be something like this:
SparkContext c = ???
RDD<String> rdd = com.cloudera.recordservice.spark.package$.MODULE$.RecordServiceContext(c)
.recordServiceTextFile("asdf");
A package object spark
is compiled to a class package
in the package spark
. The implicit class RecordServiceContext
will get compiled to a static method RecordServiceContext
(that's scala's implicit def) in package
and a class package$RecordServiceContext
.
So the following code should do it:
import com.cloudera.recordservice.spark.*;
//some code
RDD<String> rdd = package.RecordServiceContext(myContext).recordServiceTextFile(pathToFile);
//some code
But package
is probably a reserved keyword, and Java has no way of escaping them as far as I know. So you'll have to do some reflection to invoke the RecordServiceContext
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With