2

After adding the following method to map case classes to Map or js.Dictionary - and I've tried now five or six variants of the following - my code compiles fine and without warnings, but then hits errors at the fastOptJS sjs linking stage.

The method

  def ccToMap(cc: AnyRef) =
    (Map[String, Any]() /: cc.getClass.getDeclaredFields) {
      (a, f) =>
        f.setAccessible(true)
        a + (f.getName -> f.get(cc))
    }

Note that all the variants I have tried do the same thing in a slightly different manner.

The error

 [info] Fast optimizing /Users/justin/Desktop/arete/jt/client/target/scala-2.11/client-fastopt.js
 [error] Referring to non-existent class java.lang.reflect.Field
 [error]   called from com.jshin47.jtdc.client.module.visualization.DiodeStateVizC$.ccToMap(java.lang.Object)scala.collection.immutable.Map
 [error]   called from com.jshin47.jtdc.client.module.visualization.DiodeStateVizC$.<init>()
 [error]   called from com.jshin47.jtdc.client.module.landing.LandingLocC$$anonfun$2.apply(japgolly.scalajs.react.extra.router.RouterCtl)japgolly.scalajs.react.ReactElement
 [error]   called from com.jshin47.jtdc.client.module.landing.LandingLocC$$anonfun$2.apply(java.lang.Object)java.lang.Object
 [error]   called from scala.collection.LinearSeqOptimized$class.foreach(scala.collection.LinearSeqOptimized,scala.Function1)scala.Unit
 [error]   called from scala.collection.mutable.MutableList.foreach(scala.Function1)scala.Unit
 [error]   called from scala.collection.TraversableLike$WithFilter.map(scala.Function1,scala.collection.generic.CanBuildFrom)java.lang.Object
 [error]   called from scala.collection.immutable.Stream$StreamWithFilter.map(scala.Function1,scala.collection.generic.CanBuildFrom)java.lang.Object
 [error]   called from org.scalajs.testinterface.internal.Slave.org$scalajs$testinterface$internal$Slave$$execute(scala.scalajs.js.Dynamic)scala.Unit
 [error]   called from org.scalajs.testinterface.internal.Slave.handleMsgImpl(java.lang.String,scala.Function0)scala.Unit
 [error]   called from org.scalajs.testinterface.internal.BridgeBase.handleMsg(java.lang.String)scala.Unit
 [error]   called from org.scalajs.testinterface.internal.BridgeBase.$$anonfun$1(java.lang.String)scala.Unit
 [error]   called from org.scalajs.testinterface.internal.BridgeBase.init()scala.Unit
 [error]   called from org.scalajs.testinterface.internal.BridgeBase.$$js$exported$meth$init()java.lang.Object
 [error]   called from org.scalajs.testinterface.internal.BridgeBase.init
 [error]   exported to JavaScript with @JSExport
 [error] involving instantiated classes:
 [error]   com.jshin47.jtdc.client.module.visualization.DiodeStateVizC$
 [error]   com.jshin47.jtdc.client.module.landing.LandingLocC$$anonfun$2
 [error]   scala.collection.mutable.Queue
 [error]   scala.collection.mutable.MutableList
 [error]   scala.collection.TraversableLike$WithFilter
 [error]   scala.collection.immutable.Stream$StreamWithFilter
 [error]   org.scalajs.testinterface.internal.Slave
 [error]   org.scalajs.testinterface.internal.Master
 [error] Referring to non-existent method java.lang.Class.getDeclaredFields()     [java.lang.reflect.Field
 [error]   called from com.jshin47.jtdc.client.module.visualization.DiodeStateVizC$.ccToMap(java.lang.Object)scala.collection.immutable.Map
 [error]   called from com.jshin47.jtdc.client.module.visualization.DiodeStateVizC$.<init>()
 [error]   called from com.jshin47.jtdc.client.module.landing.LandingLocC$$anonfun$2.apply(japgolly.scalajs.react.extra.router.RouterCtl)japgolly.scalajs.react.ReactElement
 [error]   called from com.jshin47.jtdc.client.module.landing.LandingLocC$$anonfun$2.apply(java.lang.Object)java.lang.Object
 [error]   called from scala.collection.LinearSeqOptimized$class.foreach(scala.collection.LinearSeqOptimized,scala.Function1)scala.Unit
 [error]   called from scala.collection.mutable.MutableList.foreach(scala.Function1)scala.Unit
 [error]   called from scala.collection.TraversableLike$WithFilter.map(scala.Function1,scala.collection.generic.CanBuildFrom)java.lang.Object
 [error]   called from scala.collection.immutable.Stream$StreamWithFilter.map(scala.Function1,scala.collection.generic.CanBuildFrom)java.lang.Object
 [error]   called from org.scalajs.testinterface.internal.Slave.org$scalajs$testinterface$internal$Slave$$execute(scala.scalajs.js.Dynamic)scala.Unit
 [error]   called from org.scalajs.testinterface.internal.Slave.handleMsgImpl(java.lang.String,scala.Function0)scala.Unit
 [error]   called from org.scalajs.testinterface.internal.BridgeBase.handleMsg(java.lang.String)scala.Unit
 [error]   called from org.scalajs.testinterface.internal.BridgeBase.$$anonfun$1(java.lang.String)scala.Unit
 [error]   called from org.scalajs.testinterface.internal.BridgeBase.init()scala.Unit
 [error]   called from org.scalajs.testinterface.internal.BridgeBase.$$js$exported$meth$init()java.lang.Object
 [error]   called from org.scalajs.testinterface.internal.BridgeBase.init
 [error]   exported to JavaScript with @JSExport
 [error] involving instantiated classes:
 [error]   com.jshin47.jtdc.client.module.visualization.DiodeStateVizC$
 [error]   com.jshin47.jtdc.client.module.landing.LandingLocC$$anonfun$2
 [error]   scala.collection.mutable.Queue
 [error]   scala.collection.mutable.MutableList
 [error]   scala.collection.TraversableLike$WithFilter
 [error]   scala.collection.immutable.Stream$StreamWithFilter
 [error]   org.scalajs.testinterface.internal.Slave
 [error]   org.scalajs.testinterface.internal.Master
 [trace] Stack trace suppressed: run last client/compile:fastOptJS for the full output.
 [error] (client/compile:fastOptJS) There were linking errors
 [error] Total time: 36 s, completed May 10, 2016 2:01:07 AM

What I've tried

Being unfamiliar with the details of the linker I am only able to try some "obvious" diagnostics:

  • Whether I call the method or not, this error is thrown (it doesn't have to be in the code path, so this is getting thrown when the method itself is linked)
  • The Map type itself works just fine as an argument to the function where I am trying to invoke this
  • I know to a certainty that iff this method (or similar) is present, then I get the above linker error. (Without, no error.)

Any tips on how to proceed, debug, etc are appreciated.

Alternatively, any tips on how I may convert a case class to a Map without the above-style (reflection-based) function, please let me know

tacos_tacos_tacos
  • 10,277
  • 11
  • 73
  • 126

1 Answers1

3

You simply can't use Java reflection in Scala.js:

Java reflection and, a fortiori, Scala reflection, are not supported. There is limited support for java.lang.Class, e.g., obj.getClass.getName will work for any Scala.js object (not for objects that come from JavaScript interop).

Use macros for this instead. See e.g. Scala Macros: Making a Map out of fields of a class in Scala

Community
  • 1
  • 1
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487