what is the input type of classOf - scala

I am wondering what type do I put in place of XXX
def registerClass(cl:XXX) = kryo.register(classOf[cl])
EDIT: For why I want to do this.
I have to register many classes using the above code. I wanted to remove the duplication of calling kyro.register several times, hoping to write code like below:
Seq(com.mypackage.class1,com.mypackage.class2,com.mypackage.class3).foreach(registerClass)
Another question, can I pass String instead? and convert it somehow to a class in registerClass?
Seq("com.mypackage.class1","com.mypackage.class2").foreach(registerClass)
EDIT 2:
When I write com.mypackage.class1, it means any class defined in my source. So if I create a class
package com.mypackage.model
class Dummy(val ids:Seq[Int],val name:String)
I would provide com.mypackage.model.Dummy as input
So,
kryo.register(classOf[com.mypackage.model.Dummy])
Kryo is a Java Serialization library. The signature of the register class is
register(Class type)

You could do it like this:
def registerClass(cl:Class[_]) = kryo.register(cl)
And then call it like this:
registerClass(classOf[Int])

The type parameter to classOf needs to be known at compile time. Without knowing more about what you're trying to do, is there any reason you can't use:
def registerClass(cl:XXX) = kryo.register(cl.getClass)

Related

Pass a class name as string argument to create instance

Is there any possible way to pass a class name/path as String argument to call it in code in runtime?
Im working with some legacy code and i have no way to change it globally. Creating new integration to it suggest me to create new copy of class X, rename it, and pass new instance of Y i have created manually. My mind tells me to pass Y as some kind of argument and never copy X again.
I don't quite understand why you (think that) you need to do what you are trying to do (why copy class in the first place rather than just using it? why pass classname around instead of the class itself?), but, yeah, you can instantiate classes by (fully qualified) name using reflection.
First you get a handle to the class itself:
val clazz = Class.forName("foo.bar.X")
Then, if constructor does not need any arguments, you can just do
val instance = clazz.newInstance
If you need to pass arguments to constructor, it gets a bit more complicated.
val constructor = clazz.getConstructors().find { c =>
c.getParameters().map(_.getParameterizedType) == args.map(_.getClass)
}.getOrElse (throw new Exception("No suitable constructor found")
// or if you know for sure there will be only one constructor,
// could just do clazz.getConnstructors.headOption.getOrElse(...)
val instance = constructor.newInstance(args)
Note though, that the resulting instance is of type Object (AnyRef), so there isn't much you can actually do with it without casting to some interface type your class is known to implement.
Let me just say it again: it is very likely not the best way to achieve what you are actually trying to do. If you open another question and describe your actual problem (not the solution to it you are trying to implement), you might get more helpful answers.

Refer generic class by name

Consider the case that I want to deserialize a JSON string:
def deserialize[T](json)
I can provided class that I want to apply the function explicitly while writing code like
class Person(name: String)
deserialize[Person]("""{ "name": "Jennie" }""")
But, what if I need other class, I have to provide it in my code, compile again. I want my program more flexible, it can take a config file that contains name of which class I want to use. So, when ever require a new class, I just need to write the class definition, build it into another jar file, put it in classpath, then restart the program.
val config = ConfigLoader.load("config.txt")
val className = config.getString("class-to-deserialize")
deserialize[<from className to type>](json)
So, is it possible to do that in scala?
No. But because of type erasure, if you have a function def deserialize[T](json: String), its behavior can't depend on T in the first place and it doesn't matter what you pass as the type parameter. You may just need to add a cast at the end.
What is possible is to write such a function which also accepts an implicit ClassTag or TypeTag parameter, in which case you just need to create the parameter from class/type name, and that's entirely possible: just search for questions about this.

Use `#annotation.varargs` on constructors

I want to declare a class like this:
class StringSetCreate(val s: String*) {
// ...
}
and call that in Java. The problem is that the constructor is of type
public StringSetCreate(scala.collection.Seq)
So in java, you need to fiddle around with the scala sequences which is ugly.
I know that there is the #annotation.varargs annotation which, if used on a method, generates a second method which takes the java varargs.
This annotation does not work on constructors, at least I don't know where to put it. I found a Scala Issue SI-8383 which reports this problem. As far as I understand there is no solution currently. Is this right? Are there any workarounds? Can I somehow define that second constructor by hand?
The bug is already filed as https://issues.scala-lang.org/browse/SI-8383 .
For a workaround I'd recommend using a factory method (perhaps on the companion object), where #varargs should work:
object StringSetCreate {
#varargs def build(s: String*) = new StringSetCreate(s: _*)
}
Then in Java you call StringSetCreate.build("a", "b") rather than using new.

Scala: How to invoke method with type parameter and manifest without knowing the type at compile time?

I have a function with the following signature:
myFunc[T <: AnyRef](arg: T)(implicit m: Manifest[T]) = ???
How can I invoke this function if I do not know the exact type of the argument at the compile time?
For example:
val obj: AnyRef = new Foo() // At compile time obj is defined as AnyRef,
val objClass = obj.getClass // At runtime I can figure out that it is actually Foo
// Now I would need to call `myFunc[Foo](obj.asInstanceOf[Foo])`,
// but how would I do it without putting [Foo] in the square braces?
I would want to write something logically similar to:
myFunc[objClass](obj.asInstanceOf[objClass])
Thank you!
UPDATE:
The question is invalid - As #DaoWen, #Jelmo and #itsbruce correctly pointed, the thing I was trying to do was a complete nonsense! I just overthought the problem severely.
THANK YOU guys! It's too bad I cannot accept all the answers as correct :)
So, the problem was caused by the following situation:
I am using Salat library to serialize the objects to/from BSON/JSON representation.
Salat has an Grater[T] class which is used for both serialization and deserialization.
The method call for deserialization from BSON looks this way:
val foo = grater[Foo].asObject(bson)
Here, the role of type parameter is clear. What I was trying to do then is to use the same Grater to serialize any entity from my domain model. So I wrote:
val json = grater[???].toCompactJSON(obj)
I immediately rushed for reflection and just didn't see an obvious solution lying on the surface. Which is:
grater[Entity].toCompactJSON(obj) // where Entity...
#Salat trait Entity // is a root of the domain model hierarchy
Sometimes things are much easier than we think they are! :)
It appears that while I was writing this answer the author of the question realized that he does not need to resolve Manifests at runtime. However, in my opinion it is perfectly legal problem which I resolved successfully when I was writing Yaml [de]serialization library, so I'm leaving the answer here.
It is possible to do what you want using ClassTags or even TypeTags. I don't know about Manifests because that API is deprecated and I haven't worked with it, but I believe that with manifests it will be easier since they weren't as sophisticated as new Scala reflection. FYI, Manifest's successor is TypeTag.
Suppose you have the following functions:
def useClasstag[T: ClassTag](obj: T) = ...
def useTypetag[T: TypeTag](obj: T) = ...
and you need to call then with obj: AnyRef as an argument while providing either ClassTag or TypeTag for obj.getClass class as the implicit parameter.
ClassTag is the easiest one. You can create ClassTag directly from Class[_] instance:
useClasstag(obj)(ClassTag(obj.getClass))
That's all.
TypeTags are harder. You need to use Scala reflection to obtain one from the object, and then you have to use some internals of Scala reflection.
import scala.reflect.runtime.universe._
import scala.reflect.api
import api.{Universe, TypeCreator}
// Obtain runtime mirror for the class' classloader
val rm = runtimeMirror(obj.getClass.getClassLoader)
// Obtain instance mirror for obj
val im = rm.reflect(obj)
// Get obj's symbol object
val sym = im.symbol
// Get symbol's type signature - that's what you really want!
val tpe = sym.typeSignature
// Now the black magic begins: we create TypeTag manually
// First, make so-called type creator for the type we have just obtained
val tc = new TypeCreator {
def apply[U <: Universe with Singleton](m: api.Mirror[U]) =
if (m eq rm) tpe.asInstanceOf[U # Type]
else throw new IllegalArgumentException(s"Type tag defined in $rm cannot be migrated to other mirrors.")
}
// Next, create a TypeTag using runtime mirror and type creator
val tt = TypeTag[AnyRef](rm, tc)
// Call our method
useTypetag(obj)(tt)
As you can see, this machinery is rather complex. It means that you should use it only if you really need it, and, as others have said, the cases when you really need it are very rare.
This isn't going to work. Think about it this way: You're asking the compiler to create a class Manifest (at compile time!) for a class that isn't known until run time.
However, I have the feeling you're approaching the problem the wrong way. Is AnyRef really the most you know about the type of Foo at compile time? If that's the case, how can you do anything useful with it? (You won't be able to call any methods on it except the few that are defined for AnyRef.)
It's not clear what you are trying to achieve and a little more context could be helpful. Anyway, here's my 2 cents.
Using Manifest will not help you here because the type parameter needs to be known at compile time. What I propose is something along these lines:
def myFunc[T](arg: AnyRef, klass: Class[T]) = {
val obj: T = klass.cast(arg)
//do something with obj... but what?
}
And you could call it like this:
myFunc(obj, Foo.class)
Note that I don't see how you can do something useful inside myFunc. At compile time, you cannot call any method on a object of type T beside the methods available for AnyRef. And if you want to use reflection to manipulate the argument of myFunc, then there is no need to cast it to a specific type.
This is the wrong way to work with a type-safe OO language. If you need to do this, your design is wrong.
myFunc[T <: AnyRef](arg: T)(implicit m: Manifest[T]) = ???
This is, of course, useless, as you have probably discovered. What kind of meaningful function can you call on an object which might be anything? You can't make any direct reference to its properties or methods.
I would want to write something logically similar to:
myFunc[objClass](obj.asInstanceOf[objClass])
Why? This kind of thing is generally only necessary for very specialised cases. Are you writing a framework that will use dependency injection, for example? If you're not doing some highly technical extension of Scala's capabilities, this should not be necessary.
I bet you know something more about the class, since you say you don't know the exact type. One big part of the way class-based OO works is that if you want to do something to a general type of objects (including all its subtypes), you put that behaviour into a method belonging to the class. Let subclasses override it if they need to.
Frankly, the way to do what you are attempting is to invoke the function in a context where you know enough about the type.

Scala v 2.10: How to get a new instance of a class (object) starting from the class name

I have tens of JSON fragments to parse, and for each one I need to get an instance of the right parser. My idea was to create a config file where to write the name of the class to instantiate for each parser (a kind of map url -> parser) . Getting back to your solution, I cannot call the method I implemented in each parser if I have a pointer to Any. I suppose this is a very common problem with a well-set solution, but I have no idea what the best practices could be.
I really have no experience with Java, Reflection, Class Loading and all that stuff. So,
can anyone write for me the body of the method below? I need to get an instance of a class passed as String (no arguments needed for the constructor, at least so far...)
def createInstance(clazzName: String) = {
// get the Class for the given clazzName, e.g. "net.my.BeautifulClazz"
// instantiate an object and return it
}
Thanks, as usual...
There is a very simple answer:
scala> def createInstance(clazzName: String) = Class.forName(clazzName).newInstance
createInstance: (clazzName: String)Any
scala> createInstance("java.lang.String")
res0: Any = ""
If it works for you, everything is fine. If it don't, we have to look into your class loader. This is usually the point when things will get dirty.
Depending in what you want to do, look into:
The cake pattern, if you want to combine your classes during compile time
OSGi when you want to build a plugin infrastructure (look here for a very simple example)
Google guice, if you really need dependency injection (e.g. when mixing Scala and Java code) and the cake pattern does not work for you