How can I publish a myproject-test.jar in one sbt project, containing my test classes, and depend on both that, and myproject.jar, in another sbt project?
This answer is for sbt 0.11.3.
In the first sbt project:
publishArtifact in Test := true
In the second one, specify the dependency like this:
"com.example" % "myproject" % "42" classifier "test" classifier ""
(i.e. add the two classifiers to your existing dependency specification.)
However, you probably want to do this instead in the second project.
Related
I have a dependency (stagemonitor.org) that I want to include for everything except "test" and "test:test". How do I include a dependency for everything but "test"? I'm using SBT 0.13.8.
Thanks,
Johan
You likely need to exclude things manually via managedClasspath in Test.
Check out -= operator we are adding on 0.13.9-RC1.
Assume a hierarchical project layout as the following:
root
-subproject1
-subproject2
where root only aggregates all subprojects.
Calling eclipse in root, as expected, generates importable eclipse projects for all subprojects.
However, now consider that subproject 1 also aggregates subproject 2. Calling the eclipse task in either root or subproject 1 generates project files for all but subproject 1. In summary, having an "aggregation graph" such as
-> subproject1
/ |
root |
\ v
-> subproject2
never generates eclipse files for subproject 1.
Am I missing something about aggregation semantics or is this a bug in sbteclipse?
A concrete case where this problem occurs can be found in the build file here. Project "vfd-main" never has any eclipse projects generated unless removing its own aggregation settings on line 58.
Btw, I am using sbteclipse version 3.0.0
It turns out this is the expected behavior. Since subproject1 aggregates other projects, it is considered a parent and, by default, no project definitions are generated for parents. This can be changed by adding
EclipseKeys.skipParents in ThisBuild := false
to the build.
I was a heavy Maven user and now I'm gradually using SBT for some of my projects.
I'd like to know how could I use SBT to create a standalone Java project? This project should be packaged as a JAR file and this JAR file would be used as a dependency in another SBT project.
In Maven, I could tell in my pom.xml what type of artifact it should produce when I build it. Is there something similar that I can do in SBT?
There is a difference between standalone and making a project useable as a dependency or another project. In the first case, you would use a plugin such as sbt-assembly. What it will do is create one jar file containing the project class files along with all of its dependencies. If you write an application, what you get is a double-clickable jar that you can execute from anywhere.
If you want to use your project A as a dependency for another project B, you have different options. You could just package the class files of A, using sbt package (answer of #Channing Walton). Then you could drop the resulting .jar file in the lib directory of project B. However, if A also requires libraries, you must make sure that they also end up in project B's libraries.
A better approach is to publish your project. You can do that purely on your local machine, using sbt publish-local. That will store the jar as produced by package in a special local directory which can be accessed from sbt in another project, along with a POM file that contains the dependencies of A. It will use a group-ID (organization) and artifact-ID (name) and a version of your project A. For example, in build.sbt:
name := "projecta"
version := "0.1.0-SNAPSHOT"
organization := "com.github.myname"
scalaVersion := "2.10.3"
publishMavenStyle := true
After publishing with sbt publish-local, you can add the following dependency to your project B:
libraryDependencies += "com.github.myname" %% "projecta" % "0.1.0-SNAPSHOT"
If you have a pure Java project, you can omit the Scala version suffix, i.e. in Project A:
crossPaths := false
autoScalaLibrary := false
And then in Project B:
libraryDependencies += "com.github.myname" % "projecta" % "0.1.0-SNAPSHOT"
(using only one % character between group and artifact ID).
More on publishing in the sbt documentation.
'sbt package' will produce a jar file.
If you want it to be executable you need to add the following to your .sbt config:
mainClass in Compile := Some("your.main.Class")
Sure, you can use 'sbt package' command, it creates a jar file but this jar will be without any dependencies. To run it necessary to specify 'classpath' arg to the libraries.
In your case you wish a standalone runnable file. And you need to add the dependencies.
To do this you can use 'assembly' plugin for SBT, see https://github.com/sbt/sbt-assembly/
Afterward you can just run 'sbt assembly' command, it provides a fat jar file with all dependencies that you can deploy and run anywhere and at any time.
For details see this article
publishLocal
builds the artifact and publish in the local Ivy repository making it available for your local project dependencies.
publishM2
same as above, but the artifact is published in local Maven repo instead of Ivy repo.
I think the easiest way to produce a stand-alone jar with your project in it,
is sadly not lying inside sbt.
I personally use my IDE: Intellij to make the jar (through the 'build artifact' feature).
Thanks to Intellij I can easily choose which library I want to include in the jar or not, (for instance the scala stl).
IMHO, this is by far the simplest method to get an executable jar for your project.
If you put the scala stl you can run your jar with the "java -jar" command, if you don't you have to run it somewhere with the correct version of scala installed with "scala".
I'm using sbt 0.10 to build a Scala project using just a build.sbt file instead of a full configuration.
Every time I start sbt it gives me the messages as follows:
[info] Set current project to default-ee699e (in build file:/Users/.../project/plugins/)
[info] Set current project to default-8febe7 (in build file:/Users/.../)
I did set the name and mainClass settings in the build.sbt file, so I don't know what I need to set to get the project names default-XXXX go away.
EDIT: the answer given below is correct in that this is cosmetic. If you switch to a full configuration of sbt, then it uses that project's name as opposed to default-XXXX however.
The message can be a bit misleading, it's not saying that you must "set the curent project", it's telling you what it's doing.
It sets the current project to the plugins folder, does it's stuff (compile, etc.), then sets the current project to your actual build folder and does it's thing once again.
You don't need to set anything else.
I'm new to SBT, using version 1.0 and a custom repository, and I've set the "retrieveManaged" flag mentioned here, but it seems that SBT only downloads the directly requested JARs, but not any of the JARs upon which those JARs depend. And yes, the repository is using the customary default format described in the answers here (though SBT/Ivy doesn't seem capable of retrieving snapshots, either, but that's a separate problem, I expect). The repository does not require any kind of authentication, FYI.
Here's a slightly generified version of my built.sbt file:
name := "MyProject"
organization := "com.myorg"
version := "0.1"
scalaVersion := "2.9.0"
scalacOptions += "-deprecation"
retrieveManaged := true
resolvers += Resolver.url("myorg", url("http://host.com//content/groups/public"))
libraryDependencies += "com.myorg" % "otherproject" % "1.0"
fork in run := true
The requested "otherproject" JAR file loads fine, but SBT/Ivy seems to have no interest in opening up its POM and downloading the other JARs it needs to operate. This seems like it should be a fairly basic function (Maven does it, for example) but I have no idea how to convince SBT/Ivy to do so. (And the documentation assures us that SBT is, in fact, supposed to do this: "By default, these declarations fetch all project dependencies, transitively".)
I believe I must be doing something wrong, but have no idea -- given how simple and vanilla this basic configuration is -- what it could be.
Standard, Maven-style repositories are declared like:
resolvers += "myorg" at "http://host.com/content/groups/public"
More details are at the Library Management page you linked to and on the Resolvers page.
Typically, one only uses Resolver.url when specifying non-standard layouts.