To make debug-time introspection into classes easy, I'd like to make a generic toString method in the base class for the objects in question. As it's not performance critical code, I'd like to use Reflection to print out field name/value pairs ("x=1, y=2" etc).
Is there an easy way to do this? I tried several potential solutions, and ran up against security access issues, etc.
To be clear, the toString() method in the base class should reflectively iterate over public vals in any classes that inherit from it, as well as any traits that are mixed in.
Example:
override def toString() = {
getClass().getDeclaredFields().map { field:Field =>
field.setAccessible(true)
field.getName() + ": " + field.getType() + " = " + field.get(this).toString()
}.deepMkString("\n")
}
Uses Java Reflection API, so don't forget to import java.lang.reflect._
Also, you may need to catch IllegalAccessException on the field.get(this) calls in some scenarios, but this is just meant as a starting point.
Are you aware the Scala case classes get these compiler-generated methods:
toString(): String
equals(other: Any): Boolean
hashCode: Int
They also get companion objects for "new-less" constructors and pattern matching.
The generated toString() is pretty much like the one you describe.
import util._ // For Scala 2.8.x NameTransformer
import scala.tools.nsc.util._ // For Scala 2.7.x NameTransformer
/**
* Repeatedly run `f` until it returns None, and assemble results in a Stream.
*/
def unfold[A](a: A, f: A => Option[A]): Stream[A] = {
Stream.cons(a, f(a).map(unfold(_, f)).getOrElse(Stream.empty))
}
def get[T](f: java.lang.reflect.Field, a: AnyRef): T = {
f.setAccessible(true)
f.get(a).asInstanceOf[T]
}
/**
* #return None if t is null, Some(t) otherwise.
*/
def optNull[T <: AnyRef](t: T): Option[T] = if (t eq null) None else Some(t)
/**
* #return a Stream starting with the class c and continuing with its superclasses.
*/
def classAndSuperClasses(c: Class[_]): Stream[Class[_]] = unfold[Class[_]](c, (c) => optNull(c.getSuperclass))
def showReflect(a: AnyRef): String = {
val fields = classAndSuperClasses(a.getClass).flatMap(_.getDeclaredFields).filter(!_.isSynthetic)
fields.map((f) => NameTransformer.decode(f.getName) + "=" + get(f, a)).mkString(",")
}
// TEST
trait T {
val t1 = "t1"
}
class Base(val foo: String, val ?? : Int) {
}
class Derived(val d: Int) extends Base("foo", 1) with T
assert(showReflect(new Derived(1)) == "t1=t1,d=1,??=1,foo=foo")
Scala doesn't generate any public fields. They're all going to be private. The accessor methods are what will be public, reflect upon those. Given a class like:
class A {
var x = 5
}
The generated bytecode looks like:
private int x;
public void x_$eq(int);
public int x();
Related
I have a ZIO that looks like this:
ZIO[transactor.Transactor[Task], Serializable, String]
and I need to assert the String, that is in that ZIO with another plain String.
So my question is:
How can I assert the plain String, with the String in the ZIO, or
can I lift the String into that same ZIO, to assert it with this one:
ZIO[transactor.Transactor[Task], Serializable, String]
I´m working with ZIO-Test as my testing framework.
I got this based on the rock the jvm zio course. Important things are highlighted in the comments
package com.w33b
import zio.test._
import zio._
object ZIOAssert extends ZIOSpecDefault {
class ATask
abstract class Transact[ATask] {
def get(): String
def put(ATask: ATask): ATask
}
// This is the mock service that we will use to create a ZLayer
val mockTransact = ZIO.succeed(new Transact[ATask] {
override def get(): String = "hello"
override def put(aTask: ATask): ATask = new ATask
})
// This is the method we are testing and we need a service (Zlayer) associated with it.
// We then use the service to invoke a method to get our return value
def methodUnderTest: ZIO[Transact[ATask], Serializable, String] = {
for {
trans <- ZIO.service[Transact[ATask]]
tVal = trans.get()
} yield tVal
}
def spec = suite("Let's test that ZIO lift")(
test("lets test that lift") {
assertZIO(methodUnderTest)(Assertion.equalTo("hello"))
}
).provide(ZLayer.fromZIO(mockTransact)) // Important to provide the layer or we can't test
}
with ZIO 2.x
val spec = suite("tetst")(
test("whatever"){
val effect: ZIO[transactor.Transactor[Task], Serializable, String] = ???
val expected: String = ???
for {
value <- effect
} yield assertTrue(value == expected)
}
)
In general, you just create here a ZIO with the assertion in the success channel.
I use an external library which return some List<?>.
I need to check if each object of this list is an Object of the JDK (String, int, Integer...).
Is this a proper solution?
List<?> list = externalLibrary.search(...);
for(clazz : list) {
if (clazz.getPackage().getName().startsWith("java.lang"))
// do something different
}
Is there a better one?
Depending on your definition of "object of the JDK" -- which could get quite fuzzy around the edges -- no, this isn't going to do it. The java.lang package is only a tiny part of all the classes included in the JDK.
You might check whether each object was loaded by the same ClassLoader that loaded java.lang.String -- i.e.,
if (theObject.getClass().getClassLoader() == "".getClass().getClassLoader()) ...
In general, a different ClassLoader will be used for system classes vs. application classes.
It is probably OK, just you have to check the following packages:
java
javax
com.sun
sun
probably others...
We use the below class to check if the classes belongs to JDK
public class JDKClass {
private static Set<String> CS = new HashSet<String>();
static {
try {
File file = new File(System.getProperty("java.home"),
"lib/classlist");
BufferedReader r = new BufferedReader(new FileReader(file));
String l;
while (true) {
l = r.readLine();
if (l == null) {
break;
} else {
CS.add(l.replace('/', '.'));
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static boolean contains(String o) {
return CS.contains(o) || o.startsWith("java") || o.startsWith("com.sun")
|| o.startsWith("sun") || o.startsWith("oracle")
|| o.startsWith("org.xml") || o.startsWith("com.oracle");
}
private JDKClass() {
}
}
You can use ClassLoader.getSystemResources and then check from what jar is the class loaded (f.g. if it comes from rt.jar).
You will get URL's such as:
jar:file:/C:/Users/user/.m2/repository/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.jar!/org/slf4j/impl/StaticLoggerBinder.class
Example code taken from SLF4j:
private static String STATIC_LOGGER_BINDER_PATH =
"org/slf4j/impl/StaticLoggerBinder.class";
private static void singleImplementationSanityCheck() {
try {
ClassLoader loggerFactoryClassLoader = LoggerFactory.class
.getClassLoader();
Enumeration paths;
if (loggerFactoryClassLoader == null) {
paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
} else {
paths = loggerFactoryClassLoader
.getResources(STATIC_LOGGER_BINDER_PATH);
}
List implementationList = new ArrayList();
while (paths.hasMoreElements()) {
URL path = (URL) paths.nextElement();
implementationList.add(path);
}
....
}
Personally I like class loader base answer. But it will return true also on StringBuilder. If you want to more narrow definition that is only "built-in" types, you can try to evaluate whether this is primitive type (such as int) or wrapper type (such as Integer) or String. You can write something like this:
import java.util.Map;
import java.util.TreeMap;
public class Utils {
private static Map<String, Class<?>> SUBST_MAP = new TreeMap<String, Class<?>>();
private static Map<String, Class<?>> SIMPLE_MAP = new TreeMap<String, Class<?>>();
static {
SUBST_MAP.put(Byte.class.getName(), Byte.TYPE);
SUBST_MAP.put(Short.class.getName(), Short.TYPE);
SUBST_MAP.put(Integer.class.getName(), Integer.TYPE);
SUBST_MAP.put(Long.class.getName(), Long.TYPE);
SUBST_MAP.put(Float.class.getName(), Float.TYPE);
SUBST_MAP.put(Double.class.getName(), Double.TYPE);
SUBST_MAP.put(Boolean.class.getName(), Boolean.TYPE);
SUBST_MAP.put(Character.class.getName(), Character.TYPE);
SIMPLE_MAP.put(String.class.getName(), Boolean.TRUE);
}
/**
* Gets the the class type of the types of the argument.
*
* if substPrimitiveWrapper is true,
* then if there is argument, that represent primitive type wrapper (such as Integer),
* then it will be substituted to primitive type (such as int).
* else no substitution will be done.
*
* #param arg object.
* #param substPrimitiveWrapper - wheteher to do primitive type substitution.
* #retrun class type.
*/
public static Class<?> getClassType(Object arg, boolean substPrimitiveWrapper){
Class<?> classType = null;
String className = null;
Class<?> substClass = null;
if(arg != null ){
//making default classType
classType = arg.getClass();
if(substPrimitiveWrapper){
className = classType.getName();
substClass = (Class<?>)SUBST_MAP.get(className);
if(substClass != null){
classType = substClass;
}
}
}
return classType;
}
/**
* This method consider JDK type any primitive type, wrapper class or String.
*
*
* #param arg object
* #return where arg is JDK type or now.
*/
public static boolean isJDKClass(Object arg){
Class<?> classType = getClassType(arg, true);
boolean isJDKClass = false;
if(classType!=null){
//if(String.class.equals(classType)){
// isJDKClass = true; //this is String, note that String is final
//}
assert classType!=null;
String className = classType.getName();
Boolean isFound = (Boolean)SIMPLE_MAP.get(className);
if(Boolean.TRUE.equals(isFound)){
isJDKClass = true; //this is predefined class
}
boolean isPrimitiveType = classType.isPrimitive();
if(isPrimitiveType){
isJDKClass = true; //this is primitive type or wrapper class
}
}
return isJDKClass;
}
}
You can also optionally add support for such classes like java.math.BigDecimal, java.util.Date, java.sql.Timestamp. Note, however, that they are not final, so I assumed that if somebody extended them even in the trivial way, it will not be considered as JDK class.
I think an easier solution is to thing of the problem this way:
write a method to identify all classes that are defined by you. In most cases, all user defined classes follow a pattern like com.something.something. Then if they do not belong to com.something.something, it is a JDK class
Is there any way to implement specialized IComparer for the base class type so a child class could still use it for sorting in speciliazed collections?
Example
public class A
{
public int X;
}
public class B:A
{
public int Y;
}
public AComparer:IComparer<A>
{
int Compare(A p1, A p2)
{
//...
}
}
so following code will work:
List<A> aList = new List<A>();
aList.Sort(new AComparer());
List<B> bList = new List<B>();
bList.Sort(new AComparer()); // <- this line fails due to type cast issues
How to approach this issue to have both - inheritance of sorting and specialized collections (and do not copy IComparer classes for each of children classes?
Thanks in advance!
Firstly, note that this is fixed in .NET 4 via generic contravariance - your code would simply work. EDIT: As noted in comments, generic variance was first supported in CLR v2, but various interfaces and delegates only became covariant or contravariant in .NET 4.
However, in .NET 2 it's still fairly easy to create a converter:
public class ComparerConverter<TBase, TChild> : IComparer<TChild>
where TChild : TBase
{
private readonly IComparer<TBase> comparer;
public ComparerConverter(IComparer<TBase> comparer)
{
this.comparer = comparer;
}
public int Compare(TChild x, TChild y)
{
return comparer.Compare(x, y);
}
}
You can then use:
List<B> bList = new List<B>();
IComparer<B> bComparer = new ComparerConverter<A, B>(new AComparer());
bList.Sort(bComparer);
EDIT: There's nothing you can do without changing the way of calling it at all. You could potentially make your AComparer generic though:
public class AComparer<T> : IComparer<T> where T : A
{
int Compare(T p1, T p2)
{
// You can still access members of A here
}
}
Then you could use:
bList.Sort(new AComparer<B>());
Of course, this means making all your comparer implementations generic, and it's somewhat ugly IMO.
Considering the following Scala snippet:
case class Foo(v1: String, v2: Int, v3: Any)
def inspect(p: Product) =
(0 until p.productArity).foreach(i => println(p.productElement(i)))
inspect(Foo("Moin", 77, null))
Does the invocation of inspect() here means that reflection is used (in whatever way)?
I'd like to somehow be able to access the fields of a case-class without having to explicitly refer to them, e.g. by foo.v1 and I'd favour a solution that does not require reflection since I expect that it entails some overhead.
No reflection will be used for the productElement. It's a compiler trick. Adding case before a class doesn't just create a companion object (with apply method and so on, see http://www.scala-lang.org/node/258), it also extends the class from the trait Product. The compiler creates implementations of the abstract methods productArity and productElement.
The output of scalac -print Foo.scala shows it:
... case class Foo extends java.lang.Object with ScalaObject with Product {
...
override def productArity(): Int = 3;
override def productElement(x$1: Int): java.lang.Object = {
<synthetic> val temp6: Int = x$1;
(temp6: Int) match {
case 0 => {
Foo.this.v1()
}
case 1 => {
scala.Int.box(Foo.this.v2())
}
case 2 => {
Foo.this.v3()
}
case _ => {
throw new java.lang.IndexOutOfBoundsException(scala.Int.box(x$1).toString())
}
}
};
...
}
If you want to access to the fields without reflection, you can use the method productElement from the trait Product
scala> case class Foo(v1: String, v2: Int, v3: Any)
defined class Foo
scala> val bar = Foo("Moin", 77, null)
bar: Foo = Foo(Moin,77,null)
scala> bar.productElement(0)
res4: Any = Moin
scala> bar.productElement(1)
res5: Any = 77
scala> bar.productElement(2)
res6: Any = null
In Scala, what's the best way to dynamically instantiate an object and invoke a method using reflection?
I would like to do Scala-equivalent of the following Java code:
Class class = Class.forName("Foo");
Object foo = class.newInstance();
Method method = class.getMethod("hello", null);
method.invoke(foo, null);
In the above code, both the class name and the method name are passed in dynamically. The above Java mechanism could probably be used for Foo and hello(), but the Scala types don't match one-to-one with that of Java. For example, a class may be declared implicitly for a singleton object. Also Scala method allows all sorts of symbols to be its name. Both are resolved by name mangling. See Interop Between Java and Scala.
Another issue seems to be the matching of parameters by resolving overloads and autoboxing, described in Reflection from Scala - Heaven and Hell.
There is an easier way to invoke method reflectively without resorting to calling Java reflection methods: use Structural Typing.
Just cast the object reference to a Structural Type which has the necessary method signature then call the method: no reflection necessary (of course, Scala is doing reflection underneath but we don't need to do it).
class Foo {
def hello(name: String): String = "Hello there, %s".format(name)
}
object FooMain {
def main(args: Array[String]) {
val foo = Class.forName("Foo").newInstance.asInstanceOf[{ def hello(name: String): String }]
println(foo.hello("Walter")) // prints "Hello there, Walter"
}
}
The answers by VonC and Walter Chang are quite good, so I'll just complement with one Scala 2.8 Experimental feature. In fact, I won't even bother to dress it up, I'll just copy the scaladoc.
object Invocation
extends AnyRef
A more convenient syntax for reflective
invocation. Example usage:
class Obj { private def foo(x: Int, y: String): Long = x + y.length }
You can call it reflectively one of
two ways:
import scala.reflect.Invocation._
(new Obj) o 'foo(5, "abc") // the 'o' method returns Any
val x: Long = (new Obj) oo 'foo(5, "abc") // the 'oo' method casts to expected type.
If you call the oo
method and do not give the type
inferencer enough help, it will most
likely infer Nothing, which will
result in a ClassCastException.
Author Paul Phillips
The instanciation part could use the Manifest: see this SO answer
experimental feature in Scala called manifests which are a way to get around a Java constraint regarding type erasure
class Test[T](implicit m : Manifest[T]) {
val testVal = m.erasure.newInstance().asInstanceOf[T]
}
With this version you still write
class Foo
val t = new Test[Foo]
However, if there's no no-arg constructor available you get a runtime exception instead of a static type error
scala> new Test[Set[String]]
java.lang.InstantiationException: scala.collection.immutable.Set
at java.lang.Class.newInstance0(Class.java:340)
So the true type safe solution would be using a Factory.
Note: as stated in this thread, Manifest is here to stay, but is for now "only use is to give access to the erasure of the type as a Class instance."
The only thing manifests give you now is the erasure of the static type of a parameter at the call site (contrary to getClass which give you the erasure of the dynamic type).
You can then get a method through reflection:
classOf[ClassName].getMethod("main", classOf[Array[String]])
and invoke it
scala> class A {
| def foo_=(foo: Boolean) = "bar"
| }
defined class A
scala>val a = new A
a: A = A#1f854bd
scala>a.getClass.getMethod(decode("foo_="),
classOf[Boolean]).invoke(a, java.lang.Boolean.TRUE)
res15: java.lang.Object = bar
In case you need to invoke a method of a Scala 2.10 object (not class) and you have the names of the method and object as Strings, you can do it like this:
package com.example.mytest
import scala.reflect.runtime.universe
class MyTest
object MyTest {
def target(i: Int) = println(i)
def invoker(objectName: String, methodName: String, arg: Any) = {
val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader)
val moduleSymbol = runtimeMirror.moduleSymbol(
Class.forName(objectName))
val targetMethod = moduleSymbol.typeSignature
.members
.filter(x => x.isMethod && x.name.toString == methodName)
.head
.asMethod
runtimeMirror.reflect(runtimeMirror.reflectModule(moduleSymbol).instance)
.reflectMethod(targetMethod)(arg)
}
def main(args: Array[String]): Unit = {
invoker("com.example.mytest.MyTest$", "target", 5)
}
}
This prints 5 to standard output.
Further details in Scala Documentation.
Working up from #nedim's answer, here is a basis for a full answer,
main difference being here below we instantiate naive classes. This code does not handle the case of multiple constructors, and is by no means a full answer.
import scala.reflect.runtime.universe
case class Case(foo: Int) {
println("Case Case Instantiated")
}
class Class {
println("Class Instantiated")
}
object Inst {
def apply(className: String, arg: Any) = {
val runtimeMirror: universe.Mirror = universe.runtimeMirror(getClass.getClassLoader)
val classSymbol: universe.ClassSymbol = runtimeMirror.classSymbol(Class.forName(className))
val classMirror: universe.ClassMirror = runtimeMirror.reflectClass(classSymbol)
if (classSymbol.companion.toString() == "<none>") // TODO: use nicer method "hiding" in the api?
{
println(s"Info: $className has no companion object")
val constructors = classSymbol.typeSignature.members.filter(_.isConstructor).toList
if (constructors.length > 1) {
println(s"Info: $className has several constructors")
}
else {
val constructorMirror = classMirror.reflectConstructor(constructors.head.asMethod) // we can reuse it
constructorMirror()
}
}
else
{
val companionSymbol = classSymbol.companion
println(s"Info: $className has companion object $companionSymbol")
// TBD
}
}
}
object app extends App {
val c = Inst("Class", "")
val cc = Inst("Case", "")
}
Here is a build.sbt that would compile it:
lazy val reflection = (project in file("."))
.settings(
scalaVersion := "2.11.7",
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-compiler" % scalaVersion.value % "provided",
"org.scala-lang" % "scala-library" % scalaVersion.value % "provided"
)
)