Gary Sieling

Fixing scala error: bad symbolic reference

If you write Scala code, you’re almost guaranteed to end up with incompatible class files somewhere in the chain. This is particularly irritating when it happens within libraries you don’t control, because the scala compiler apparently decides not to give you any useful information, like so:

[error] bad symbolic reference. A signature in DefaultWrites.class refers to term time
[error] in package java which is not available.
[error] It may be completely missing from the current classpath, or the version on
[error] the classpath might be incompatible with the version used when compiling DefaultWrites.class.
[error]                   "id" -> id,

This is especially irritating because for me it only occurred when I started using some implicit that apparently depended on a Java 8 class, when the rest of the Play JSON library had been working fine.

Basically the cause of this is that you have several points of control: Java 7/8, Scala 2.10, 2.11, or 2.12 (perhaps a point release).

Within SBT, you control this in several ways:

scalaVersion := "2.10.5"

If you specify the maven dependencies correctly, SBT will just figure out the right thing. If you copy stuff from people’s blogs, you may end up with mismatched scala versions, which breaks things:

libraryDependencies += "com.typesafe.play" %% "play-json" % "2.4.6"

libraryDependencies += "com.typesafe.akka" % "akka-actor_2.10" % "2.3.14" // don't do this

You may see some blog posts that suggest adding scalacOptions or javacOptions. This is less helpful than you’d think, because this just tells it what platforms to target, so you can only choose numbers equal to or lower than your current environment. Oddly, no tool I’ve seen (including Intellij) can find the JVMs you’ve installed on your machine, so there is no easy way to make a config file that picks one.

javacOptions ++= Seq("-source", "1.8", "-target", "1.8")
scalacOptions += "-target:jvm-1.8"

Thus, a final possible cause for this problem is a bad JAVA_HOME, more likely if you see Java 7 than 8. It is worth making sure you control this carefully, as this problem is only going to get worse (scala 12, 13, etc, Java 9, etc)

echo %JAVA_HOME%
C:\Program Files\Java\jdk1.8.0
Exit mobile version