Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Scala implicit class in Java

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.

like image 793
Shankar Avatar asked Apr 08 '16 10:04

Shankar


People also ask

How do Scala implicit classes work?

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.

What is implicit class in Java?

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.

What is implicit object in Scala?

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.

What is implicit conversion in Scala?

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.


2 Answers

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");
like image 130
Łukasz Avatar answered Oct 13 '22 01:10

Łukasz


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.

like image 39
Jasper-M Avatar answered Oct 13 '22 01:10

Jasper-M