Multi project setup

27 views
Skip to first unread message

Saurabh Raje

unread,
Nov 18, 2009, 1:55:04 AM11/18/09
to simple-build-tool, dmha...@gmail.com
I was looking for a way to get away from XML based build scripts when
I stumbled upon sbt. I have played with some basic examples (single
project) and got them to work to my satisfaction. I am currently stuck
on getting multiple projects working with sbt.

Suppose the simplified multiple projects structure is as follows -
<root folder>
|- project1 (generates jar)
|- project2 (generates jar & war - depends on project1 jar)
|- project3 (generated multiple wars - depends on project1 &
project2 jar)

Some questions here -
* What is the best way to get such a setup working with sbt?
* Is there a way where I can keep single project/boot (and not repeat
the copying exercise for each of projects 1 to 3) - perhaps in the
root folder? The ideal, I think, would be that these jars be pulled
onto sbt classpath from shared ivy repository cache - can that be
done?
* Can I use ivy.xml to define dependencies & ivy-settings.xml to
define repositories/settings for projects? That way eclipse can be
happy & pull dependencies automatically in its classpath (ivyde).

I have lot of hopes for this project to become the build tool of
choice for java/scala projects. Wish you the best of luck.

Thanks,
- Saurabh

Mark Harrah

unread,
Nov 18, 2009, 7:52:19 AM11/18/09
to simple-build-tool
Hi Saurabh,

On Wednesday 18 November 2009, Saurabh Raje wrote:
> I was looking for a way to get away from XML based build scripts when
> I stumbled upon sbt. I have played with some basic examples (single
> project) and got them to work to my satisfaction. I am currently stuck
> on getting multiple projects working with sbt.
>
> Suppose the simplified multiple projects structure is as follows -
> <root folder>
>
> |- project1 (generates jar)
> |- project2 (generates jar & war - depends on project1 jar)
> |- project3 (generated multiple wars - depends on project1 &
> project2 jar)
>
> Some questions here -
> * What is the best way to get such a setup working with sbt?

Put a project definition in <root folder>/project/build/ that looks something
like:

import sbt._
class MyProject(info: ProjectInfo) extends ParentProject(info) {

// sub-project path, name, definition, and project-level dependencies
val p1 = project("project1", "Project 1")
val p2 = project("project2", "Project 2", new Project2(_), p1)
val p3 = project("project3", "Project 3", new Project3(_), p1, p2)

// Define a web project for project 2
// The 'war' artifact is already defined and built by DefaultWebProject
// Add the 'jar' artifact for publishing
// and a package-jar action to produce that artifact

class Project2(info: ProjectInfo) extends DefaultWebProject(info) {

val jarArtifact = Artifact(artifactID, "jar", "jar")

override def packageAction = packageJar dependsOn(super.packageAction)
lazy val packageJar = packageTask(...)
}
...
}

If you explain a bit more about how you want to create the jar/war and the
multiple wars, I can be more specific. The general idea in the above example
is that you define an action to build the package and then declare the package
as an artifact to be published. The project-level dependencies declared at
the beginning ensure that a 'compile' on project 3 runs 'compile' on project 1
and then on project 2 before it runs 'compile' on 3.

> * Is there a way where I can keep single project/boot (and not repeat
> the copying exercise for each of projects 1 to 3) - perhaps in the
> root folder? The ideal, I think, would be that these jars be pulled
> onto sbt classpath from shared ivy repository cache - can that be
> done?

Using the above, you'll have a single project/boot in the root directory. It
is not currently possible to have a single project/boot for the whole machine
in the stable 0.5.x series of sbt. It works in 0.6.x, but that is still in
the experimental stage.

> * Can I use ivy.xml to define dependencies & ivy-settings.xml to
> define repositories/settings for projects? That way eclipse can be
> happy & pull dependencies automatically in its classpath (ivyde).

Yes, you can. See also [1] for how to do it without ivy.xml.

> I have lot of hopes for this project to become the build tool of
> choice for java/scala projects. Wish you the best of luck.

Thanks!

-Mark

[1] http://code.google.com/p/simple-build-tool/wiki/IntegrationSupport

Saurabh Raje

unread,
Nov 20, 2009, 6:10:16 AM11/20/09
to simple-build-tool
Hi Mark,

Thanks for the reply. One of my mistakes was that I had erroneously
inferred that the build file for subproject could also be put in
<subproject folder>/project/build.

Regarding your question of what is packaged in multiple jar/war's - it
is based on packages.

say for project 2
- org/foo/common/* goes in both project2.jar & project2.war
- org/foo/webapp/* goes in project2.war

say for project 3
- org/foo/common/* goes in both project3_war1.war & project3_war2.war
- org/foo/webapp1/* goes in project3_war1.war
- org/foo/webapp2/* goes in project3_war2.war
- typically same resources but different web.xml's

So this should be as simple as using the idiom you mentioned and
specifying different packagePaths for the packageTask's right?

Btw, got my existing ivy.xml & ivysettings.xml working too! Thanks
again! It was too easy :)

- Saurabh

P.S. have you thought about moving your source code to git?
exluding .svn's from almost everything you do is so frustating! - how
do you manage it? :)

Mark Harrah

unread,
Nov 20, 2009, 7:55:28 AM11/20/09
to simple-b...@googlegroups.com
On Friday 20 November 2009, Saurabh Raje wrote:
> Hi Mark,
>
> Thanks for the reply. One of my mistakes was that I had erroneously
> inferred that the build file for subproject could also be put in
> <subproject folder>/project/build.

You should be able to do that as well. For example, in your root project:

val p1 = project("project1", "Project 1")
val p2 = project("project2", "Project 2", p1)
val p3 = project("project3", "Project 3", p1, p2)

This should use the project definitions in the <subprojectN>/project/build/.

I personally prefer putting everything in the root definition, but this method
is valid and supported.

> Regarding your question of what is packaged in multiple jar/war's - it
> is based on packages.
>
> say for project 2
> - org/foo/common/* goes in both project2.jar & project2.war
> - org/foo/webapp/* goes in project2.war
>
> say for project 3
> - org/foo/common/* goes in both project3_war1.war & project3_war2.war
> - org/foo/webapp1/* goes in project3_war1.war
> - org/foo/webapp2/* goes in project3_war2.war
> - typically same resources but different web.xml's
>
> So this should be as simple as using the idiom you mentioned and
> specifying different packagePaths for the packageTask's right?

Yes, that should work. You'll need to do something like:

val warArtifact1 = Artifact(organization % "project3_war1" % version, "war",
"war")

or similar since the jar ID is different than the project ID.

Projects in sbt are lightweight enough that I often make everything a
subproject (common, webapp1, webapp2). Logging can be less readable though.

> Btw, got my existing ivy.xml & ivysettings.xml working too! Thanks
> again! It was too easy :)

Great!

> - Saurabh
>
> P.S. have you thought about moving your source code to git?
> exluding .svn's from almost everything you do is so frustating! - how
> do you manage it? :)

My projects are all at http://github.com/harrah now.

-Mark
Reply all
Reply to author
Forward
0 new messages