sbt ignoring library dependency - scala

I have a library dependency
libraryDependencies += "mygroup" % "myartifact" % "myversion"
This is properly retrieved, and found in lib_managed. It contains some XML files (resources), and using jar tf I can see that the jar file is complete.
Ok. But—although this had always been working before—it is not ending up on my classpath any more. When I do show full-classpath, I see all libraries but this one. Consequently the program fails because it cannot read these resources. This also effects bundling the program as a standalone.
This library has no dependencies itself, nor does any other library of the project depend on it. What could cause this problem, and how to fix it? sbt version is 0.12.4.

This is a variant of this problem. Although other than in the linked question the .jar file does end up in lib_managed, it still isn't somehow "considered important" by sbt.
The solution is the same.
$ rm -r ~/.ivy2/cache/mygroup/myartifact

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.

How to build a jar file out of github project in sbt to be used in a scala program

I am trying to use scala to access Amazon's DynamoDB and found this great package on github https://github.com/piotrga/async-dynamo
so I downloaded the code as a zip file , unzipped it and then did "sbt clean test" and getting the following error
error sbt.ResolveException: unresolved dependency: asyncdynamo#async-dynamo;1.6.0: not found
Questions : is this the correct way to generate a jar file that I can include in my Scala program or is there a better way?
thanks in advance.
EDIT:
just for the benefit of others, the SCALA SBT documentation provides lots of information regarding the build process.
Instead of generating a jar file, you can just run 'sbt publish-local' and then include the lines for the managed dependency in the other project.
Sbt/ivy will see you have the artifact that way you don't need to add the jar to the other project which is much cleaner.
Then for example if you need to update the other project you don't need to replace the jar again - just publish-local again and clean and run your other project!
You are not the only one to have problems with this it seems, see github issues page:
https://github.com/piotrga/async-dynamo/issues
The command 'sbt clean test' will run the tests sbt detects. If you want a .jar file you could use 'sbt clean package', which produces a .jar in the target/ folder.
I cloned the repo and was able to run sbt package after changing release.sbt a bit. I had to change the 'publishTo'-variable as it seemed to depend on the repository creators local environment variable, so I just commented it away.
I did not get the dependency problem, so I suppose it is correctly declared. The tests it tries to run do fail though, but sbt package compiles produces the .jar just fine.
EDIT: As Matthias Schlaipfer pointed out in the comments, the more elegant way(and much easier) would just be to add this as an depency in your build.sbt. From the readme, this is what you need to add:
resolvers += "piotrga" at
"https://github.com/piotrga/piotrga.github.com/tree/master/maven-repo"
libraryDependencies += "asyncdynamo" % "async-dynamo" % "1.6"

sbt retrieveManaged doesn't pick up jars produced using publish-local

Suppose I have a project in which I've used sbt publish-local to generate local copies of the jar files in ~/.ivy2/local.
Another sbt project on the same machine can successfully locate these jars to satisfy dependencies. However, if in that project I use the option retrieveManaged := true, sbt never copies the jars out of ~/.iv2/local into the lib_managed directory.
How can I make this happen? (Is this behaviour intended?)
(I'm using sbt 0.12.1.)
I am using the same setup. When I update my locally published dependencies, I remove the managed jars first and then run the update:
$ rm -r lib_managed/jars/my-package-prefix
$ sbt test:compile
(test:compile will figure out that the jars are missing and do the update by itself).
In older versions of sbt I believe there was an issue when using -SNAPSHOT versions, but I haven't seen this problem anymore with sbt 0.12.
In rare situations, something messes up with the Ivy cache and somehow you cannot enforce the updates. This is perhaps the case when corrupt Ivy meta data files have been used. Then the only solution is to wipe all occurrences of your dependency from ~/.ivy2/local and ~/.ivy2/cache, re-publish, and re-update.

how to compile single file in sbt

I'm doing some refactoring that made compiler temporally give errors in several files. I'd like to work with them one by one (starting with common dependencies) and need some tool to check if modification is correct.
sbt compile is inconvenient because it gives too many errors and spends much time for compiling things that have no good.
I'm searching for a way to compile single file with sbt or a method for extracting sbt side libraries definition to pass them to a normal scalac compiler
There was a similar topic: How to compile just some files with sbt? that turned out to be source code error discussion rather that sbt functionality disclosure.
You could add the following line to build.sbt:
sources in Compile <<= (sources in Compile).map(_ filter(_.name == "Particular.scala"))
Then fix Particular.scala, then edit build.sbt and put the name of the next source file. If you keep the sbt console open, reload will re-read the .sbt file after you modify it.
I just wanted to mention here that I came across sbt-compile-quick-plugin (https://github.com/etsy/sbt-compile-quick-plugin). It does what it says on the tin, just add addSbtPlugin("com.etsy" % "sbt-compile-quick-plugin" % "1.3.0") to your project/plugins.sbt, then you can just start up sbt and run compileQuick /path/to/your/file

How can I let sbt download the source of scala-library.jar?

I know if I add withSources when I define one dependency, sbt can download that sources jar file automatically.
For example,
val specs = "org.scala-tools.testing" % "specs_2.8.1" % "1.6.6" % "test" withSources ()
But for the scala-library.jar and scala-compiler.jar, I don't need define them explicitly, how can I get sbt download their sources for me? So, I don't need config it manually after generate idea project using sbt-idea-plugin.
You have to change the boot properties. There is a nice description in the recent blog decodified from Mathias:
"How to make SBT download scala library sources" (started from #hseeberger key starting points)
Here is the relevant part (in case that link ever goes stale)
First, forget about trying to find some “hidden” setting in your SBT project definition enabling Scala library source download! It does not exist (at least not in SBT version 0.7.x).
Rather, there are these two things you need to do in order to whip SBT into submission:
Create an alternative configuration file for your SBT launcher.
Make the SBT launcher use it.
These are the steps in detail:
Find your sbt-launcher-0.7.x.jar file.
Since I’m on OS/X and use SBT via Homebrew mine lives at /usr/local/Cellar/sbt/0.7.5.RC0/libexec/sbt-launch-0.7.5.RC0.jar.
Extract the sbt.boot.properties from the sbt sub directory in the launcher jar
Fire up your favorite editor and change line 3 to classifiers: sources (uncomment the line)
Find the sbt script file you created during your SBT setup (e.g. ~/bin/sbt, or, when using Homebrew, /usr/local/Cellar/sbt/0.7.x/bin/sbt)
Add the path to your tweaked sbt.boot.properties file, prepended with an ’#’ character and in double quotes, as the second-to-last argument of the java call.
This is what my sbt script file looks like:
#!/bin/sh
java -Xmx768M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m \
-jar /usr/local/Cellar/sbt/0.7.5.RC0/libexec/sbt-launch-0.7.5.RC0.jar \
"#/usr/local/Cellar/sbt/0.7.5.RC0/libexec/sbt.boot.properties" \
"$#"
Once you have completed these steps SBT should happily download the scala-...-sources.jar files for the Scala compiler and standard library for any new project you create.
To have SBT do this for an existing project, you have to manually delete the project/boot/scala-{version} directory before performing an ‘sbt update’ (SBT does not fetch additional source artifacts if the main jar is already present).
Once you have a custom sbt.boot.properties file, there are also other ways to supply it to the SBT launcher.
See SO question "how do I get sbt to use a local maven proxy repository (Nexus)?"
Based on Michael Slinn comments:
If you are using sbt 0.11.x and above, use this command:
sbt update-sbt-classifiers
Two pieces of information.
(1) SBT Documentation
http://www.scala-sbt.org/0.13.5/docs/Detailed-Topics/Library-Management.html
and I quote:
"To obtain particular classifiers for all dependencies transitively, run the updateClassifiers task. By default, this resolves all artifacts with the sources or javadoc classifier."
This means you should not need to do anything, but you can make it explicit and put in you build.sbt:
transitiveClassifiers := Seq("sources", "javadoc")
To actually get the sources downloaded by SBT then you do:
"updateClassifiers"
(2) If you are working with Eclipse scala IDE - most likely you are as development of plugins for Eclipse/Netebeans is a lot more active for eclipse - then you should configure your ecplise to find out the sources if you do the following.
EclipseKeys.withSource := true
Here is the documentation you should read,
https://github.com/typesafehub/sbteclipse/wiki/Using-sbteclipse