Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove entry from classpath after compile

Tags:

scala

sbt

I have a legacy war project that depends on a jar project, the jar project needs to add a few unmanaged jars to the classpath for compilation. But these jars should not be packaged in the war. So my question is how do I remove these entries from the fullClasspath. The following won't work:

val excludeFilter = "(servlet-api.jar)|(gwt-dev.jar)|(gwt-user.jar)"
val filteredCP = cp.flatMap({ entry =>
   val jar = entry.data.getName()
   if (jar.matches(excludeFilter)) {
     Nil
   } else {
     Seq(entry)
   }
})
fullClasspath in Runtime = filteredCP

I am pretty sure there must be simple way to do this but so far it has eluded me.

Edit: Based on Pablo's sugestion to use the managed classpath instead of the unmanaged I can rephrase the question as: how do you add local jars to the managedClasspath. My jars are placed in a local folder with a (very) nonstandard layout:

lib/testng.jar
lib/gwt/2.3/gwt-user.jar
lib/jetty/servlet.jar

So basically I am looking for something like:

libraryDependencies += "testng" % "provided->test"
libraryDependencies += "gwt" % "2.3" % "gwt-user" % "provided->compile"
libraryDependencies += "jetty" % "servlet" % "provided->default"

allowing me to grab jars from my own local lib folder.

like image 256
Lars Tackmann Avatar asked Oct 20 '11 00:10

Lars Tackmann


2 Answers

Some information is provided on the Classpaths page, but it is not very clear or detailed. The information is also available using the inspect command, described on the Inspecting Settings page.

Basically, for a configuration X, in a short-hand notation:

// complete, exported classpath, such as used by 
//   'run', 'test', 'console', and the war task
fullClasspath in X =
  dependencyClasspath in X ++ exportedProducts in X

// classpath only containing dependencies, 
//   used by 'compile' or 'console-quick', for example
dependencyClasspath in X =
  externalDependencyClasspath in X ++ internalDependencyClasspath in X

// classpath containing only dependencies external to the build
//  (as opposed to the inter-project dependencies in internalDependencyClasspath)
externalDependencyClasspath in X =
  unmanagedClasspath in X ++ managedClasspath in X

// the manually provided classpath
unmanagedClasspath in X =
  unmanagedJars for X and all configurations X extends, transitively

So, normally, when you want to add unmanaged libraries, you add them to unmanagedJars. For example, if you add libraries to unmanagedJars in Compile, then sbt will correctly include the libraries on the unmanagedClasspath for Compile, Runtime, and Test.

However, you want explicit control here. Add the libraries only to the unmanagedClasspath you want the jars on, which is unmanagedClasspath in Compile. For example, in sbt 0.11.0+:

unmanagedClasspath in Compile <++= baseDirectory map { base =>
  val lib = base / "lib"
  Seq(
    lib / "testng.jar",
    lib / "gwt/2.3/gwt-user.jar",
    lib / "jetty/servlet.jar"
  )
}

Assuming the war plugin uses the Runtime classpath, those jars will only show up on the compile classpath and not in the war.

like image 97
Mark Harrah Avatar answered Oct 15 '22 03:10

Mark Harrah


sbt supports ivy-like configurations, and implements maven basic scopes.

If you want to use some jars in your compilation classpath but don't want to ship them, I guess the provided scope is for you:

libraryDependencies += "org.example" % "example" % "1.0" % "provided->compile"
like image 33
Pablo Fernandez Avatar answered Oct 15 '22 03:10

Pablo Fernandez