Configuring Lift with xsbt-web-plugin: finding the main method class - scala

I'm attempting to create 'from scratch' a Lift web application and running into some difficulty. I started with xsbt-web-plugin version 2.1, and managed to get it working with a simple Jetty servlet. Then I tried to integrate information from the Lift Cookbook.
This is my build.sbt:
organization := "ford.nathaniel"
name := "Lift From Scratch"
version := "0.1-SNAPSHOT"
scalaVersion := "2.11.7"
libraryDependencies += "javax.servlet" % "javax.servlet-api" % "3.0.1" % "provided"
enablePlugins(JettyPlugin)
libraryDependencies ++= {
val liftVersion = "3.0-M8"
Seq(
"net.liftweb" %% "lift-webkit" % liftVersion % "compile",
"org.eclipse.jetty" % "jetty-webapp" % "9.2.1.v20140609" % "container, test",
"org.eclipse.jetty" % "jetty-plus" % "9.2.1.v20140609" % "container, compile"
)
}
I have a (one line) project/plugins.sbt:
addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "2.1.0")
I lifted the Boot.scala file directly from the above-linked Cookbook and placed it in src/main/scala/bootstrap, and similarly src/main/webapp/WEB-INF/web.xml. I can run sbt from the command line, and it loads cleanly, but when I try container:start...
> container:start
[info] starting server ...
[success] Total time: 0 s, completed Mar 3, 2016 9:52:25 PM
Error: Could not find or load main class
>
I am unclear on how sbt is meant to find Lift's main class. I looked through a lot of older versions of sbt configuration, which differ because earlier versions use earlier versions of the xsbt plugin. (Specifically, you see things like seq(webSettings :_*) - what does that even do?) I pulled recent versions of jetty-webapp and jetty-plus, so I don't think that's the problem. On the other hand, none of those configurations make clear how Lift figures out where Boot.scala is, and in turn I'm not sure how to write the configuration such that it knows how to bootstrap the framework.
One main difference between the two sources is that the new Jetty README configures the servlet like this:
libraryDependencies += "javax.servlet" % "javax.servlet-api" % "3.0.1" % "provided"
enablePlugins(JettyPlugin)
containerLibs in Jetty := Seq("org.eclipse.jetty" % "jetty-runner" % "9.2.1.v20140609" intransitive())
containerMain in Jetty := "org.eclipse.jetty.runner.Runner"
This seems to configure a SettingKey on the Jetty plugin, and point to the Jetty runner to kick off the servlet. However, given that I'm not running through a standard servlet, but through a filter configured to point to the Lift app in web.xml, this seemed like something I should remove.
Clearly I'm misunderstanding something. How do I diagnose why the xsbt-web-plugin is not picking up the Lift framework? It seems like either there is configuration-by-convention I can't find or I need to do something special with Jetty to point to the web.xml filter. Can anyone help clarify how to diagnose this, or elucidate how the two libraries should work together?

The following build.sbt ended up working for me when executed as jetty:start (rather than container:start). It appears that net.liftweb needs to be included as a libraryDependency rather than in the containerLibs, and that the Jetty plugin manages the container. I don't understand particularly, though, what the difference is or how to diagnose this in the future (ended up just trying a lot of different things).
Notably, though, the Boot.scala class of Lift is picked up automagically if the web.xml file is set up to use a Lift filter.
organization := "ford.nathaniel"
name := "Lift From Scratch"
version := "0.1-SNAPSHOT"
scalaVersion := "2.11.7"
libraryDependencies += "javax.servlet" % "javax.servlet-api" % "3.0.1" % "provided"
//logLevel := Level.Debug
enablePlugins(JettyPlugin)
libraryDependencies ++= {
val liftVersion = "3.0-M8"
Seq(
"net.liftweb" %% "lift-webkit" % liftVersion % "compile"
)
}
containerLibs in Jetty := {
val liftVersion = "3.0-M8"
Seq(
"org.eclipse.jetty" % "jetty-webapp" % "9.2.1.v20140609",
"org.eclipse.jetty" % "jetty-plus" % "9.2.1.v20140609",
"org.eclipse.jetty" % "jetty-runner" % "9.2.1.v20140609" intransitive()
)
}
containerMain in Jetty := "org.eclipse.jetty.runner.Runner"

Related

How to define Scala API for Kafka Streams as dependency in build.sbt?

I am trying to start a new SBT Scala project and have the following in build.sbt file:
name := "ScalaKafkaStreamsDemo"
version := "1.0"
scalaVersion := "2.12.1"
libraryDependencies += "javax.ws.rs" % "javax.ws.rs-api" % "2.1" artifacts(Artifact("javax.ws.rs-api", "jar", "jar"))
libraryDependencies += "org.apache.kafka" %% "kafka" % "2.0.0"
libraryDependencies += "org.apache.kafka" % "kafka-streams" % "2.0.0"
So according to the GitHub repo, in 2.0.0 I should see the Scala classes/functions etc etc that I want to use, however they just don't seem to be available. Within IntelliJ I can open up the kafka-streams-2.0.0.jar, but I don't see any Scala classes.
Is there another JAR I need to include?
Just while we are on the subject of extra JARs, does anyone know what JAR I need to include to be able to use the EmbeddedKafkaCluster?
The artifact you need is kafka-streams-scala:
libraryDependencies += "org.apache.kafka" %% "kafka-streams-scala" % "2.0.1"
(please use 2.0.1, or even better 2.1.0, as 2.0.0 has some scala API bugs)
To answer your latter question, it's in the test-jar, which you can address using a classifier:
libraryDependencies += "org.apache.kafka" %% "kafka-streams" % "2.0.1" % "test" classifier "test"
But note that this is an internal class and subject to change (or removal) without notice. If at all possible, it's highly recommended that you use the TopologyTestDriver in the test-utils instead:
libraryDependencies += "org.apache.kafka" %% "kafka-streams-test-utils" % "2.0.1" % "test"
It looks like you face the issue of unresolved javax.ws.rs-api dependency that happens with some Java projects that are direct or transitive dependencies of Scala projects that use sbt. I've faced it with Scala projects that use Apache Spark and recently with Kafka Streams (with and without the Scala API).
A workaround that has worked fine for me is to simply exclude the dependency and define it again explicitly.
excludeDependencies += ExclusionRule("javax.ws.rs", "javax.ws.rs-api")
libraryDependencies += "javax.ws.rs" % "javax.ws.rs-api" % "2.1.1"
Make sure that you use the latest and greatest of sbt (i.e. 1.2.7 as of the time of this writing).
With that said, the dependencies in build.sbt should be as follows:
scalaVersion := "2.12.8"
val kafkaVer = "2.1.0"
libraryDependencies += "org.apache.kafka" % "kafka-streams" % kafkaVer
libraryDependencies += "org.apache.kafka" %% "kafka-streams-scala" % kafkaVer
excludeDependencies += ExclusionRule("javax.ws.rs", "javax.ws.rs-api")
libraryDependencies += "javax.ws.rs" % "javax.ws.rs-api" % "2.1.1"
Within IntelliJ I can open up the kafka-streams-2.0.0.jar, but I don't see any Scala classes. Is there another JAR I need to include?
The following dependency is all you need:
libraryDependencies += "org.apache.kafka" %% "kafka-streams-scala" % kafkaVer
You can also use following workaround, that works in my case - more details
here
import sbt._
object PackagingTypePlugin extends AutoPlugin {
override val buildSettings = {
sys.props += "packaging.type" -> "jar"
Nil
}
}

How to attach sources to scala sbt project at Intellij Idea?

I am new at scala. And for start I want to use Intellij 13.1.5 IDE.
However IDE can't attach sources. Here is how it looks for AnyVal:
Search at internet can't find any source.
I tried Attach sources and attach unpacked scala archive. It doesn't work either.
UPDATE:
Here is sbt configuration:
name := "scalatest-selenium"
version := "1.0"
scalaVersion := "2.11.1"
libraryDependencies ++= Seq(
"net.sourceforge.htmlunit" % "htmlunit" % "2.14",
"org.seleniumhq.selenium" % "selenium-java" % "2.42.2",
"org.scalacheck" % "scalacheck_2.10" % "1.11.4" % "test",
"org.scalatest" % "scalatest_2.11" % "2.2.0" % "test"
)
testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-u", "target/test-reports")
How to solve this trouble?
I get rid of this trouble at the following way:
removed the .sbt directory in your Home Folder.
When you run sbt again, the new folder is created in the correct format and the error goes away.

Can't compile 2.2 to 2.3 Migration

I have been fighting with this for the past few hours and I haven't made any headway at all. It seems no matter what I do, I keep getting the same error.
java.lang.NoClassDefFoundError: play/Project$
My build.sbt
name := "appname"
version := "1.0-SNAPSHOT"
libraryDependencies ++= Seq(
jdbc,
anorm,
cache,
filters,
"org.postgresql" % "postgresql" % "9.3-1100-jdbc4",
"org.mindrot" % "jbcrypt" % "0.3m",
"org.webjars" %% "webjars-play" % "2.3.0-2",
"org.webjars" % "foundation" % "5.3.0",
"org.scalaj" %% "scalaj-http" % "0.3.16"
)
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.10.4"
I have also tried this build.sbt
object ApplicationBuild extends Build {
val appName = "appname"
val appVersion = "1.0-SNAPSHOT"
val appDependencies ++= Seq(
jdbc,
anorm,
cache,
filters,
"org.postgresql" % "postgresql" % "9.3-1100-jdbc4",
"org.mindrot" % "jbcrypt" % "0.3m",
"org.webjars" %% "webjars-play" % "2.3.0-2",
"org.webjars" % "foundation" % "5.3.0",
"org.scalaj" %% "scalaj-http" % "0.3.16"
)
val main = Project(appName, file(".")).enablePlugins(play.PlayScala).settings(
scalaVersion := "2.10.4",
version := appVersion,
libraryDependencies ++= appDependencies
)
}
As well as different tweaks and modifications. Always the same error. The build.properties is set to sbt.version=0.13.5
plugins.sbt
logLevel := Level.Debug
// The Typesafe repository
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
// Use the Play sbt plugin for Play projects
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.4")
After running Patrick Mahoney's suggestion and making sure I removed the import.
Errors:
[error] java.lang.NoClassDefFoundError: play/Project$
[error] Use 'last' for the full log.
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? q
me#me-desktop:~/Projects/appname$ sbt --version
sbt launcher version 0.13.6
me#me-desktop:~/Projects/appname$ find . | grep -r "play.Project"
me#me-desktop:~/Projects/appname$ find . | grep -r "play/Project"
Try cleaning your build project compiled outputs:
rm -rf project/target
or
$> sbt "reload plugins" clean
(in addition to applying James' answer)
Thanks to James and Patrick, but I found the problem. The problem was in the activator-sbt-echo-play-shim.sbt file in the /project directory.
It contained the following:
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "0.1.1.3")
I created a second blank 2.3.4 app using Activator and it's activator-sbt-echo-play-shim.sbt listed:
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.5")
So I updated the one in my project to 1.5 and deleted the idea and eclipse .sbts for good measure and the app was finally able to compile. It auotmatically updated the above to:
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.5.2")
Now I have other, more expected, issues I need to work out (like anorm). But I'm now able to compile it and get those errors to start working them out. I did not think these files were part of the activator/sbt compile, but I guess they were. I thought they were for debugging. But they made the difference and the changes above worked.
Thanks again to everyone for their help.
Make sure you've updated project/build.properties to have sbt version 0.13.5. Then, remove import play.Project._, it's not needed. That should work.

Lift-2.5 build issue in sbt/Eclipse

I'm trying to get a mac development environment operational around Eclipse, SBT and Lift. Once installed as near to proper as I'm able to manage, I can run the app from sbt, but Eclipse still reports problems.
Eclipse is the Scala IDE build of Eclipse SDK, Build id:
3.0.1-vfinal-20130711-0941-Typesafe.
SBT is macport installed: sbt #0.12.3_1
Lift is the most recent 2.5 zip (This from this page.)
This tutorial was used for initial guidance. However, this tutorial is for a somewhat earlier version of Lift and associated dependencies, including the sbt-eclipse plugin. What I landed at was the 2.2 version of the eclipse plugin, and in my ~/.sbt/plugin/build.sbt I have this single line:
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.2.0")
Per the tutorial instructions, I'm pulling over the source file (of Lift's lift_basic project specifically) and modifying my project build.sbt to the following:
name := "sample project"
organization := "com.nford"
version := "0.1-SNAPSHOT"
scalaVersion := "2.10.1"
EclipseKeys.createSrc := EclipseCreateSrc.Default + EclipseCreateSrc.Resource
libraryDependencies ++= {
val liftVersion = "2.5"
Seq(
"net.liftweb" %% "lift-webkit" % liftVersion % "compile",
"net.liftweb" %% "lift-mapper" % liftVersion % "compile",
"org.mortbay.jetty" % "jetty" % "6.1.26" % "test",
"junit" % "junit" % "4.7" % "test",
"ch.qos.logback" % "logback-classic" % "0.9.26",
"org.scala-tools.testing" %% "specs" % "1.6.9" % "test",
"com.h2database" % "h2" % "1.2.147"
)
}
Importing the project into Eclipse works fine, except for 20 errors, mostly around the test cases. These include, but are not limited to:
object eclipse is not a member of package org
not found: value JQueryModule
Googling errors like this I see a lot of stuff from a year ago, largely which seems to be a package mismatch. From this research I was able to make some changes (reflected in the build.sbt, etc. above):
Upgrade scala version to 2.10.1
Upgrade lift version to 2.5
Use sbt-eclipse 2.2 plugin
Yet I'm still receiving these errors. To verify; I have updated, from the sbt terminal console, and run the eclipse build from there as well. I imported the project to Eclipse after that point. I am unable to determine where the package mismatches are coming from (or indeed why they can't be discovered, since they exist on the system and sbt can find them). Is this an eclipse IDE plugin weakness, or a solvable problem? Or, in my obvious newness to Scala Lift, am I missing something really obvious?
JQueryModule is not part of Lift. You need to add:
"net.liftmodules" %% "lift-jquery-module_2.5" % "2.3"
Jetty:
"org.eclipse.jetty" % "jetty-webapp" % "8.1.7.v20120910" % "container,compile",
"org.eclipse.jetty" % "jetty-servlets" % "8.1.7.v20120910" % "container,compile",
"org.eclipse.jetty.orbit" % "javax.servlet" % "3.0.0.v201112011016" % "container,compile" artifacts Artifact("javax.servlet", "jar", "jar")
Specs2:
"org.specs2" %% "specs2" % "1.14"

Need help getting sbt 0.10 to choose a local copy of scala 2.9.1.final on Ubuntu

What I have so far:
.bashrc
2 PATH=/opt/scala-2.9.1.final/bin:$PATH
3 PATH=/opt/sbt:$PATH
So my scala-2.9.1.final version is in the /opt folder. The same goes with sbt 0.10.
I'm trying to get it to pick my 2.9.1.final instead of 2.8 whatever. I've tried looking.
What i've done so far is putting symbolic links in projectname/boot/ directory.
ln -s /opt/scala-2.9.1.final scala-2.9.1.final
But it doesn't seem to work? I've also tried this build.sbt (https://github.com/VonC/xsbt-template/blob/master/build.sbt) and change the version to 2.9.1.final.
How do I get sbt>console to use 2.9.1.final? And how does it build using 2.9.1.final?
This is what I get when I type sbt:
user#acomputer:~/project/sbt$ sbt
[info] Set current project to default-295917 (in build file:/home/user/project/sbt/)
>
Thank you for your time.
I'm not experienced sbt user and may only suggest. Seems sbt 0.10.x use scala 2.8.1 itself, so I think sbt console is working by default with this version.
But you can build project with targetting on 2.9.1 by specify scala version in you build.sbt file: `scalaVersion := "2.9.1"' (see https://github.com/harrah/xsbt/wiki/Setup "ConfigureBuild")
And also you can switch scala version used by sbt console by typing "++ 2.9.1" in sbt prompt. (see https://github.com/harrah/xsbt/wiki/Running)
Here's an example of an build.sbt in one of my projects.
organization := "com.andyczerwonka"
name := "esi.intelligence"
version := "0.1"
scalaVersion := "2.9.1"
retrieveManaged := false
logLevel := Level.Info
jettyScanDirs := Nil
seq(webSettings :_*)
temporaryWarPath <<= (sourceDirectory in Compile)(_ / "webapp")
libraryDependencies ++= {
val liftVersion = "2.4-M4"
Seq(
"net.liftweb" %% "lift-webkit" % liftVersion % "compile->default",
"net.liftweb" %% "lift-mapper" % liftVersion % "compile",
"org.eclipse.jetty" % "jetty-webapp" % "7.3.0.v20110203" % "provided,jetty",
"junit" % "junit" % "4.8" % "test",
"ch.qos.logback" % "logback-classic" % "0.9.26",
"org.specs2" %% "specs2" % "1.6.1" % "test",
"net.databinder" %% "dispatch-http" % "0.8.5",
"com.h2database" % "h2" % "1.2.138"
)
}
Notice the 4th line. This tells sbt that I want to use 2.9.1. sbt will bring it down for me and use it.