I am interested in understanding "best practice" for the use of application server (for example Glassfish). I have a medium size application that consists of various components that consume and source web services. These components are hosted in a Glassfish environment.
I now have a requirement for a simple scheduled function that copies data from one database to another. That is, it requires no web type functionality. It could easily be built as a simple application (say around Quartz) and deployed in the same Glassfish server with the other components. I understand that this is a simple question, however is this a "reasonable" approach or should it really be a stand alone application running independently from an application server? I guess the more general question is "What are appropriate uses for an application server and what are not?"
It could just be a shell script called from cron...
Seriously, not a very good use of an app server UNLESS you're going to get some sort of monitoring or load distribution out of it. But it sounds like this is really just a batch job in which case you should do the easy thing and just write a script or a simple app with a main method that you either call from cron (or something similar) or run from the command line with some sort of embedded timer (or a sleeping thread).
Related
I'm sure this is very obvious, but I'm new and just trying to wrap my head around this. And googling this question isn't helping, because I think the answer is just so obvious... but I'd really appreciate an answer.
First of all, there are many modules Spring provides for a variety of applications. For applications like job scheduling, console applications, batch or stream processing, serverless applications, etc. you don't require any kind of server or browser.
But, when it comes to a web or enterprise application, you definitely need a web container. Spring comes with a built-in server of its own, i.e Tomcat (though there is also an option for Jetty and UnderTow, etc.). This is basically a container that handles the dynamic requests coming from the clients. But, you can have your own configuration by modifying the default one to meet your custom requirements. Like say, for example, Usually, it runs on port no.-8080 you can change it to say, 8081 by simply mentioning 'server.port=8081' in the application property of your application.
Now, coming back to your question any Spring/Spring Boot application runs on servers as a whole and sole application.
I've been researching Apache's commons-daemon and it seems pretty cool: basically its an API as well as a library that helps register your JAR with the underlying OS so that it can be started and stopped like a daemon service. Additionally, it intercepts OS signals that would normally kill your app and instead gives you a chance to shutdown politely.
So it's got me wondering, if given the choice between deploying your business logic inside EJBs and wrapping them in a container like OGS or JBoss, why not just create a daemon JAR that listens on a port and responds to client requests?
Is it just the benefit of all the features/services that an app container provides out of the box (security, logging, etc.), or are there times when it would be favorable to choose a daemon over an app container/EJB solution?
Basically, what I'm asking if: when is it more appropriate to use an app container/EJB solution, and when is it more appropriate to use commons-daemon to help build a system-level service (in Java)?
Disclaimer: just interested in these two choices, I am aware that other solutions exist (web containers, ESBs, OSGi, etc.). But for the purposes of this question I am only interested in hearing the reasoning between app container or daemon solutions. Thanks in advance!
Why don't you look at it like System level (daemon) vs Application level (in container)?
This will give more or less clear distinction (especially if worked with Linux some time).
For Daemon:
has its own life cycle (you can start and stop it separately);
different privileges (could be run under different user);
use case is something like CRON, MailServer, synchronization and any system-level service.
For Container:
managed app (by some privileged user via Container console);
plenty of out-of-the-box features (which you'd already mentioned);
use case some general case business application.
Well the simple answer is yes, the app server (Glassfish or JBoss) give you plenty of nice things that you would have to implement or setup yourself in a plain Java SE app.
However it is not so black and white, and you can get a lot of the application server goodness with very little effort, I am in the process of writing a blog series on exactly this topic.
My reason for not using an app server, was that we had a project for a widely distributed software product, and we wanted to avoid having to patch and maintain thousands of application server instances!
However if your app will be running in one place, there is little reason to go Java SE.
Problem: I have a standalone Java app (henceforth known as "the agent") that runs as a service on internal company servers. It acts as a remote agent for some central servers. As the agent gets deployed in more places, managing them is getting more complicated. Specifically: pushing updates is painful because it's a fairly manual process, and getting access to the logs and other info about the environments where the agents are running is problematic, making debugging difficult. The servers under discussion are headless and unattended, meaning that this has to be a fully automated process with no manual intervention, hence Java Web Start isn't a viable solution.
Proposed solution: Make the agent phone home (to the central servers) periodically to provide agent status and check for updates.
I'm open to other suggested solutions to the problem, but I've already got a working prototype for the "status and self-updates" idea, which is what this question is focused on.
What I came up with is actually a separate project that acts as a wrapper for the agent. The wrapper periodically calls the central server via HTTP to check for an updated version of the agent. Upon finding an update, it downloads the new version, shuts down the running agent, and starts the new one. If that seems like an odd or roundabout solution, here are a few other considerations/constraints worth noting:
When the wrapper gets a new version of the agent, there may be new JAR dependencies, meaning class path changes, meaning I probably want to spawn a separate Java process instead of fiddling with ClassLoaders and running the risk of a permanent generation memory leak, which would require manual intervention--exactly what I'm trying to get away from. This is why I ended up with a separate, "wrapper" process to manage the agent updates in my prototype.
Some servers where the agents are deployed are resource-limited, so any solution needs to be low on CPU and memory usage. That makes me want a solution that doesn't involve spinning up a new JVM and is a stroke against having a separate wrapper process.
The agent is already deployed to both Windows and RHEL servers, so the solution must be cross-platform, though I wouldn't have a problem duplicating a reasonable amount of the process in batch and bash scripts to get things rolling.
Question: As stated, I want to know how to make a self-updating Java app. More specifically, are there any frameworks/libraries out there that would help me with this? Can someone with experience in this area give me some pointers?
If your application is OSGi based, you could let OSGi handle bundle updates for you. It is similar to the wrapper approach you suggest, in that the OSGi container itself is "the wrapper" and some of it won't be updated. Here's a discussion on this
Different solution: use (and pay for) install4j. Check out the auto-update features here
No need for wrapper (save memory) or java web start (adds more restrictions on your application), simply let a thread in you application check periodically for updates (e.g. from cloud) and download updates if available, then code these two calls in you application:
launch a shell script (.sh or .cmd) to update your artifacts and launch your application after few seconds pause in the script(to avoid having two instances of your application at the same time).
Terminate your application (first instance)
The script can overwrite needed artifacts and re-launch your application.
enjoy !
Have a look at Java Web Start.
It is technology that's been part of Java since... 1.5? maybe 1.4? and allows deployment and install of standalone Java-based apps through a web browswer. It also enables you to always run the latest app.
http://www.oracle.com/technetwork/java/javase/overview-137531.html
http://en.wikipedia.org/wiki/JNLP#Java_Network_Launching_Protocol_.28JNLP.29
also see this question: What's the best way to add a self-update feature to a Java Swing application?
It appears as though Webstart is the only built in way to do this at the moment.
I need to develop a game server that will run periodically (e.g., triggered by a CRON job every five minutes or hour as appropriate). Once started up, the server will access all of the current game state (fetched through REST from the game's data servers (Stackmob, Parse or similar), do the processing of player actions, and then POST the results back to the data server. In other words, it will be doing a lot of HTTP requests, but does not itself necessarily need to be a web service.
I've been considering multiple ways of developing this.
I do not feel for setting up a server myself, so I need to find a service to run this on that permits the workflow I would like.
The game engine is Java, so something that works neatly with that.
Will need to GET and POST data files, so access to static files would be needed.
Most of the services that exist which provide something similar to what I require are directed at web services - which generally means that one needs to jump through some hoops to get things to work.
Google App Engine, for instance, would require that I implement this using backends (since the game server could potentially run for more than 60 seconds), and isn't particularly happy with the idea of static files.
Amazon EC2 would seem easier to develop on (again by building a web service frontend, of course), but there seems to be relatively poor support for CRON.
Generally speaking, it feels like I want to shoot some sparrows with a slingshot, but all the services are offering me cannons. Are there any alternative platforms/frameworks beyond the big two mentioned above that would be suitable for something like this?
You could try Heroku. They support Java. If you created a project that used a single worker dyno then the hosting would be free (see link).
The process would be running continuously, so you might want use a Timer for periodic execution. You could also use Quartz, but it might be overkill.
Edit:
Here's some links that might help get started:
Running non-web Java processes on Heroku
Heroku Java quickstart - this is for a web app ('web dyno') rather than a 'worker dyno', but it may help.
java.herokuapp.com has links to some example projects (again web apps rather than workers)
How about using EC2, but rather than putting the scheduler in the instance (which won't work because the instance can go away at any time), putting it in AWS? Like this guy:
http://alestic.com/2011/11/ec2-schedule-instance
Alternatively, if you manage your EC2 instances through Ylastic, it looks even easier:
http://blog.ylastic.com/scheduling-tasks-on-the-aws-cloud
Although you'll have to pay for Ylastic as well as EC2, i imagine.
I found a nifty way of writing something like this in Groovy with Maven. You can write a multithreaded Groovy script to pull the stats, do the updates, etc. and then have maven's assembly plugin assemble the whole thing into a self-contained, executable jar file that can be called by a CRON job. One nice thing about Groovy is that its syntax allows you to do this:
def google = "http://google.com".toURL().text
which will turn the string into a URL and handle all of the details of turning the URL into a HTTPURLConnection and getting the raw text.
You could develop the app as a standalone Java program first and then worry about where to deploy it later.
To develop the app you could write a simple Java program that uses HtmlUnit to talk to the external web services. The job could be internally started via Quartz. If you really wanted to start the job externally via CRON, you could have CRON run the app, passing in args. The app would then run and exit.
Alternatively, you could have the app always running and have cron run a bash script that triggers the job in some way.
Essentially, all you need to deploy is a Unix machine so you could use AWS.
I'm a long-time client-side (Swing) developer and I operated pretty much by myself in the same job for a long time. Working from home in a vacuum, I was pretty much completely isolated from the community. I recently took a position as a server-side Java guy for a startup, and I'm learning a ton of stuff but I'm the only Java person and am pretty much on my own again. Having never done server-side Java before, so much of this stuff is completely new and I feel like I have no idea what the normal best-practices are, or I don't have an intuitive feel for what tools to use for what jobs. I keep reading and reading various Internet sources (SO is awesome!) trying to bulk up my knowledge, but some things seem hard to search for because they don't have any obvious keywords. Hopefully some of you gurus here can point me in the right direction.
I'm in charge of implementing our backend REST service, which for now supports our website and an iPhone app. We're doing a social media site, eventually with many different clients. Currently the only clients of the service are our own website and our own iPhone app. I'm using Jersey, Spring, Tomcat, and RDS (Amazon's MySQL) on Amazon's EC2 platform. Our media storage is via S3. I've picked up all of these things pretty quickly and so far so good -- things are working fine with the website and the iPhone app. Cool.
Our next step is adding some long-running server-side processing. This processing is basically CPU-intensive stuff that doesn't involve any communication until it's done. I'm trying to figure out what the best way to handle this is. I'm thinking of using Amazon's SQS to queue up jobs in response to the REST events that should trigger them, but I can't figure out how I should handle the dequeuing and processing. I know I need some threads somewhere that take jobs off the SQS queue and process them, and then tell the REST service that the job is done. But where do these threads live?
In a plain "java -jar jobconsumer.jar" process on another EC2 instance that starts a small thread pool. Maybe use Spring to wire up this piece and start it running?
In a webapp deployed in a container like Tomcat on another EC2 instance? I don't really know what benefits I would get from this, but somehow running in a container like this seems more stable? Does this sort of container even really support long-running processing loops, or is it just good at responding to HTTP events?
Now that I write it out like that, I don't really see why I would want to use a container. It just seems like an over-complication. However, the Java community seems so centered on these types of containerized, "managed" environments that to not use a container seems somehow wrong. I feel like maybe I'm not understanding what some of the major benefits of these containers are? I mean, beyond the obvious benefits of the web-facing Servlet and JSP specs. Would any of the functionality of those specs help me out with something like this?
For a regular Java web app, you almost certainly want to be using one of the Servlet containers such as Tomcat - it takes care of accepting connections, parsing and serialising HTTP messages, JSPs, SSL, authentication, etc for you.
For a non-web app, the argument for using Tomcat (or similar) is weaker, but there are a few reasons to still consider it:
straightforward to add JSPs for querying and managing the app or add a web API in future
easy distribution of releases (one .war vs. an unholy mess of jars and config files)
hot deployment (although I've yet to see anyone using this for anything serious)
In terms of long-running processing loops, Servlet containers don't help you out beyond notifying your ServletContextListener when the app starts, so you can kick off any long-running tasks.
It's worth noting that if you're already using Spring, it's relatively easy to switch from a stand-alone app to a container using ContextLoaderListener, so it shouldn't be a problem if you decide later that you need the web stuff.
We recently faced a similar question, as we are hosting a large distributed service on EC2.
In short, we are very happy with Jetty 7 as a container. We use it for our user-facing-www, public-api, and internal-backend-api services. In some cases we use it for non-api services such as a workqueue, simply to expose a bit of status & health info for our monitoring.
The great thing about Jetty (any version) is that it can be configured in ~5 lines of code, with zero external config files etc. It's not a container specifically, but an http server that you can embed.
We use Guice for dependency injection, which also favors config-file-less implementations.
Long lived Java processes are nothing to worry about - you basically bring up your servers / threads / threadpools in your main method and don't call System.exit until you want to shutdown explicitly.