I am currently developing something in Java using Jetty as my web container. How can I test if my WAR/EAR/etc file can be deployed on other servers (including enterprise level servers)?
I want to try and sell my application to enterprises, but not sure how I can know whether or not the application will deploy? I've only ever used OS servers before
Also how do I spec my 'system requirements' if i don't have access to enterprise grade hardware?
edit: I mean, if I look at something like this: http://wiki.gxtechnical.com/commwiki/servlet/hwiki?Oracle+Application+Server+Deployment, it looks deceptively easy.. But going in blind is quite scary!
You need to download, configure, and install each server and try it out. Many have free or limited development versions.
Depending on the complexity of your application, you will very likely encounter issues with each container. I can't say if any of them will be in conflict (i.e. fix it to work with container X makes it break in container Y), but it is possible.
Related
There seems to be a current trend in java space to move away from deploying java web applications to a java servlet container (or application server) in the form of a war file (or ear file) and instead package the application as an executable jar with an embedded servlet/HTTP server like jetty. And I mean this more so in the way newer frameworks are influencing how new applications are developed and deployed rather than how applications are delivered to end users (because, for example, I get why Jenkins uses an embedded container, very easy to grab and go). Examples of frameworks adopting the executable jar option:
Dropwizard, Spring Boot, and Play (well it doesn't run on a servlet container but the HTTP server is embedded).
My question is, coming from an environment where we have deployed our (up to this point mostly Struts2) applications to a single tomcat application server, what changes, best practices, or considerations need to be made if we plan on using an embedded container approach? Currently, we have about 10 homegrown applications running on a single tomcat server and for these smallish applications
the ability to share resources and be managed on one server is nice. Our applications are not intended to be distributed to end users to run within their environment. However, moving forward if we decide to leverage a newer java framework, should this approach change? Is the shift to executable jars spurred on by the increasing use of cloud deployments (e.g., Heroku)?
If you've had experience managing multiple applications in the Play style of deployment versus traditional war file deployment on a single application server, please share your insight.
An interesting question. This is just my view on the topic, so take everything with a grain of salt. I have occasionally deployed and managed applications using both servlet containers and embedded servers. I'm sure there are still many good reasons for using servlet containers but I will try to just focus on why they are less popular today.
Short version: Servlet containers are great to manage multiple applications on a single host but don't seem very useful to manage just one single application. With cloud environments, a single application per virtual machine seems preferable and more common. Modern frameworks want to be cloud compatible, therefore the shift to embedded servers.
So I think cloud services are the main reason for abandoning servlet containers. Just like servlet containers let you manage applications, cloud services let you manage virtual machines, instances, data storage and much more. This sounds more complicated, but with cloud environments, there has been a shift to single app machines. This means you can often treat the whole machine like it is the application. Each application runs on a machine with appropriate size. Cloud instances can pop up and vanish at any time which is great for scaling. If an application needs more resources, you create more instances.
Dedicated servers on the other hand usually are powerful but with a fixed size, so you run multiple applications on a single machine to maximize the use of resources. Managing dozens of application - each with their own configurations, web servers, routes and connections etc. - is not fun, so using a servlet container helps you to keep everything manageable and yourself sane. It is harder to scale though. Servlet containers in the cloud don't seem very useful. They would have to be set up for each tiny instance, without providing much value since they only manage a single application.
Also, clouds are cool and non-cloud stuff is boring (if we still believe the hype). Many frameworks try to be scalable by default, so that they can easily be deployed to the clouds. Embedded servers are fast to deploy and run so they seem like a reasonable solution. Servlet containers are usually still supported but require a more complicated set up.
Some other points:
The embedded server could be optimized for the framework or is better integrated with the frameworks tooling (like the play console for example).
Not all cloud environments come with customizable machine images. Instead of writing initialization scripts to download and set up servlet containers, using dedicated software for cloud application deployments is much simpler.
I have yet to find a Tomcat setup that doesn't greet you with a perm gen space error every few redeployments of your app. Taking a bit longer to (re-)start embedded servers is no problem when you can almost instantly switch between staging and production instances without any downtime.
As already mentioned in the question, it's very convenient for the end user to just run the application.
Embedded servers are portable and convenient for development. Today everything is rapid, prototypes and MVPs need to be created and delivered as fast as possible. No one wants to spend too much time setting up an environment for every developer.
Just wondering if anyone has ever converted a Websphere project to run under tc server? I run on a Mac and would love to be able to run my application locally without having to run Websphere in a VM.
I realize there are differences which would have to be accounted for, and that's really my question - what would I have to change? I also realize that even if this is possible, one couldn't depend on the tc server configuration before going to production - it would have to be tested in Websphere first.
As we know, application server provides lot more features than a tomcat. Hence first, you would have to check if your application is using any of those features. If so, then you would have to see if that missing functionality could be plugged-in somehow. To exemplify, you could be using the transactional capability of the application server. Tomcat doesn't come with transaction capability. You would need to plug-in a a third party component for that. For this to happen less intrusively, the code should be configurable so that based on the environment it would know whether to make use of the capabilities of the application server or use the capabilities of the plugged-in components in case of tomcat.
Advantage of this: It would certainly be boosting to the productivity if you use tomcat to develop rather than any application server, as the time it takes to start and stop tomcat if far less than the coffee time (To me ,one coffee time is the amount it takes for an application server to stop and start even when you have the minimal hardware requirements mentioned by it)
Warning:: Again this approach has a negative point that you would miss to see how your component interacts with the classes in the production environment, while you develop. Hence it becomes mandatory to have your QA environment and above to make use of the application server. This way you could avoid any surprises in production.
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.
I recently have a problem that my java code works perfectly ok on my local machine, however it just wouldn't work when I deploy it onto the web server, especially the DB part. The worst part is that the server is not my machine. So I had to come back and forth to check the versions of softwares, the db accounts, the settings, and so on...
I have to admit that I did not do a good job with the logging mechanism in the system. However as an newbie programmer with little experience, I had to accept my learning curves. Therefore, here comes a very general but important question:
According to your experience, where would it be most likely to go wrong when it is working perfectly on the development machine but totally surprises you on the production machine?
Thank you for sharing your experience.
The absolute number one cause of problems which occur in production but not in development is Environment.
Your production machine is, more likely than not, configured very differently from your development machine. You might be developing your Java application on a Windows PC whilst deploying to a Linux-based server, for example.
It's important to try and develop against the same applications and libraries as you'll be deploying to in production. Here's a quick checklist:
Ensure the JVM version you're using in development is the exact same one on the production machine (java -version).
Ensure the application server (e.g. Tomcat, Resin) is the same version in production as you're using in development.
Ensure the version of the database you're using is the same in production as in development.
Ensure the libraries (e.g. the database driver) installed on the production machine are the same versions as you're using in development.
Ensure the user has the correct access rights on the production server.
Of course you can't always get everything the same -- a lot of Linux servers now run in a 64-bit environment, whilst this isn't always the case (yet!) with standard developer machines. But, the rule still stands that if you can get your environments to match as closely as possible, you will minimise the chances of this sort of problem.
Ideally you would build a staging server (which can be a virtual machine, as opposed to a real server) which has exactly (or as close as possible to) the same environment as the production server.
If you can afford a staging server, the deployment process should be something like this:
Ensure application runs locally in development and ensure all unit and functional tests pass in development
Deploy to staging server. Ensure all tests pass.
Once happy, deploy to production
You're most likely running under a different user account. So the environment that you inherit as a developer will be vastly different from that a a production user (which is likely to be a very cut down environment). Your PATH/LD_LIBRARY_PATH (or Windows equivalents) will be different. Permissions will have changed etc. Plus the installed software will be different.
I would strongly recommend maintaining a test box and a test user account that is set up with the same software, permissions and environments as the production user. Otherwise you really can't guarantee anything. You really need to manage and control the production and test servers wrt. accounts/installed software etc. Your development box will always be different, but you need to be aware of the differences.
Finally a deployment sanity check is always a good idea. I usually implement a test URL that can be checked as soon as the app is deployed. It will perform database queries or whatever other key functions are required, and report unambiguously as to what's working/not working via a traffic light mechanism.
Specifically you can check all the configuration files (*.xml / *.properties) in your application and ensure that you are not hard coding any paths/variables in your app.
You should maintain different config files for each env. and verify the installation guide from env admin. (if exists)
Other than that versions of all softwares/dependency list etc as described by others.
A production machine will likely miss some of the libraries and tools you have on your development machine. Or there may be older versions of them. Under circumstances it may interfere with the normal software function.
Database connection situation may be different, meaning users and roles and access levels.
One common (albeit easy to detect) problem is conflicting libraries, especially if you're using Maven or Ivy for dependency management and don't double check all the managed dependencies at least once before deploying.
We've had numerous incompatible versions of logging frameworks and even Servlet/JSP API .jar:s a few times too many in our test deployment environment. Also it's always a good idea to check what the shared libraries folder of your tomcat/equivalent contains, we've had some database datasource class conflicts because someone had put postgre's jdbc jar to the shared folder and project came with its own jar for jdbc connectivity.
I always try to get an exact copy of the Server my product is running. After some apps and of course a lot of Bugs i vreated myself a List of common Bugs/Hints. Another Solution i tested for my last project was to get the running Software on that Server and try to configure it. Strange effects can happen with that^^
Last but not least..i always test my apps on different machines.
In my experience there is no definite answer to this question. Following are some of the issues I faced.
Automatic updates was not turned on in dev server (windows) and it was turned on in the production server(which in first place is wrong!). So one of my web application crached due to a patch applied.
Some batch jobs were running in the production app server which changed some data on which my application was using.
It is not me who does the deployment for my company so most of the time people who deploy miss some registry entries, or add wrong registry entries. Simple but very hard to detect (may be for me ;-) ) once I took hours to identify a space in one of the registry values. Now We have a very long release document which has all the details about all servers used by the application and there is a check list for "current release" which the engineers who deploy the application fill in.
Willl add more if I remeber any.
Beyond just a staging server another strategy for making sure the environments you deploy into are the same is to make sure they are set up automatically. That is you use a tool like Puppet to install all the dependencies that the server has and run your install process before every installation so that all the configuration is reset. That way you can ensure the configuration of the box is what you have set it to during the development process and have the configuration of the production environment in source control.
We have had a web application product for several years, and used Tomcat to deploy it under Windows as it registers itself as a Windows service so it starts and stops automatically.
We may now happen to need more Java EE facilities than is provided by Tomcat (we are very tempted by the Java EE 6 things in the container) so the question is which Open Source Java EE containers work well as Windows services. Since Glassfish is the only Java EE 6 implementation right now, it would be nice if it works well, but I'd like to hear experiences and not just what I can read from brochures. If not, what else do people use?
EDIT: This goes for web containers too, and not just Java EE containers. We will probably keep the necessary stack included until we find the right container and it gets Java EE 6 support.
EDIT: I want this to work as distributed. I'm not interested in manually hacking wrappers etc., but want the installation process to handle the creation and removal of the service.
EDIT 2012: It turned out that the Windows installer for Glassfish can install as a service (requires .NET). Component web site http://kenai.com/projects/winsw. Has proven very robust.
We use Tomcat as a service. We have also used JBoss as a service.
It is possible to run GlassFish as a service.
It is also worth noting that most of the commercial Java EE containers can also run as a service. In particular, I know that all of the following can be run as a service, since we have set them up in that way:
Netweaver
WebLogic
WebSphere
In fact I think you would be hard pressed to find a Java EE container that could not be run as a service, since you could always use the Java service wrapper to wrap any java program as a service.
Since it was mentioned in another answer that you might also be interested in web servers running as services, it is probably worth pointing out that the big two on Windows, IIS and Apache, can both be run as services.
Edit: Since you edited to ask specifically about Java EE containers that contain installers that install the windows service:
Tomcat
JBoss
Netweaver
WebLogic
WebSphere
There are probably others, but these are the only ones that I have used.
There is Platform Services Support in GlassFish v3 which can interact with Solaris/OpenSolaris SMF and Windows Services. To my knowledge, it just works.
I use Caucho's Resin under windows, it comes with its own service installer which works quite well for me.
We use JBoss and it runs perfect as a service, no problems so far. We even have loaded the servers with ssh acces so we can remotely restart the services if we want.
I've used Glassfish (Version 2 though) as a Windows service. While it does take some work to get things installed, once set up, it worked pretty well. We used it in a production environment, and our set up consisted of a two node cluster (so we had to set up a domain, and two nodes (on two different machines)).
If I recall correctly, my biggest challenge was trying to use sc, and figuring out its funky escape sequences.
Another thing to look at is Hudson. I've always been impressed with how it installs itself as a Windows service. You may want to have a look at how they do it. They use Winstone as their embded servlet engine though, which as far as I know, is not EE 6 compliant.