Trouble adding tensorflow dependency for scala 2.12.11 - scala

I am following a tutorial to perform object detection in scala. I am
having issues adding the tensorFlow dependency. I have followed the instructions on the official Tensorflow for Scala website http://platanios.org/tensorflow_scala/installation.html, but that doesn't seem to work. I also made sure to use the Java 11 JDK for the project. However, whenever I try to add the sbt dependency
libraryDependencies += "org.platanios" % "tensorflow" % "0.4.0" classifier "linux-cpu-x86_64", I get a "No dependencies found for given import" error in IntelliJ. Any idea on how to set this up properly ?

Try to replace one % in your dependency line to twice %%:
libraryDependencies += "org.platanios" %% "tensorflow" % "0.4.0" classifier "linux-cpu-x86_64"

On top of what the previous answer already suggested, I believe it's probably worth mentioning that (until 2.12) libraries in the 2.x are not binary-compatible across versions. The convention for Scala libraries is to append a _2.x to the published library JAR's artifact identifier. Since SBT was built around Scala (and it's its de facto standard build tool) it acknowledges this conventions and the %% operator will automatically append that extra "qualifier" based on the Scala version you are using.
Notice here on mvnrepository.com how the artifact identifier changes between the Maven and the SBT dependency declaration (in Maven, the artifact identifier is tensorflow_2.12, in SBT the %% allows you to not have to specify that).
The single % is generally used for Java dependencies (that are not affected by the aforementioned convention).
As an alternative (that I would suggest just to play around and see that there's no magic involved), you can also use % to specify a Scala dependency and explicitly mention the Scala version in the artifact identifier, as follows:
libraryDependencies += "org.platanios" % "tensorflow_2.12" % "0.4.0" classifier "linux-cpu-x86_64"
The good news is that starting from Scala 2.13 this issue was tackled at the very root using an intermediate representation that was also introduced to make sure the interoperability between Scala 2.13 and Scala 3.x compiled code.
EDIT
What you have found was actually an issue in the documentation that was already reported, I opened a PR to fix it.

Related

Scala and Scala.js version included in artifact id

I just successfully released my first Scala & Scala.js cross-building library to Sonatype and can now use the following two artifacts in my applicatons:
https://search.maven.org/artifact/com.github.fbaierl/scala-tarjan_2.12/0.1.1/jar
https://search.maven.org/artifact/com.github.fbaierl/scala-tarjan_sjs0.6_2.12/0.1.1/jar
My question now is: Why is the Scala and Scala.js version included in the artifact id? I don't think I have seen such a thing before so I was wondering if I did something wrong. Here is my build.sbt: https://github.com/fbaierl/scalajs-cross-compile-tarjan/blob/03954a3e2d1442ad339298a986209c1403c9692e/build.sbt
That's the way that Scala artifacts work. Pretty much all artifacts look like this -- it just isn't obvious when you use those artifacts in sbt, because (IIRC) the _2.12 is implied by the %% operator in sbt. (And the _sjs0.6 is implied by the %%% operator.)
The underlying reason for it is that artifacts compiled by different major versions of the Scala compiler (Scala versions are epoch.major.minor) aren't binary compatible (because otherwise the language and standard library couldn't evolve). You can't mix e.g. _2.12 and _2.11 artifacts on the classpath, so the “same” version of the same library must be published separately for both Scala versions, so the suffix is needed to distinguish them.

How to use multiple versions of a library in Scala?

I am using a library say A in Scala which is dependent on version x.11 of another library say Z.
Now, I am also using a library say B which is dependent on version x.31 of Z.
This leads to compile error because we will have two versions of library Z, how can I use both libraries A and B in scala's sbt? Is there any way to specify it.
If completely replacing one dependency with a newer version happens to work, then Sparko's solution works. However, that isn't always the case.
If you want to include both versions of a library in the uber-jar produced by sbt-assembly, you'll need to use shading. See this post for an overview of what shading is, and some of the drawbacks associated with it.
Shading is covered in sbt-assembly's documentation here, but if you're anything like me, their way of explaining it will leave you more confused than you started. There's a good blog post, Spark, Uber Jars and Shading with sbt-assembly (waybackmachine link), that helps to demystify it a bit. Here's the relevant section:
I can shade over my typesafe config version, giving it a different
name so Spark won’t get confused between the versions. I quickly went
to my build.sbt file, and added the following code:
assemblyShadeRules in assembly := Seq(
ShadeRule.rename("com.typesafe.config.**" -> "my_conf.#1")
.inLibrary("com.typesafe" % "config" % "1.3.0")
.inProject )
According to the documentation, this should place any class under
com.typesafe.config under the new package my_conf.
For your case, the solution would be adding something like this to your build.sbt file:
assemblyShadeRules in assembly := Seq(
ShadeRule.rename("com.somecompany.**" -> "my_conf.#1")
.inLibrary("com.somecompany" % "libraryZ" % "0.11")
.inProject
)
In sbt, conflicts between libraries are configured using the conflict manager. By default, the latest revision is selected but this can also be overridden in you .sbt file:
conflictManager := ConflictManager.strict
If you're using sbt 0.13.6 or greater you will be warned when you have an incompatible binary version between your dependencies. In this situation, you could configure an override in your sbt file for the specific library:
dependencyOverrides += "org.raman" % "Z" % "x.11"
This will force the resolved version of Z to x.11 but not pull a direct dependency in.

Using util.parsing in Scala 2.11

I have written a Scala program with Eclipse Scala IDE that uses scala.util.parsing.JSON and I would like to transform it to support Scala 2.11 version. In Scala 2.11 I get an error:
error: object parsing is not a member of package util.
I have found out that the parsing library is not anymore in the util package by default, but has to be downloaded separately here.
I have downloaded that and tried to add it to my Eclipse project as a new source folder, but that didn't work out. The instructions are only for adding it to sbt, but I don't think that is relevant to me if I want to just use it in Eclipse.
Should I try to find a JAR file somewhere?
Should I try to find a JAR file somewhere?
Yes, you should. :)
And specifically, you should use this one (in SBT syntax):
libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.2"
The above line should be all you need to add to build.sbt if you're using SBT. If you want to manually add it to your project by downloading it, you can find it on Maven Central.
The scala-parser-combinators library was removed in 2.11 so that people who don't use it don't have to pay a price for having it in the scala runtime library. Consequently, people who do want to use it have to now explicitly include it in their build. Note that the XML library was similarly removed in 2.11 to its own library.

Necessary to export Quasiquotes dependency for exported macro libraries on Scala 2.10?

I just updated a project which was using macro-paradise 2.0 snapshot under 2.10; with the final version of macro-paradise 2.0 it tells me the following when I compile under 2.10 (not 2.11):
Quasiquotes in macro paradise for Scala 2.10 require a dependency on a supporting library. Add the following line to your SBT build: libraryDependencies += "org.scalamacros" %% "quasiquotes" % "2.0.0"
Now I'm worried because that dependency turns up as a regular dependency of my published Maven artifact. Is this really so? Or isn't Quasiquotes perhaps just a compile-time dependency that should not be needed for the published artifact?
If so, should I go through these hoops to get rid of the artifact, i.e. % "compileonly"?
Macros that use quasiquotes provided by recent versions of paradise for Scala 2.10, i.e. 2.0.0-M4+, including 2.0.0 and later ones, will almost always require the supporting library to be on classpath when expanding (very simple quasiquotes don't require the library, but that's quite rare).
Therefore if you want users of your library to also use macros that you've written with quasiquotes, you'll need to export "org.scalamacros" %% "quasiquotes" % "2.x.y" in your pom file or rely on someone else to provide this dependency for your users.
Well, I just tried the approach in the linked question to create a special "compileonly" configuration and thus remove it from the exported POM. It was possible to use the library in Scala 2.10 even with Quasiquotes absent.

Why can't Scala find org.apache.commons.lang package?

I want to use org.apache.commons.lang.NotImplementedException as it seems to be the only NotImplementedException implementation in Java/Scala domain. I can remember I used to use it with Scala 2.8.1 with no hacks. But now it says "object lang is not a member of package org.apache.commons". Where has org.apache.commons.lang gone?
I've just found the answer myself. The problem is Apache Commons 3 no longer include lang (including lang3 instead, which is differend and doesn't contain NotImplementedException), so we need Apache Commons 2.6. And what's inobvious here is that the Maven group id for it is not org.apache.commons, but commons-lang - the same as its artifact id.
So I had to add "commons-lang" % "commons-lang" % "2.6" dependency and do sbt update to make it work.