Scala & XSBT - share part of build classpath with project classpath - scala

First of all I'm very new to Scala, SBT and Vaadin.
I'm trying to make an Scala & Vaadin application with Timeline addon. I had to put Timeline jar (unmanaged dependency) and Vaadin dependency under build project (project/) so I can compile it during build (well, by calling vaadin task). How can I merge vaadin-timeline-agpl-3.0-1.2.3.jar and Vaadin dependency into vaadinTest project without duplicating jar and dependency? Below is my project structure. Thank you. By the way, I already tried existing Vaadin plugins but they suck (all I need to do is to compile widgetset).
This is my project structure:
vaadinTest/
project/
lib/vaadin-timeline-agpl-3.0-1.2.3.jar
build.sbt
ProjectBuild.scala
src/
vaadinTest/project/build.sbt:
libraryDependencies ++= Seq(
"com.google.gwt" % "gwt-user" % "2.4.0",
"com.google.gwt" % "gwt-dev" % "2.4.0",
"com.vaadin" % "vaadin" % "6.7.4"
)
vaadinTest/project/ProjectBuild.scala:
import com.google.gwt.dev.Compiler
import sbt._
import Keys._
object ProjectBuild extends Build {
val deps = Seq(
"org.eclipse.jetty" % "jetty-server" % "8.1.0.RC5",
"org.eclipse.jetty" % "jetty-webapp" % "8.1.0.RC5",
"org.eclipse.jetty" % "jetty-servlet" % "8.1.0.RC5",
)
val vaadinTest = Project(
"vaadinTest", file("."), Defaults.defaultSettings
++ Seq(libraryDependencies ++= deps)
++ Seq(vaadinTask)
)
val vaadin = TaskKey[Unit]("vaadin")
val vaadinTask = vaadin := {
Compiler.main(Array("-war", "src/main/webapp/VAADIN/widgetsets",
"com.vaadin.addon.timeline.gwt.TimelineWidgetSet"))
}
}

Your question mentions a "plugin" project, but I can't see that project in your project structure or ProjectBuild.scala?
In any case, you can add additional directories to your classpath by modifying the dependencyClasspath setting. This is documented here (see the "Unmanaged dependencies" section).

Related

Exception in thread "main" java.lang.NoClassDefFoundError: org/rogach/scallop/ScallopConf

As I want to execute the jar generated by my scala project in the Command Line Interface, I get the following problem:
Exception in thread "main" java.lang.NoClassDefFoundError: org/rogach/scallop/ScallopConf
Although in the dependency file I mentionned scallop dependency as follow
import sbt._
object Dependencies {
lazy val betterFiles = "com.github.pathikrit" %% "better-files" % "3.7.0"
lazy val scalaz = "org.scalaz" %% "scalaz-core" % "7.2.27"
lazy val scallop = "org.rogach" %% "scallop" % "3.1.5"
// -- Logging
lazy val scalaLogging = "com.typesafe.scala-logging" %% "scala-logging" % "3.9.2"
lazy val slf4jBackend = "org.slf4j" % "slf4j-simple" % "1.7.26"
// -- Testing
lazy val scalaTest = "org.scalatest" %% "scalatest" % "3.0.5"
}
My build.sbt file is the following:
import Dependencies._
ThisBuild / scalaVersion := "2.12.5"
ThisBuild / sbtVersion := "1.2.6"
ThisBuild / version := "0.1.0-SNAPSHOT"
lazy val root = (project in file("."))
.settings(
name := "phenix-challenge",
libraryDependencies ++= Seq(
betterFiles,
scalaz,
scallop,
scalaLogging,
slf4jBackend % Runtime,
scalaTest % Test
)
)
If you have an Idea that could resolve my Issue please HELP!
Many thanks in advance
To execute the jar generated by your scala project in the Command Line Interface you can use sbt plugin to assembly a fat-jar including your libraries/dependencies. Having such jar you would be able to run your app via java -jar ...
There are several SBT plugins for build a fat-jar. Perhaps the easiest one would be the sbt-assembly.
Add this plugin to file project/plugins.sbt (create this file if needed):
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.9")
Now use sbt to build a fat-jar:
sbt assembly
Then run via java -jar YouMainClass
Another option is to use pure sbt to run Main class using command sbt run, then you do really need to build a fat-jar.

SBT Compiler Plugin as Transitive Dependency

I have a library that uses the macro paradise plugin (referred to as macro-provider library). In the build.sbt,
addCompilerPlugin("org.scalamacros" % "paradise" % "2.0.0" cross CrossVersion.full)
to gain access to the macro annotations.
When adding the macro library as a libraryDependency to a separate project (referred to as macro-consumer project), the annotations are present, but the macro implementation is never called. Adding the macro paradise compiler plugin to the macro-consumer project libraryDependencies solves the problem.
Is it possible to include compiler plugins as transitive dependencies? This would free consumers of the macro library from adding the required plugin.
Update #1:
The addCompilerPlugin helper adds the dependency to the libraryDependencies and sets the dependency with a configuration = Some("plugin->default(compile)") within the macro-provider library.
Adding the paradise dependency in the libraryDependencies of the macro-provider library causes the artifact to show up in the macro-consumer project. It does not add the dependency as a compiler plugin.
Update #2:
Setting autoCompilerPlugins := true in the macro-consumer project in conjunction with Update #1 does not resolve the issue.
The only way I found to resolve this issue was by adding a sbt-plugin sub-module that includes the settings required. The plugin is very basic,
package fixme
import sbt._
import Keys._
object Plugin extends sbt.Plugin {
val paradiseVersion = "2.0.0"
val fixmeVersion = "1.4"
val fixmeSettings: Seq[Setting[_]] = Seq(
resolvers += "tysonjh releases" at "http://tysonjh.github.io/releases/",
libraryDependencies <++= (scalaVersion) { v: String ⇒
(if (v.startsWith("2.10")) List("org.scalamacros" %% "quasiquotes" % paradiseVersion % "compile")
else Nil) :+
"org.scala-lang" % "scala-reflect" % v % "compile" :+
"com.tysonjh" %% "fixme" % fixmeVersion % "compile"
},
addCompilerPlugin("org.scalamacros" % "paradise" % paradiseVersion cross CrossVersion.full))
}
This can be used by including in your project/plugins.sbt,
resolvers += "tysonjh releases" at "http://tysonjh.github.io/releases/"
addSbtPlugin("com.tysonjh" % "sbt-fixme" % "1.4")
and the build.sbt file,
fixmeSettings
The sbt-plugin settings add the macro paradise plugin as a compiler dependency and the macro implementation as a library dependency.

Have sbt put javadocs and sources of dependencies on the class path

When using a managed dependency, I can tell sbt to download the javadocs and sources:
"mygroup" % "mymodule" % "myversion" withJavadoc() withSources()
But these jars don't seem to be on the runtime classpath?
What I would like to do, is access the javadocs and sources from my application. Can I make these jars appear as managed resources, such that I could do
ClassLoader.getSystemClassLoader.getResource("/my/package/MyDependency.scala")
?
You can do this by adding a classifier.
For a given library dependency, add a javadoc or sources classifer:
libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.0.6" classifier "javadoc"
libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.0.6" classifier "sources"
Then, access its contents from the classpath:
val docStream = getClass.getResourceAsStream("""/scalaz/Monad$.html""")
val doc = io.Source.fromInputStream(docStream).mkString
println(doc)
Here's a working example: https://earldouglas.com/ext/stackoverflow.com/questions/22160701/

Explain Build.scala in play framework

Can somebody explain the syntax for Build.scala in detail? For example, I have the following Build.scala:
import sbt._
import Keys._
import play.Project._
object Build extends sbt.Build {
val appName = "myapp"
val appVersion = "1.0"
val appDependencies = Seq(
"postgresql" % "postgresql" % "9.1-901-1.jdbc4",
javaCore,
javaJdbc,
javaEbean,
"org.json" %"org.json" % "chargebee-1.0",
"org.reflections" % "reflections" % "0.9.8",
"org.mockito" % "mockito-all" % "1.9.5" % "test"
)
val main = play.Project(appName, appVersion, appDependencies).settings(
libraryDependencies += "com.jolbox" % "bonecp" % "0.8.0-rc2-SNAPSHOT",
resolvers += Resolver.url("sbt-plugin-snapshots", new URL("http://repo.scala-sbt.org/scalasbt/sbt-plugin-snapshots/"))(Resolver.ivyStylePatterns),
resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/"
)
}
How do I match the appDependencies with the resolvers? Or how do I know what resolvers I need to add for what appDependencies? Where do I look in the resolver's repo? What is libraryDependencies? How are they different from appDependencies?
Thanks.
There are a few things we need to disentangle here.
Let's first distinguish between an sbt build file and Build.scala. While the build file is exactly like a Maven pom or a Gradle build file, think of Build.scala as a build capability with the full power and expressiveness of Scala because it is a Scala class like any other. I believe the gap between the two has narrowed though with the latest version of sbt.
Now in both sbt and Build.scala, you have the notion of library dependencies, which are the jar libraries containing code you can use for your projects. These libraries can be found in lots of places--Maven repositories, the local file system, etc. You use resolvers to specify those locations.
So you tell both which jars you need and where to find them.
As for appDependencies, that's not actually a thing. As I said, Build.scala is a class like any other, and appDependencies is just a variable name. It just makes sense to use that name because that Seq is what you will pass to the Project constructor.

LIFT setup for web project: generate with mvn, and manage with sbt

I am new to LIFT, and I am trying to find a reliable instructions how to generate and manage LIFT web project with maven and sbt respectively. Can someone please direct me (or provide here) to the up to date instructions how to setup sbt for the maven generated project? From every post what I've red, it looks like the best setup for the LIFT projects: generate with mvn, manage with sbt. Will you agree? (I cannot generate LIFT/web project with sbt. Right? SBT is only good for managing it. Right? ) Every instructions I tried are out of date though. (I obviously can simply download and un-tar the archetype project, but I want to find a more fundamental approach for managing the environment ) Thanks.
While I'm using lift I don't need a maven at all, just SBT. So, it is very useful to read SBT Getting Started section. Also lift wiki contains some information. But be sure that you read material related to the proper SBT version. And finally, you can pay attention to my lift project template on github.
Good Luck with Lift! It's awesome ;)
By following question in you comment I put here some common config from my projects.
So, that is ./project/build.scala as alternative to ./build.sbt
import sbt._
import Keys._
import com.github.siasia._
import PluginKeys._
import WebPlugin._
import WebappPlugin._
object LiftProjectBuild extends Build {
override lazy val settings = super.settings ++ buildSettings
lazy val buildSettings = Seq(
organization := "com.yourorganization",
version := "0.1-SNAPSHOT",
scalaVersion := "2.9.1")
def yourWebSettings = webSettings ++ Seq(
// If you are using jrebel
scanDirectories in Compile := Nil
)
lazy val shade = Project(
id = "project-name",
base = file("."),
settings = defaultSettings ++ yourWebSettings)
lazy val defaultSettings = Defaults.defaultSettings ++ Seq(
name := "project-name",
resolvers ++= Seq(
"Typesafe Repo" at "http://repo.typesafe.com/typesafe/releases",
"Java.net Maven2 Repository" at "http://download.java.net/maven/2/"),
libraryDependencies ++= {
val liftVersion = "2.4-M5"
Seq(
"net.liftweb" %% "lift-webkit" % liftVersion % "compile",
"org.eclipse.jetty" % "jetty-webapp" % "7.5.4.v20111024" % "container",
"org.squeryl" %% "squeryl" % "0.9.5-SNAPSHOT" % "compile",
"ch.qos.logback" % "logback-classic" % "1.0.0" % "compile",
"org.scalatest" %% "scalatest" % "1.6.1" % "test",
"junit" % "junit" % "4.10" % "test")
},
// compile options
scalacOptions ++= Seq("-encoding", "UTF-8", "-deprecation", "-unchecked"),
javacOptions ++= Seq("-Xlint:unchecked", "-Xlint:deprecation"),
// show full stack traces
testOptions in Test += Tests.Argument("-oF")
)
}
./project/build.properties
#Project properties
sbt.version=0.11.1
./project/plugins.sbt
resolvers += Classpaths.typesafeResolver
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse" % "1.5.0")
libraryDependencies <+= sbtVersion(v => "com.github.siasia" %% "xsbt-web-plugin" % (v+"-0.2.10"))
Having these three files are enough to configure sbt.
And of course you can run your application by calling container:start
Your mileage may vary, but my experience with sbt has been less than stellar (out-of-date docs, breakage on version changes, etc). The recent improvements to the eclipse scala IDE and corresponding maven and jrebel plugins make it a clear winner compared to using sbt.
If you follow the instructions, you'll get the ability to build/package at the command line, but superior support for eclipse features and fast development.
See the sample project setup at:
https://github.com/awkay/lift_squeryl_demo