sbt doesn't recognize external library - scala

I'm using IntelliJ, and the sbt shell. I added an external jar to my project via Project Structure, and then ran sbt assembly. My code looks something like this:
package myPackage
import com.myExternalPackage.stuff
// implementation using com.myExternalPackage.stuff
IntelliJ recognizes this external jar and there are no red lines in the IDE. If I CTRL-click on myExternalPackage in the editor, it even opens up the exact place in External Libraries where the package is coming from.
But sbt assembly complains that
object myExternalPackage is not a member of package com
Do I need to do something to my build.sbt? Other people in my company are using this code without a problem.

In your build.sbt, you should have:
libraryDependencies ++= Seq(
"com.myExternalPackage" % "xxxx" % "version"
)

Related

Scala "not found: object com" - should i really add entry in build.sbt if there are no other dependencies?

I have created basic Scala Play application with https://www.playframework.com/getting-started play-scala-seed. This project compiles and runs with sbt run. But I have another Scala project that compiles and runs and which I have submitted to my local Ivy repository with command sbt publishLocal. This other project was saved at C:\Users\tomr\.ivy2\local\com.agiintelligence\scala-isabelle_2.13\master-SNAPSHOT as a result of this command.
Then I imported (exactly so - imported, no just opened) my Play project in IntelliJ and I used Project - Open Module Settings - Project Settings - Libraries to add com.agiintelligence jar from my ivy2 location. After such operations IntelliJ editor recognizes com.agiintelligence classes. That is fine.
But when I am trying to run my Play application with sbt run, I experience the error message not found: object com that is exactly when compiling import com.agiintelligence line in my Scala controller file of Play application.
Of course - such error has been reported and resolved with, e.g. object play not found in scala application
But that solution suggests to append build.sbt file. My build.sbt file is pretty bare:
name := """agiintelligence"""
organization := "com.agiintelligence"
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.13.5"
libraryDependencies += guice
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0" % Test
// Adds additional packages into Twirl
//TwirlKeys.templateImports += "com.skaraintelligence.controllers._"
// Adds additional packages into conf/routes
// play.sbt.routes.RoutesKeys.routesImport += "com.skaraintelligence.binders._"
My Play application contains (as can bee seen from the IntelliJ project pane) some tens of 'external libraries' (it shows my com.agiintelligence jar as well), but why should I add my own ivy2 library in build.sbt file if no other libraries are listed here? What is different with my library? It is on my computer, in the repository as expected already?
Of course, I can try to add it build.sbt and issue sbt update and see what happens, but I can not understand this logic? Can someone explain it and provide some clue to intelligible solution of my error message?
My Play application contains (as can bee seen from the IntelliJ project pane) some tens of 'external libraries'
Those are probably just transitive dependencies of your Play dependency, that is why sbt downloaded all of them and put them in your classpath so you could use them without you needing to tell it about them; because the pom of Play already did.
It is not that the build tool or the IDE magically added all those dependencies for you because they read your mind and magically understood you wanted them. And that for some reason the magic stopped working for your own library.
Why it is not sufficient to list it Project-Setting--External Libraries in IntelliJ only?
That is sufficient for the IDE to work, but not for the build tool. The build tool is independent of the IDE; it doesn't know about it. sbt just knows about the dependencies you configured in your definition file.
Even more, you should always configure your dependencies on your build tool and then import that in the IDE; rather than the opposite. IDEs are graphical tools, so their state can not be committed, can not be shared, can not keep track of changes, can not be used in CI / CD environments; additionally, different teammates may want to use different IDEs.
I resolved the error message by adding line in build.sbt file
libraryDependencies += "de.unruh" %% "scala-isabelle" % "master-SNAPSHOT"
and by subsequent run of sbt update.
Error is solved, but the main question still stand - why I had to do this? Why there are tens of dependencies that are not listed in build.sbt and why should I list my dependency in build.sbt and why it is not sufficient to list it Project-Setting--External Libraries in IntelliJ only?
OK, comment by #Luis_Miguel_Mejía_Suárez gave the explanation, that comment is the actual and expected answer to my question.

Scala's build.sbt not recognised by IntelliJ

I'm having an issue where my build.sbt file is not being picked up properly using IntelliJ (Ultimate 2020.2.3). I create a new Scala sbt project using the IntelliJ wizard (file > new > project > scala / sbt) and add a new dependancy to the buid.sbt file but when I try to import it into one of my class files, IntelliJ will not compile my project due to a dependancy issue.
The sbt tool window picks up the external dependancies but my project "external dependancies" doesn't contain the library at all, even after I refresh the project. Also, my build.sbt file has a bunch of errors in it like it's not being recognised properly by IntelliJ but I've installed the Scala plugin so I don't know what else I could do?
Here you can see that I've added the org.slf4j dependancy into my build.sbt; It's picked up by the sbt tool window (on the right) but not by my project (on the left)
When I hover over the libraryDependencies in the build.sbt file it doesn't seem to recognise the sbt syntax:
I cannot import the library into my class file and the project wont build:
I'm new to Scala and I'm simply trying to create a basic hello world project but I can't seem to get past this frustrating issue.
You can try first to create an SBT project manually in some directory. build.sbt alone would be enough.
Then run sbt in that directory to see that SBT shell works properly. Try some commands like sbt compile, sbt run with some helloworld app. When you create helloworld app mind the directory structure where you put it, i.e.: src/main/scala/HelloWorld.scala.
If all that works go to IntelliJ and import/open project from there - select build.sbt.
When you create or import SBT project from IntelliJ it takes a while to bootstrap everything and download compiler, etc. Just leave it until it's done. Same goes for first time compilation when the compiler needs to be compiled :).
To setup a sample project you can issue these shell commands:
mkdir untitled
cd untitled/
echo 'name := "untitled"
version := "0.1"
scalaVersion := "2.13.3"
libraryDependencies ++= Seq(
"org.slf4j" % "slf4j-simple" % "1.7.26",
)
' > build.sbt
mkdir -p src/main/scala/
echo 'object HelloWorld {
def main(args: Array[String]): Unit = {
println("Hello World")
}
}
' > src/main/scala/HelloWorld.scala
sbt run
If there are not issues with these steps then import build.sbt into IntelliJ.
I was finally able to get past this issue. I'm not 100% sure what solved it in the end unfortunately but disabling a bunch of plugins I wasn't using seemed to fix the issue for me.
I suspect it may have been the Gradle plugin since I saw some errors in the idea.log file but after re-enabling the Gradle plugin to test everything is still working so not sure.

SBT Plugin in an unmanaged jar file

The requirement: an SBT plugin code is in an unmanaged jar, for example in lib/unmanaged-sbt-plugin-0.0.1.jar.
I was expecting the jar file would be picked up by SBT automatically and the plugin would work out-of-the-box, i.e.: the tasks would be accessible from SBT command line, but that is not the case.
The jar file has the sbt/sbt.autoplugins file in it and the plugin works if pulled from a remote repo into the local one and imported via addSbtPlugin(...). Please note I cannot do that - it's a requirement to get it to load from the lib/unmanaged-sbt-plugin-0.0.1.jar and not from the local/remote repo.
Putting the following line in the build.sbt doesn't make the plugin work (there's not error either):
unmanagedJars in Compile += file("lib/unmanaged-sbt-plugin-0.0.1.jar")
The implementation of addSbtPlugin(...) is simply (according to http://www.scala-sbt.org/0.12.2/docs/Getting-Started/Using-Plugins.html):
def addSbtPlugin(dependency: ModuleID): Setting[Seq[ModuleID]] =
libraryDependencies <+= (sbtBinaryVersion in update, scalaBinaryVersion in update)
{ (sbtV, scalaV) => sbtPluginExtra(dependency, sbtV, scalaV) }
I'm wondering if the above info can be used to resolve my issue?
Thank you in advance!
So you can specify an explicit URL for library dependencies (ModuleID):
addSbtPlugin("org.my-org" % "unmanaged-sbt-plugin" % "0.0.1"
from "file:///./lib/unmanaged-sbt-plugin-0.0.1.jar")
Have been struggling to get this to work.
Could not get it to work with proposed solution using from "file://.." (using sbt 1.0.4).
Got it to work by putting the plugin in project/lib folder and adding all the plugin dependencies to plugins.sbt using libraryDependencies ++= Seq(..) like in build.sbt. You can find the plugin dependencies by looking at the plugin pom file, usually in .ivy2/local/<org>/<pluginname>/poms folder.

How to add com.typesafe.sbt.* dependencies to my project?

I was playing with one sbt web plugin and I wanted to reuse the code in my project. Unfortunately I wasn't even able to compile the original code in my project because of missing dependencies. These are the imports:
import com.typesafe.sbt.jse.SbtJsTask
import com.typesafe.sbt.web.{CompileProblems, LineBasedProblem}
import sbt.Keys._
import sbt._
import xsbti.Severity
None of these could be resolved. The build fails with messages like not found: object sbt. I checked the original project's build.sbt file but there was nothing relevant in libraryDependencies.
I'm using Intellij Idea and the strange thing is that when I expand External Libraries in the Project View I can find all the required stuff under SBT: sbt-and-plugins (for example object com.typesafe.sbt.web.CompileProblems is there and I can see its definition in the class file).
It seems to me that the stuff I need is a core part of sbt but somehow it won't load to the project. What am I doing wrong?
short answer: from here
EDIT (3): answer:
use a custom ivy resolver:
resolvers += Resolver.url("SBT Plugins", url("https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns)
libraryDependencies += ("com.typesafe.sbt" % "sbt-js-engine" % "1.0.2")
.extra(
sbt.mavenint.PomExtraDependencyAttributes.SbtVersionKey -> sbtBinaryVersion.value,
sbt.mavenint.PomExtraDependencyAttributes.ScalaVersionKey -> scalaBinaryVersion.value)
.copy(crossVersion = CrossVersion.Disabled)
how to find plugin jars:
to figure out from where exactly sbt downloads the jars, I used this (somewhat awkward) process:
first, I wanted to see where sbt stores the file localy. so:
sbt "reload plugins" "show fullClasspath" | sed s/\),\ Attributed\(/\\n/g
and I searched the output (or you can use grep).
then, I deleted the file, and executed sbt again with: reload plugins, update & last update to see the full update log.
searching the log, I found a line saying where sbt got the plugin from.

Any IDE supporting SBT?

is any IDE supporting SBT in a proper way (like Maven for example)? Because I've found a lot of tools that generate IDE-related configuration files but I haven't found any plugins that give any support of SBT interaction form within IDE.
I want to make an IDE-agnostic project based on SBT, but also I want to be able to use full spectrum of features that IDE provide and not just use it as an editor and do all the other stuff from console.
Does Intellij fit the bill ? It has an SBT plugin (and a Scala plugin, obviously!)
I know this isn't exactly what you're looking for, but putting it here as a work-around for working with SBT in eclipse for whoever is interested.
SBT generates eclipse config files, but after you import it, it works fine from within eclipse. You just need to set up the project for the first time outside of Eclipse, run SBT to resolve dependencies, generate eclipse structure using the eclipse sbt plugin and import into Eclipse. After that, you can run the code directly from Eclipse and it works fine.
Here're the steps in detail:
Create the folder structure as follows:
Create a file called plugins.sbt in the project folder and add the following line to it:
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0")
Create build.sbt in the root directory i.e. ScalaSBTProject with content similar to the following. I'm using akka here, but add and remove libraries as you require:
name := "ScalaSBTProject"
version := "1.0"
scalaVersion := "2.10.0-RC2"
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"
libraryDependencies += "com.typesafe.akka" % "akka-cluster-experimental_2.10.0-RC2" % "2.1.0-RC2"
Open command prompt and run sbt in the directory ScalaSBTProject. SBT will download and resolve whatever dependencies are required
Run the command eclipse at the SBT command line. This will generate all the eclipse related project files
Import ScalaSBTProject into Eclipse using File->Import->Existing Project to workspace, and make sure you check Import into workspace
EDIT: Just as a Post-Script, you can quite easily create a batch file to take the name of the project and generate the eclipse compatible project, just a way to speed up the process.