This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I can deploy my war file to a bare bones, fresh tomcat installation and it will run just peachy.
And then came the idea of "What if we embedded Jetty into our app? Maybe instead of one war file and tomcat, we could have just one jar file. That would be so much easier for people to install!"
I've never used Jetty before. This idea sounds really cool. And today's the day to take two hours to try and figure it out.
So ... I got to the part where I'm going to stuff everything into a jar file ... and ... well ... where do you put your classes? Your libs? Your .html files ??? I see that I'm going to have to write a tiny main() to kick off the jetty stuff. That's easy. And I already know how to do the "java -jar trick" ...
I guess I thought there would be a web page spelling this sort of thing out: the jar file directory structure would like like .... this ... and the manifest file would look like ..... this .... and don't forget to ....
I have only used jetty once for a small project, so take the following with a grain of salt.
As far as I can tell, regarding your classes and libraries, jetty doesn't really change anything. It is just another third party library for your application. If you want to have just one jar, you might want to take a look at http://one-jar.sourceforge.net (haven't ever used it myself, though).
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Yup! I can see serving my servlet stuff just fine. I'm looking for the part where I say "and you can find my html files and my images in the jar file!"
And then I wanna make sure that hackers can't download my servlet class files.
But I wasn't seeing that sort of thing. And rather than spend eight hours experimenting, I thought (I can't be the first person to do this - surely somebody has been down this same road and there is a 30 minute recipe ....)
For your html files, you need to add a ResourceHandler to your context: http://www.mortbay.org/apidocs/org/mortbay/jetty/handler/ResourceHandler.html - the resourceBase you have to configure is the root folder for your static content (that is, html files, images, etc. pp.) I don't see a handler that would be able to serve the static content directly from the jar file, but I guess it wouldn't be too hard to write your own.
I guess my hopes were that it would be simpler than this. Something already cooked up and I just have to plug in my stuff.
Does that help?
Yes! That moves me waaaay forward.
why not use Tomcat as the embedded server?
Size, mostly. The tomcat solution just looks much bigger. And this is something where I want to find that quickest path and my impression is that more folks have done this sort of thing with Jetty than with tomcat.
the file size of the required JAR files to run an embedded jetty is roughly 4.6MB. Embedded Tomcat is about 5.8 I believe, last time I looked. You aren't saving much in the way of space.
That being said, I prefer Jetty for embedded purposes and I am in the processing of tweaking my own dev cycle to use Jetty. Because my own personal project structure is a bit non-standard I am writing my own Jetty Launcher customized to my needs. It's not that difficult but still having a few lingering issues.
I've never tried putting web accessible content in JAR files though so I can't help with that. I'd be willing to bet its not very common.
if your application knows where your jar is in the local file system, and in which path your static content is in the jar, it might be worth a try using a ZipInputStream to read the static content from the jar. Since you have to skip through the ZipEntry objects one by one until you find the one whose getName() method returns the sought name, this might be somewhat costly if the jar has many entries. You might also unpack the static resources on-demand, storing them on the local file system on the first request, and search the jar file with the above method only if the sought static content is not found in the local file system.
I had the same idea for an upcoming project at work. I did some googling a while back and found this article describing how to use Winstone as the embedded container. http://www.itmill.com/articles/Packaging_web_applications_for_desktop_use.htm I think Winstone only provides the servlet container but there are instructions on their Sourceforge page for integrating Jasper to handle JSP content. I don't know if this would help you out with the static content or not. I don't recall reading anything in either direction about it being handled. I've not had a chance to try any of this, so consider this a disclaimer I'd be interested to know if you have any success getting this to work regardless of which embedded container you end up using.