As to full blown app servers vs embedded servers, I think it's the other way around. It's the big app servers that require justification, as they are a lot more cumbersome to set up and deploy.
You wouldn't do this for a production deployment, right? Application starup that may or may not require access to the artifact repository to complete successfully. When that idea bounces around my developer neocortex, my sysadmin hindbrain starts reaching forward to strangle it.
And if you're not going to do it in production, doing it in development means having a gratuitous difference between development and production, which, again, is something i have learned to fear.
A zip with startup scripts is OK, but it requires installation.
'gradle installApp' works out of the box, and 'installs' the jars and scripts in your build directory, which is all you need to run locally. It's work of minutes to write an fpm [1] invocation that packages the output of installApp as an operating system package, which you can then send down the pipe towards production. This is simple, easy, standard, and fully integrated with a world of existing package management tools. Why would i use Capsule instead of doing this?
And i still don't see what advantage this has over just pushing out normal packages.
Alternatively, you can embed the dependencies, in which case it's just like a "normal package", only it doesn't require installation, and is just as easy to create (your build tool can create it). So it's a platform independent "normal package", with added features.
But then, i have spent a fair amount of managing machines, shuffling packages around apt repositories, writing Puppet code and so on. Perhaps for a developer who has not served a sentence in operations, operating system packages are a less comforting proposition.
You seem to be very keen on avoiding "installation". Could you tell us about why that is?
And could you remind me what the added features of a capsule are? Putting aside the differences in delivery mechanism, which as i've said, i'm afraid i see as misfeatures, the only one i see is that it automatically finds the right JRE.
(Sorry you're being downvoted, by the way. I think this is an interesting discussion, and your gracious responses deserve upvotes, not downvotes.)
There are other ways to achieve stateless deployment, and Capsule is not always the right fit. For example, it's not the right fit if your app requires an Oracle DB installed locally (it could be done, because Capsule supports an installation script embedded in the JAR, but that probably wouldn't be a good idea in this case). But when it is the right fit (e.g. microservices, grid workers etc.), it's much more lightweight than any other solution.
Again, for what advantage?
I mean, fine if you want to do that. But I wouldn't call it Modern Java or recommend anyone else do it.
And if you don't want to enable automatic upgrades, you still get stateless, installation-free deployment.
And you can't see why this is a bad idea?
Please don't. Never assume that production machines have access to the internet or even an internal Maven repository. If they do, they're a security risk. There are plenty of scenarios I can think of where an attacker could possibly make your application download something from the internet, or has your application server functioning as an anonymous proxy by exploiting your application.
Aren't the app servers and the embedded servers the same servers just configured differently? Standalone it is configured with XML and and embedded it is configured with Java code. It doesn't seem to me like there is much of a set up difference.
As far as I can tell, it comes down who cares more about the settings for the server, the people who maintain the machines or the people who maintain the code. If those people are the same then it sounds like it really doesn't matter.
> As far as I can tell, it comes down who cares more about the settings for the server
There's a lot of truth to that. I think that the whole devops approach is that they should be the same people. Of course, you might have valid reasons for not subscribing to that approach.
I grant you, upgrading servers can be more involved depending on how you do it.
[0] - http://tomcat.apache.org/tomcat-7.0-doc/deployer-howto.html#...
Fully agreed with the zip and script though, that's what we do (using the appassembler maven plugin, so it just happens as part of the build).
I'm not sure why it matters that different distros put Tomcat in different locations. Embedding Jetty just means that now you have to restart every time. You could just do the same thing with standalone Tomcat instance. The only reason you are running out PermGen space on the redeploys is because your application is not cleaning up its threads on shutdown.
Why is it difficult to do any of those development things without having the server embedded in your application? Pretty much every Java build tool (Maven, SBT, Gradle, Lein) makes those things easy to do without specifying an XML file for your server. Also, they will frequently let you reload your application, which is faster.
So now either I need to figure out how to hook my deployment script into the host system's init scripts, or I need to package tomcat as part of my app (and worry about its shared library linkage). With embedded, my app is just a program, not at all integrated with the host system; it runs like a program and stops like a program.
> Why is it difficult to do any of those development things without having the server embedded in your application?
Because the tool needs support for the server and often it has to be done in a server-specific way. How does one use JProfiler on an app deployed in Tomcat? One edits one of the internal Tomcat xml files. How does one use JProfiler on an app that embeds Jetty? One runs it with the same command line arguments one uses for running any other app with JProfiler. And it's like that for every tool - the way to do it with Tomcat is slightly different, the way to do it with an embedded server is standard.
> Pretty much every Java build tool (Maven, SBT, Gradle, Lein) makes those things easy to do without specifying an XML file for your server.
If you're building a war you need a web.xml (or I'm seeing some speculation it can be done with annotations? Either way, much less clear than just making a servlet in code).
> Also, they will frequently let you reload your application, which is faster.
Not in a way that matters. If you're just doing day-to-day dev then IDE hot code replace is faster still. If you want to be sure you've cleaned out all traces of the old version and are definitely running your latest code then reload isn't reliable enough.
Tool support is not server specific. In both cases you set the appropriate VM arguments. What XML file would you have to edit?
Yes, hot code replacement is faster (although it comes with other tradeoffs). Why can't you do that with standalone Tomcat? What is unreliable about reloading? You can leak PermGen space if you don't finalize your threads properly, but why wouldn't you be running the latest code?
You're right about the web.xml file. I had forgotten about that. I can see why you might prefer to write that in Java code rather than XML.
With an embedded Jetty my app can just be a jar or set of jars. Tomcat has a directory structure and ships as a binary rather than a jar so I'd need to unpack it and worry about it being linked correctly for the target system.
> Tool support is not server specific. In both cases you set the appropriate VM arguments. What XML file would you have to edit?
I forget the name - catalina.xml or something? You can't just run ./tomcat -agent:myagent.jar. because it won't pass the arguments through to the JVM, unless that's changed.
For setting JVM arguments, I think you are thinking of 'setenv.sh' or 'setenv.bat'. These are shell scripts where you can set environment variables used when running Tomcat. This includes the standard 'JAVA_OPTS' to set VM arguments.
I've never totally understood why people want to make fat jars. It seems like a process full of headaches since you can't have jars in jars. Wouldn't it be much easier to create a regular zip file with a small script to set the classpath and and run the project?
I'm not sure I understand the motivation for embedded instead of standalone servlet container. The article linked to some slides but they mostly seemed be demonstrating that you can function using an embedded container rather than providing clear benefits. Maybe it would have made more sense with the associated talk.
Can anyone provide more insight to these?