a FOSS project that uses Lift+jetty+revolver+akka

216 views
Skip to first unread message

Vasya Novikov

unread,
Jan 20, 2015, 6:31:49 AM1/20/15
to lif...@googlegroups.com
I recently thought my hobby project may be worth introducing to the
mailing list, so here it is:

https://github.com/vn971/roboCup

Interesting things about the project:

* it's Lift-based :)

* it uses an embedded jetty instead of the "system-wide tomcat" stuff.
It uses `sbt-assembly` to produce the self-contained jar. (Note that one
can still output war-s compatible with tomcat by marking the jetty
dependency as "provided".)

* it uses `spray-revolver` instead of the `xsbt-web-plugin` to do the
fast-reload cycle. This way SBT never gets "PermGen out of space". It
takes about 1-2 seconds to do a full server-restart cycle after source
change.

* it has a correct configuration of `sbt-native-packager` plugin, suited
for Liftweb. So, one can produce "*.deb" and "*.rpm" files. I switched
to manual scripts and jar-s anyway, they seemed much more simpler. But
if you want to experiment with "sbt-native-packager", you can.

* it uses two lint-er settings and "scalariform" to keep the project a
little better maintained. More precisely, I used "-lint:" scalac options
and the `wartremover` plugin.

* the project uses both "akka" and "liftweb" actors.
It's quite known thought that these actor systems work transparently by
the `!` method, and my project is not an exception to this. If you still
want to be even more convinced, here's the exact line. We're sending a
message from an akka actor to a lift actor here:

https://github.com/vn971/roboCup/blob/5c73ad2aaf0aed4571b892f05587618c59389058/src/main/scala/ru/ya/vn91/robotour/RegistrationCore.scala#L52

* initialization of the embedded jetty server can be seen here:

https://github.com/vn971/roboCup/blob/5c73ad2aaf0aed4571b892f05587618c59389058/src/main/scala/bootstrap/liftweb/Start.scala


The project goal and contents are probably much less interesting. It's
about a game that isn't exactly popular, and you cannot even play the
game on this server because it only integrates with another server (not
mine, not FOSS).
So, it's rather a collection of interesting & working solutions that can
be taken as an example.
Hope it may be interesting, have fun.:)


--
Vasya Novikov

Vasya Novikov

unread,
Jan 20, 2015, 7:16:12 AM1/20/15
to lif...@googlegroups.com
* found out that lift-2.6 is out and updated some stuff.:)

Tyler Weir

unread,
Jan 20, 2015, 9:22:21 AM1/20/15
to lif...@googlegroups.com, n1m5-goo...@yandex.ru


On Tuesday, January 20, 2015 at 6:31:49 AM UTC-5, Vasya Novikov wrote:
* it uses `spray-revolver` instead of the `xsbt-web-plugin` to do the
fast-reload cycle. This way SBT never gets "PermGen out of space". It
takes about 1-2 seconds to do a full server-restart cycle after source
change.

Intriguing, I'll have to take a look. :) 

Antonio Salazar Cardozo

unread,
Jan 20, 2015, 10:09:52 AM1/20/15
to lif...@googlegroups.com, n1m5-goo...@yandex.ru
Very cool, thanks for sharing this!
Antonio


On Tuesday, January 20, 2015 at 6:31:49 AM UTC-5, Vasya Novikov wrote:

Vasya Novikov

unread,
Jan 21, 2015, 8:49:13 AM1/21/15
to lif...@googlegroups.com
Yeah, that's the property I like the most.

It's kind of atomic move from `xsbt-web-plugin` to
https://github.com/spray/sbt-revolver
and
https://github.com/sbt/sbt-assembly

BTW, I even thought about creating a specialized lift template for that.
Dunno if that would be interesting, and whether it would make sense to
integrate it to the official templates.
--
Vasya Novikov

Joe Barnes

unread,
Jan 22, 2015, 5:17:35 PM1/22/15
to lif...@googlegroups.com, n1m5-goo...@yandex.ru
Very cool, and thanks for sharing!  I'm interested in the embedded jetty and the reloading stuff.  I'll have to make some time to look this project over. :)

Joe

Antonio Salazar Cardozo

unread,
Jan 23, 2015, 12:17:30 AM1/23/15
to lif...@googlegroups.com, n1m5-goo...@yandex.ru
It sounds pretty cool, so if you can make a template for some of us to play
with and it improves the workflow, I think it'd be awesome to move the official
templates to that.
Thanks,
Antonio

Alexej Bondarenko

unread,
Feb 15, 2015, 6:32:06 AM2/15/15
to lif...@googlegroups.com, n1m5-goo...@yandex.ru
Vasya, thank you for sharing! I have tried it in a project i'am currently working on. Works pretty well.

Does anyone has an idea how to shut down such an application properly? I use LiftRules unloadHooks to add some application cleanups (shut down akka actors, close connections,...). But when i use sbt-revolver with re-stop, this method is never called at all. (Or i am just using it in a wrong way :) )

Alexej

Arkadiusz Burdach

unread,
Feb 15, 2015, 7:58:47 AM2/15/15
to lif...@googlegroups.com, n1m5-goo...@yandex.ru
Hi Alexej,

I think that you can add some extra cleanups after server.join() e.g.

actorSystem.stop()
actorSystem.awaitTermination()

As far as I understand how it works - when some changes are detected there is a try to interrupt of all running threads. It cause interupption of server.join() at the end. Please give a feedback if it helped you.

I have other problem using sbt-resolver. It restart application after resources change which is annoying devloping client side code - it isn't necessary with container:start approach because jetty has own mechanism for this purpose. Somebody have an idea how to exclude webapps dir?

Arek

Vasya Novikov

unread,
Feb 23, 2015, 1:50:13 AM2/23/15
to lif...@googlegroups.com
Glad if you liked it!

Unfortunately, shutdown hooks are never run this way. It's the way how
sbt-revolver (currently) works. See here for their official description:

> https://github.com/spray/sbt-revolver
> re-stop stops application. This is done by simply force-killing the
forked JVM. Note, that this means that shutdown hooks are not run (see #20).

And the issue they're referencing to:
> https://github.com/spray/sbt-revolver/issues/20
--
Vasya Novikov

Vasya Novikov

unread,
Feb 23, 2015, 1:59:42 AM2/23/15
to lif...@googlegroups.com
Hi!
About application restarts when the resources change. I'd separate two
things: resources under "/src/main/resources" and under "/src/main/webapp".

Changes in the first dir WILL force SBT to restart. I'd say that's good,
there may be configuration things in this dir etc.

Changes in "webapp" dir will NOT force the application to restart, if
configured correctly. See the build.sbt trick in the project I
mentioned to see how it's done.
--
Vasya Novikov

Alexej Bondarenko

unread,
Feb 23, 2015, 8:27:12 AM2/23/15
to lif...@googlegroups.com, n1m5-goo...@yandex.ru
Thanks Vasya!

Brett Grace

unread,
Apr 4, 2015, 7:56:23 PM4/4/15
to lif...@googlegroups.com, n1m5-goo...@yandex.ru
I thought this would be cool for my weekend toy project:

* it uses `spray-revolver` instead of the `xsbt-web-plugin` to do the
fast-reload cycle. This way SBT never gets "PermGen out of space". It
takes about 1-2 seconds to do a full server-restart cycle after source
change.

Getting revolver working took a little digging for me. How much? I solemnly swear, no more than 30 seconds. However, perhaps I can save somebody else the bother.

I updated my plugins.sbt and build.sbt in accordance with the project and the Revolver instructions, but it still needed an entry point to actually start Jetty. Poking around led me to this answer to a question on StackOverflow by some fellow calling himself "Vasya Novikov" linking some code which does exactly that, which was ultimately the solution, and which looks suspiciously like this code on Github.

A minimal, working, interpretation:

object TheApp extends App with Loggable {

 
logger.info("Starting Lift")

 
val port = Props.getInt("liftweb.port").openOr(8080)
 
val server = new Server(port)
 
val context = new WebAppContext

 
context.setWar("src/main/webapp")
 
server.setHandler(context)
 
server.start()
 
logger.info("Booted")

}

Now, on the weekends I both Lift and Revolve, like some sort of gimmicky restaurant, or perhaps a 19th century labor saving deathtrap.

Vasya Novikov

unread,
Apr 5, 2015, 6:40:13 AM4/5/15
to lif...@googlegroups.com
Hi!

The fellow "calling himself Vasya Novikov" is the same person starting
this ML thread.:)
But unfortunately, there are some goals not covered by the "easy way"
you mentioned. You may want to:

1. launch the app locally with SBT `reStart`

2. package the app as a "jar" and launch it with `java -jar ...`

3. package the app as a "war" and move it to a JEE container, so that
the container will start the app itself.

4. NOT restart your app on html changes.

5. package and distribute as *.deb / *.rpm / *.exe ? Rare case though.

And it's not that easy to be compatible with 1-4. For example, :
context.setWar("src/main/webapp")
You do not have an "src" directory while working from inside a jar.

BTW, I'll probably edit my StackOverflow answer so it'll point to the
most correct example.


On 2015-04-05 02:56, Brett Grace wrote:
> I thought this would be cool for my weekend toy project:
>
> * it uses `spray-revolver` instead of the `xsbt-web-plugin` to do the
>> fast-reload cycle. This way SBT never gets "PermGen out of space". It
>> takes about 1-2 seconds to do a full server-restart cycle after source
>> change.
>>
>
> Getting revolver working took a little digging for me. How much? I solemnly
> swear, *no more than 30 seconds*. However, perhaps I can save somebody else
> the bother.
>
> I updated my plugins.sbt and build.sbt in accordance with the project and
> the Revolver instructions, but it still needed an entry point to actually
> start Jetty. Poking around led me to this answer to a question on
> StackOverflow <http://stackoverflow.com/a/22685685/807730> by some fellow
> calling himself "Vasya Novikov" linking some code
> <https://gitorious.org/pointsgame/pointsgame/source/07e29455783e3a88bf7f7d01f8bc1b1d0d3cf81d:src/main/scala/bootstrap/liftweb/Start.scala>
> which does exactly that, which was ultimately the solution, and which looks
> *suspiciously* like this code on Github
> <https://github.com/vn971/roboCup/blob/master/src/main/scala/bootstrap/liftweb/Start.scala>
> .
>
> A minimal, working, interpretation:
>
> object TheApp extends App with Loggable {
>
> logger.info("Starting Lift")
>
> val port = Props.getInt("liftweb.port").openOr(8080)
> val server = new Server(port)
> val context = new WebAppContext
>
> context.setWar("src/main/webapp")
> server.setHandler(context)
> server.start()
> logger.info("Booted")
>
> }
>
>
> Now, on the weekends I both Lift *and* Revolve, like some sort of gimmicky
> restaurant, or perhaps a 19th century labor saving deathtrap
> <http://en.wikipedia.org/wiki/Paternoster>.
>

--
Vasya Novikov

Vasya Novikov

unread,
Aug 4, 2018, 6:40:18 PM8/4/18
to Lift
Hi all.

I'm not sure anybody's following this thread, but I notice some people use the shared project as an example of liftweb + sbt-revolver + jetty + akka-actor project.
It was a shame to find it outdated after a while though. All fixed, the project uses all the newest libraries now & still enjoys the fast sbt-revolver turn-around speed.

Thanks,
Vasilii (I'm the topic-starter)

Henrik Härkönen

unread,
Aug 6, 2018, 1:15:57 AM8/6/18
to Lift
Cool, thanks!

I find that interesting especially due to the usage of sbt-assembly and the "Start" main object. Good example.

-Henrik

Chris Hagan

unread,
Nov 23, 2018, 11:07:51 AM11/23/18
to Lift
I'm still using it.  Well, cannibalizing it for a good practice set in my current project.  Thanks for your effort and keeping it current.

c
Reply all
Reply to author
Forward
0 new messages