Fedora and Debian play the role where many chaotic projects get a degree of charm school: they learn to play nice with a lot of other projects. In Fedora, as near as I can tell, there is only one Java based web application packages as part of the distribution: Dogtag, the Public Key Infrastructure server. As we look at how PKI should look in the future, the dearth of comparable applications packaged for Fedora leaves us with the opportunity for defining a logical and simple standard packing scheme. While I am not there yet, this post is the start of my attempts to organize my thoughts on the subject. I’m looking for input.
Some one has already started discussing this for Debian. I’ll use this http://dep.debian.net/deps/dep7/ as a starting point.
I think that, if the application is deployed as a war file from the get-go, fine, but generating the war file after deployment is heavy weight. Lets treat this as a “last resort” approach if we can’t come up with a better one. Most application servers need to extract the files from the .war file if it is deployed that way. It makes more sense to try and get a method together for merging the configuration files with rest of the code
Many of the resources that the application requires should actually be external to it. The two that are most common are the authentication mechanism and the configuration for database connections.
What is more common is for an application to be “Themable” which means that some aspect of the CSS and the images can be customized after the install. There does not seem to be a decent standard in the JEE world for extending and application this way.
Another common pattern is for an application to specify a plugin architecture. A plugin is implemented as a Java package that implements a set of interfaces specified by the project. The package that implements the plugins can go into a common location, such as the Tomcat lib/ext directory, external to the web app. But, in the Java world, if nothing attempts to refer to a class in this package, all the code will lay inactive during deployment. So, it is necessary to register the package with the application server. Taken to its logical continuation, we have OSGi, and JBoss containers, but for simple Tomcat apps, there is no standard way to do this. The best we have is MBeans, with are really supposed to be the management API for Tomcat, not a shared business component.
Some of the problems people have typically had in deploying applications involved Jar conflicts. The Standard Fedora setup is designed around the compromise that people can link to the system libraries in known locations: /usr/share/java/ for pure java files and /usr/lib/java if there is JNI involved. If an application needs a version of a library different from the ones provided by the platform, they can put it in webapps/appname/WEB-INF/lib. However, the applications packaged with Fedora should only use the packages from the distribution.
There are a couple things that the Fedora Tomcat distribution doesn’t do for us yet:
- Generate the symbolic links for required libraries
- configure SSL,
- configure HTTPD as a proxy so we can serve on ports 80/443
- Perform the SE Linux configuration for the web apps that allows us to run the web server in enforcing mode
So here is the starting point for a deployment standard for web applications in Fedora. These should be orthogonal to other Java development factors: it shouldn’t change how the project development is done.
- All supporting libraries go into /usr/share/java. Typically, they will have the name of the webapp as some aspect of the jar file.
- JSPs and other clear text files will be put into a WAR directory structure in expanded form in the directory /usr/share/java/webapps. All files in this directory will be owned by the RPM that creates them. Supporting libraries will be symlinked from jar files in /usr/share/java.
- A zipped war file is optional. If provided, it also goes into /usr/share/java/webapps.
- Configuration files for the application go into /etc/java/webapps. A subdirectory for each webapp contains the files that belong to the webapp, but that are editable. If a webapp requires an editable server.xml file, that file is held in /etc/java/webapps/<appname>.
- Deployment to a Tomcat instance is done via symlinks. The webapp in /usr/share/java/webapps will have a symlink to the config files in /etc/java/webapps/<appname> if required. The WEB-APP itself will be deployed via a symlink from /var/lib/tomcat6/webapps to /usr/share/java/webpass/<appname>. Note that if a war file is provided, the expectation is that this will be used for deployment, but the choice is up to the system administrator.
- All files are owned by root and set as readable by the tomcat user. Modifications of files in the Tomcat directory is not allowed. If a web app needs a local file repository, it will be created under /var/lib/tomcat6/temp/<appname> and be owned by the tomcat user. SELinux system policy will reflect this.
This is the simplest form of deployment. More complex deployments are allowed, but require the rationale to be explained in the spec file for any deviations. The most common change will be where the end user is expected to customize the web application. In those cases, deployment of the webapp will happen like this:
- The code in expanded form from /usr/share/java/webapps/<appname> is copied into /var/lib/tomcat6/webapps/<appname>
- /var/lib/tomcat6/webapps/<appname>/WEB-INF/* are copied from from /etc/java/webapps/<appnam>.
- Upgrades of the RPM will only replace files outside of the realm of the webapp. Upgrades from Changed RPM controlled files to the webapp are done by the system administrator.
- File ownership rules as stated above still apply.
Tool support would expedite adoption of this standard. But adoption does not require tool support. The simplest cases can be deployed via a single symbolic link. More complex deployments can be managed by a script, providing that the script is agnostic of the Servlet container location. While Tomcat6 is the only web container that ships with Fedora today, that is not going to be the case indefinitely. Efforts to package up other Servlet containers are underway. Thus, the deployment approach should be agnostic of targeted servlet container. If the webapp RPM maintainer wants to perform additional Tomcat specific configuration, that should be done in a separate RPM from the main code, with a title of: <appname>-tomcat6-<version>.rpm where the version is the App version, not the tomcat6 version. If the end user chooses to deploy this way, it is acceptable, but not required, for the app to be in the deployed state after RPM installation. This choice should be documented in the Spec file info.
Fedora should provide a series of scripts, a-la JPackage, that perform Servlet container specific actions. These are:
- Create a JDBC Database pool
- Create an LDAP connection pool
- Set up an Authentication Realm
- Register a Globally scoped JNDI named component.
- deploy a war file or expanded webapp directory
- Enable SSL on port 8443
- Configure apache to work as an AJP proxy
- Add a webapp to the AJP proxy definition
Please provide feedback.