I was wondering how should I setup Step so I can embed Jetty in it to
produce a single executable .WAR/.JAR file? Thanks very much!
- Rio
Let us know how it goes!
Alan
> To unsubscribe from this group, send email to
> step-user+unsubscribegooglegroups.com or reply to this email with the
> words "REMOVE ME" as the subject.
>
>
You might also look at
http://docs.codehaus.org/display/JETTY/Embedding+Jetty. That has
example code for embedding Jetty through Java (easily translatable to
Scala), which you could put in a main method. 'sbt package' will
package your code along with the Step library. You could distribute
the resulting jar, along with the Jetty dependencies (in lib_managed),
and probably a shell script to set up the class path and run your main
class. If you really need a single executable jar, you would need to
merge all the jars into one, which is beyond my sbt skills, but
probably possible.
--
Ross A. Baker
ba...@alumni.indiana.edu
Indianapolis, IN, USA
> I get a jar instead of a war when I run 'sbt package', which seems
> contrary to the sbt documentation. For my own usage, I am copying the
> Step jar into the WEB-INF/lib of a separately maintained web project,
> and building a war from that project.
I have the same result using the the project definition file coming with Step. I have to comment out the following lines:
import BasicScalaProject._
override def useMavenConfigurations = true
override def packageAction = packageTask(mainClasses +++ mainResources, outputPath, defaultJarName, packageOptions).dependsOn(compile) describedAs PackageDescription
then `sbt package` will produce a .war instead of a .jar. Don't know why, but it works for me now :|
On a side note: is it possible for you guys to host Step as a Maven repository, so I can just add the following line, for example,
val scalastep = "some.domain" % "step" % "version" % "provided->default"
to the sbt project file and let sbt download Step automatically? I guess that will be a lot easier for end users.
> You might also look at
> http://docs.codehaus.org/display/JETTY/Embedding+Jetty. That has
> example code for embedding Jetty through Java (easily translatable to
> Scala), which you could put in a main method. 'sbt package' will
> package your code along with the Step library. You could distribute
> the resulting jar, along with the Jetty dependencies (in lib_managed),
> and probably a shell script to set up the class path and run your main
> class. If you really need a single executable jar, you would need to
> merge all the jars into one, which is beyond my sbt skills, but
> probably possible.
Thanks Ross for the hint! I'm a completely newbie to the Java platform. It took me a whole afternoon to figure out all the tiny pieces of code necessary to produce a single executable jar (including all dependencies) running Step for me. Anyway, here is how (pretty long story):
Step 1: extend sbt project definition
Copy this piece of code from here <http://technically.us/git?p=sling.git;a=blob;f=project/build/AssemblyProject.scala;h=2231d9c9c54b5cde7d54c52c360cc778a41e4e3e;hb=HEAD
>
into your sbt project definition (/project/build/src/your project.scala) and extend your project with the AssemblyPorject, so you should have something like this:
class JettyStepProject(info: ProjectInfo) extends DefaultProject(info) with AssemblyProject {
override def mainClass = Some("com.riobard.JettyStep.JettyLauncher") # point this to your entry object
val jettytester = "org.mortbay.jetty" % "jetty-servlet-tester" % "6.1.22" % "provided->default"
val scalatest = "org.scalatest" % "scalatest" % "1.0" % "provided->default"
}
Then launch sbt or reload it if it is already running. This should give you a new sbt command called "assembly". Try that in the sbt interactive prompt and it should produce a ****-assembly-**.jar file in your sbt /target/scala-2.7.7 folder. All dependencies (like scala-library.jar) are included in this jar file and you can run it directly, e.g.
java -jar ***-assembly-**.jar
Step 2: launch Step as a servlet
Basically the Step class is a Servlet, we just need some glue code to launch an embedded Jetty server with this Servlet. (This simple code took me a lot of time to figure due to my lack of understanding of Jetty ...)
package com.riobard.JettyStep // remember this package in the sbt project definition
import org.mortbay.jetty.Server
import org.mortbay.jetty.servlet.{Context, ServletHolder}
import com.thinkminimo.step.TemplateExample // this is the example Step project
object JettyLauncher { // this is my entry object as specified in sbt project definition
def main(args: Array[String]) {
val server = new Server(8080)
val root = new Context(server, "/", Context.SESSIONS)
root.addServlet(new ServletHolder(new TemplateExample), "/*")
server.start()
server.join()
}
}
Now save this alongside your Step project as JettyLauncher.scala and run `sbt clean assembly`. You'll have the ultimate executable jar file in the target soon. Try
java -jar **-assembly-**.jar
and see it will launch the embedded Jetty at port 8080 with the example Step project running. On my machine (OS X 10.6 with JVM 1.6) this setup costs 38MB memory.
I hope this would be useful if someone tries to package Step.
By the way, Step is currently using Jetty 6. Is there any plan to switch to Jetty 7 later? This different package naming and library structure between Jetty 6 and 7 really causes a lot of headache for me. I just want to be sure which one I should rely on now. I would be glad if there is an answer for this. Thanks!
- Rio
Yes, that would be nice. Alan is looking into a hosting option that
would give us a public repository for deployment, so stay tuned. A
temporary solution that I've been using is to add the following lines
to StepProject.scala. This lets me run 'sbt publish' to add it to my
personal Nexus repository. It may not be the best approach, but it
works for me.
override def managedStyle = ManagedStyle.Maven
val publishTo = "nexus.example.com" at
"http://nexus.example.com/content/repositories/snapshots/"
Credentials(Path.userHome / ".ivy2" / ".credentials", log)
override def packageSrcJar = defaultJarPath("-sources.jar")
val sourceArtifact = Artifact(artifactID, "src", "jar",
Some("sources"), Nil, None)
override def packageToPublishActions = super.packageToPublishActions
++ Seq(packageSrc)
This is great stuff. I've added it as a wiki page on github. Thank
you for this!
> By the way, Step is currently using Jetty 6. Is there any plan to switch to Jetty 7 later? This different package naming and library structure between Jetty 6 and 7 really causes a lot of headache for me. I just want to be sure which one I should rely on now. I would be glad if there is an answer for this. Thanks!
There are two distributions of Jetty 7: one from Codehaus and one from
Eclipse. I'm not clear on the reasons we might prefer one over the
other. Any opinions?
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/images/*</url-pattern>
...
</servlet-mapping>
But doing a request for server:8080/images/put_images_here yields a
404 from my servlet:
"Requesting /images/put_images_here but only have Map(DELETE ->
List(), POST -> List(), GET -> List(/, /people/:person, ...)...)"
I'd guess it'd be something in the JettyLauncher.scala lines:
val root = new Context(server, "/", Context.SESSIONS)
root.addServlet(new ServletHolder(new MyServlet), "/*")
where only my servlet gets added... does something need to be added
about a default servlet?
For now I could just have the servlet serve up the static content, I
suppose.
-Leif
> > Copy this piece of code from here <http://technically.us/git?p=sling.git;a=blob;f=project/build/Assembly...
When mixing dynamic and static content, extending StepFilter instead
of Step is a good alternative. You would need to change JettyLauncher
to run it as a filter instead of as a servlet. By running as a
filter, instead of returning a 404 when no route matches, it just
delegates to the next handler in the chain, which would be the default
servlet.
> To unsubscribe from this group, send email to step-user+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
>
--