Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala/java reflection - `newInstance` throws InstantiationException

object classof extends App {

 trait Config {
    def test(): Unit
  }

  case class Test() extends Config {
    override def test(): Unit = println("test")
  }

  val s = classOf[Test]

  s.newInstance().test()

}

The above code works fine, but when you run it as a scala worksheet, it throws InstantiationException.

Caused by: java.lang.NoSuchMethodException: 
reflection.A$A20$A$A20$Test.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.newInstance(Class.java:412)

I am facing this issue primarily when executing tests. For example

Animal.config.newInstance().test where Animal is an instantiated object and config holds val config: Class[_ <: Config] = classOf[Test].

I don't have sound knowledge on java reflections. Not sure why this is happening.

like image 634
druuu Avatar asked Mar 18 '26 08:03

druuu


1 Answers

I run your example first in IntelliJ idea with a ScalaWorkSheet, and I felt into your same error, my conclusion is that reflection is not well implemented in scala sheet, for me the log is:

(I tried different ways expecting different results):

trait Config {
  def test(): Unit
}

case class Test() extends Config {
  override def test(): Unit = println("test")
}

Test.getClass.getSimpleName

val t: Test = classOf[Test].getConstructors()(0).newInstance().asInstanceOf[Test]

t.test()

java.lang.IllegalArgumentException: wrong number of arguments
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(TestingSO.sc)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(TestingSO.sc:58)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(TestingSO.sc:41)
    at java.lang.reflect.Constructor.newInstance(TestingSO.sc:419)
...

The most rare thing is:

sun.reflect.NativeConstructorAccessorImpl.newInstance0(TestingSO.sc)

That's the name of my scala

Then I made a simple scala class:

class Testing {
}

trait Config {
  def test(): Unit
}

case class Test() extends Config {
  override def test(): Unit = println("test")
}

object Main{
  def main(args: Array[String]): Unit = {
    val s = classOf[Test]

    s.newInstance().test()
  }
}

And works just fine...

Conclusion

Careful with Scala Sheet, some times may be a sh*t haha

like image 162
A Monad is a Monoid Avatar answered Mar 20 '26 20:03

A Monad is a Monoid