How to exclude unnecessary unmanaged dependencies from packaging? - scala

I want to create a standalone version of my application and was wondering how i could exclude
an unmanaged *.jar file to be packaged. It's the "mariaDB4j-2.0-SNAPSHOT.jar" file I solely
use in tests which is about 56MB huge.
I tried to put the jar file into a custom directory 'test/lib'. Unfortunately, this did not exclude mariaDB4j from packaging.
unmanagedBase <<= baseDirectory { base => base / "test/lib" }
unmanagedJars in Test <<= unmanagedBase map { base => (base ** "mariaDB4j-2.0-SNAPSHOT.jar").classpath }
Any thoughts on this?
Cheers
Oliver

I think you want to add to the testing classpath.
Two things:
You can check out what's on the classpath using show test:fullClasspath to make sure your jar is on there. Using inspect test:fullClasspath will show you what the dependencies used for testing are.
I think you can directly add your jar to the classpath via:
fullClasspath in Test += Attributed.blank(baseDirectory.value / "test/lib/mariaDB4j-2.0-SNAPSHOT")
Hope that helps!

This works, but it looks a little overstated. Changing the base directory of the unmanaged dependencies, include the file to the test's and exclude it from compile.
unmanagedBase <<= baseDirectory { base => base / "test/lib" }
unmanagedJars in Test <<= unmanagedBase map { base => (base ** "mariaDB4j-2.0-SNAPSHOT.jar").classpath }
excludeFilter in unmanagedJars in Compile := "mariaDB4j-2.0-SNAPSHOT.jar"
excludeFilter in unmanagedJars in Compile ~= { _ || "mariaDB4j-2.0-SNAPSHOT.jar" }

don't use unmanaged dependencies
if you want to keep the jar in your source repository just use a file based maven repository in your source tree with
resolvers += "Private Maven Repository" at file(".").toURI.toURL+"/repository"
then mvn install MariaDB4j locally and copy resulting stuff from maven cache to $yourproject/repository
and use the dependency like a regular managed dependency

Related

How do I add additional file to class path which is not java or scala file using SBT configuration?

How do I add additional file to classpath which is not java or scala file using SBT configuration ?
My source folder is defined like this
javaSource in Compile := baseDirectory.value / "src"
I have jawr.properties in the root of my /src folder. I'd like this file to be copied to WEB-INF/classes of my packaged app. I tried changing filter to
includeFilter in (Compile, unmanagedSources) := "*.java" || "*.scala" || "jawr.properties",
But it fails on sbt compile because it tries to compile it as java file.
I'm on SBT 0.13.6
The philosophy of SBT is to work by convention (and not by configuration) as much as possible. So the most straightforward solution, in many cases, isn't to look for the correct setting to tell SBT where your files are... But rather to figure out where SBT already expects to find them. You can check this page of the "getting started with SBT" guide for the basics.
For resource files that needs to be packaged together with compiled classes, the default directory is src/main/resources (a convention borrowed from Maven, like most of SBT's default directory structure). Similarly, files in src/test/resources are added to the classpath but only during tests.
If, for some reason, you want to use non-standard directories, you will want to have a look at this page of the documentation. For resources, the key to modify is resourceDirectory:
// resources in `resources` instead of `src/main/resources` :
resourceDirectory in Compile := baseDirectory.value / "resources"
// test resources in `test-resources` instead of `src/test/resources` :
resourceDirectory in Test := baseDirectory.value / "test-resources"
You want it be an unmanaged resource (not source)
unmanagedResourceDirectories in Compile := Seq(baseDirectory.value / "src")
includeFilter in unmanagedResources := "jawr.properties"

Multiple project dependencies in SBT native packager

I am using the SBT native packager plugin (https://github.com/sbt/sbt-native-packager) for a project composed of multiple modules.
In my SBT settings I have:
lazy val settings = packageArchetype.java_application ++ Seq(
...
// Java is required to install this application
debianPackageDependencies in Debian ++= Seq("java2-runtime"),
// Include the module JAR in the ZIP file
mappings in Universal <+= (packageBin in Compile) map { jar =>
jar -> ("lib/" + jar.getName)
}
)
The problem is that the generated ZIP, or DEB for example, do not seem to include my project's modules dependencies. There is only the final module JAR, and the libraries used in it, but not the modules that it depends on.
Do you know how could I fix that?
Found a solution to my problem:
I needed to add exportJars := true in my settings for all my internal dependencies to be embedded in the package.

Add an extra lib folder dependency to build sbt in a lift project

I have an external java project that my lift project depends on. I have been able to add the dependency to the classes in that project by adding the following line to my sbt:
unmanagedClasspath in Compile += file("[Path to My Project]/classes")
But this project also has a lib folder with a set of jars that it references and I cannot figure out what the correct syntax should be to add these dependencies. Have tried the following but it does not work:
unmanagedJars in Compile += file("[Path to My Project]/lib/*.jar")
Any pointers greatly appreciated
Regards
Des
You can use sbt's Path API to get all jars in your directory.
Edit: a shorter version using .classpath:
unmanagedJars in Compile ++=
(file("[Path to My Project]/lib/") * "*.jar").classpath
which is more or less equivalent to:
unmanagedJars in Compile ++=
Attributed.blankSeq((file("[Path to My Project]/lib/") * "*.jar").get)
(Attributed is necessary because unmanagedJars is a setting of type Seq[Attributed[File]] and not Seq[File])

sbteclipse additional source folders

How do I configure an extra folder for sbteclipse to include? I have a default sbt directory layout with an additional it/scala folder. I want that folder to be included in the generated .project and .classpath files, but I don't know how to do that....
You can achieve this for example by adding something like the following to your build.sbt:
unmanagedSourceDirectories in Compile <++= baseDirectory { base =>
Seq(
base / "some/subdir/src"
)
}
For details of the relation between unmanaged-sources, unmanaged-source-directories and scala-source you might want to check the documentation. After exporting the eclipse project from sbt, you should find a corresponding entry in your .classpath file, like:
<classpathentry output="target/scala-2.9.1/classes" path="some/subdir/src" kind="src"></classpathentry>
there can be case in which you may just want to add a folder say conf to the eclipse classpath which contains configurations required at runtime. Below is the trick -
unmanagedJars in Compile ++= {
val confBase = (baseDirectory.value ** "conf")
confBase.classpath
}
if you want to add, e.g., the folder src/folderXYZ, then add to build.sbt:
Compile / unmanagedSourceDirectories += baseDirectory.value / "src/folderXYZ"

Remove entry from classpath after compile

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.
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.
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"