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.
Related
One my customers has very strict requirements about how they can deploy a web application. They require it to be deploy-able as WAR within a Java server like Tomcat. Our application however is written in golang and compiles into an executable server.
The only solution I could think off would be to start a long lived golang process in the background which listens on a non-standard port like 8080 and then put some kind of a proxy in java which would transparently proxy all HTTP requests and responses to this process.
How should I go about implementing this ? I'm not at all familiar with Java Servlets and running long running processes like this in the background.
My main concern is if something like this is standard,
would it affect the JVM's memory usage, etc ?
Would the server allow my golang process to allocate the required
amount of memory ?
Would the JVM be able to track it's processor utilization ?
Is there a better way to do this maybe ? Like some kind of inter-process communication mechanism ?
If HTTP is the only API your Go application exposes, then you're only left with the option to just send a HTTP request to Go. Yes you can start the Go executable as a child process from the JVM using a ProcessBuilder. But that's not truly embedding go within your WAR. You can use JNI (Go bindings are called GoJVM) to invoke native routines in Go from Java, but then you have to make a lot of adjustments to your Go code base as well.
What you are looking probably for is indeed a reverse proxy. It's not frequently done in servlets / application servers, because this is usually done in load balancers already. So usually that would be NGINX or httpd with mod_rewrite. For application servers, you can use a proxy servlet.
Examples:
https://github.com/mitre/HTTP-Proxy-Servlet
https://sourceforge.net/projects/j2ep/
The memory footprint is usually not to bad, because you're essentially only connecting the streams. The JVM will be able to track processor and memory utilisation - if implemented properly and the Go executable runs on the same server. Obviously the Java specific statistics don't make much sense anymore, as you're only using your Java server as a pass-through.
Sounds like you will be in trouble though. If my strict requirement was a WAR-archive that can be deployed to an application server, I wouldn't accept another executable added to my stack. Reverse proxied or not.
If they want war, give them war!
Write a thin layer web service that has the executable embedded as a resource that executes it to bring up the go server and accepts web calls and does a pass through to the go service.
Achieves nothing I hear you say? Well, neither does their arbitrary requirement that was probably put in place by someone who's long since left the company, and/or because they lack the confidence/experience/ knowledge to operationally deal with other forms of deployment. There is no particularly good reason to deny your service to be deployed except the work required to establish proper operational procedures (laziness).
Just follow the letter of their rules, not the spirit, and be honest if asked about your implementation. They won't mind.
This may sound like a rant, but IMHO and experience, this kind of approach is reality and the drivers for the requirement are emotionally based, so a somewhat emotional answer is warranted.
I'm looking for something that can monitor the traffic of a java web application in order to estimate cloud computing prices.
It would be great if it can categorize the traffic in different categories, e.g. database, static resources, pages, etc.
Ideally, it should be something working in the same way New Relic does. Unfortunately, New Relic only monitors times and not traffic...
Does something like this exist?
Thanks.
You don't need any java-specific software for doing that. You can use any network monitor tool and just run your application locally! For monitoring different kind of traffic, I would use different tools too. There are a lot of DB-monitor tools out there... Sorry for not being more specific.
There are quite a lot solutions for monitoring Java web applications. I have tried a few of them but finally stopped at two: Zabbix and JavaMelody. Both are appropriate to monitor and categorize a traffic of apps, although they are completely different in how they work. Zabbix allows watching an app over the long term via JMX. JavaMelody can be built into an app and provides complete insight into business app processes.
Your final decision about Java app monitoring platform depends on the prioritized app features that you’d like to monitor. I recommend you to read the review that helps you look at both solutions in details: http://cases.azoft.com/enterprise-system-monitoring-solutions-business-apps/
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'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.
I'll need to develop a Java service that is simple because:
It only communicates via a TCP socket, no HTTP.
It runs on a dedicated server (there are no other services except the basic SSH and such)
Should I make this a standalone service (maybe in something like Java Service Wrapper) or make it run in a container like Tomcat? What are the benefits and detriments of both?
If you aren't working with HTTP, you will have to build your own connectors for Tomcat. When I've written these types of applications, I've just written them as standard Java applications. On Windows machines, I use a service wrapper that allows them to be part of the Windows startup process. On non-windows machines, you just need to add a start up script.
Using a container (regardless which) buys you that all the details about starting, stopping, scaling, logging etc, which you have to do yourself otherwise, and it is always harder than you think (at least when you reach production).
Especially the scalability is something you need to consider already now. Later it will be much harder to change your mind.
So, if somebody already wrote most of what you need, then use that.
Tomcat doesn't sound like a good choice for me in your situation. AFAIK it's primarily made for Servlets and JSPs, and you have neither. You also don't need to deploy multiple applications on your app. server etc. (so no benefit from ".war").
If you need dependency injection, connection pooling, logging, network programming framework etc., there are a lot of good solutions out there and they don't need tomcat.
For example, in my case I went for a standalone app. that used Spring, Hibernate, Netty, Apache Commons DBCP, Log4j etc. These can be easily setup, and this way you have a lot more freedom.
Should you need a HTTP server, maybe embedding Jetty is another option. With this option too, you have more control over the app. and this can potentially simplify your implementation compared to using a tomcat container.
Tomcat doesn't really buy you much if you don't use HTTP.
However, I was forced to move a non-HTTP server to Tomcat for following reasons,
We need some simple web pages to display the status/stats of the server so I need a web server. Java 6 comes with a simple HTTP server but Tomcat is more robust.
Our operation tools are geared to run Tomcat only and standalone app just falls off radar in their monitoring system.
We use DBCP for database pooling and everyone seems more comfortable to use it under Tomcat.
The memory foot-print of Tomcat (a few MBs) is not an issue for us so we haven't seen any performance change since moved to Tomcat.
A container can save you from reinventing the wheel in terms of startup, monitoring, logging, configuration, deployment, etc. Also it makes your service more understandable to non-developers.
I wouldn't necessarily go for tomcat, check out glassfish and germonimo as they are more modular, and you can have just the bits the need, and exclude the http server.
We faced a similar decision a while back, and some parts of the system ended up being jsw based, and the others as .war files. The .war option is simpler (well more standard for sure) to build and configure.