From Fedora Project Wiki
m (Minor formatting change to make the numbered items easier to read. No content changes.)
(Remove dead discussion points, clean up.)
Line 1: Line 1:
= Packaging Java Web Applications =
= Packaging Java Web Applications =


Please also read the ["PackagingDrafts/Java"]  guidelines.
{{admon/important|Please contribute to discussion|Most of discussion points that were mentioned here were removed, with an effort to integrate parts that discussed deeply enough to make a conclusion in this draft. Look in the history to see what they were and feel free to raise them again if you feel otherwise. Feel free to comment on anything if you disagree, of have an idea how to improve the draft.}}


'''We really need a separate section for web application policies within Fedora (for all web applications, not just Java related ones)'''
{{admon/tip|Java Guidelines|
Please be sure to read [[Packaging/Java|Java Packaging Guidelines]]. They contain information that is generally useful when dealing with Java packages, and need to be complied with.}}


Web applications can be written in Java to be deployed on a Java web server (for example Tomcat and Jetty).  These applications are bundled into what is referred to as a WAR file.  Like a JAR file, a WAR file is similar to a zip archive and contains all data needed to run the application, this includes things like images, html pages, servlets, JAR files and configuration files.
{{admon/important|Web Applications|We really need a separate section for web application policies within Fedora (for all web applications, not just Java related ones)}}


The problem with WARs is that they contain JAR files which may already exist on the system. This means that JAR files would have to be maintained in multiple locations on the machine.
== Web Application Archives ==


Fortunately, most servers can use WAR files in an 'exploded' formatThis means that the WAR file is expanded into a directory structure instead of being an archive and we can symbolically link the JAR files as needed.
Web applications can be written in Java to be deployed on a Java web server (for example [http://tomcat.apache.org/ Tomcat] and [http://www.mortbay.org/jetty-6/ Jetty]).  These applications are bundled into what is referred to as a WAR fileLike a JAR file, a WAR file is similar to a zip archive and contains all data needed to run the application, this includes things like images, html pages, servlets, JAR files and configuration files.


e.g. package <code>foo</code> which provides <code>foo.war</code>, the package would have:
The problem with WARs is that they contain JAR files which may already exist on the system. This means that JAR files would have to be maintained in multiple locations on the machine. Fortunately, most servers can use WAR files in an ''exploded'' format.  This means that the WAR file is expanded into a directory structure instead of being an archive and we can symbolically link the JAR files as needed; e.g. package <code>foo</code> which provides <code>foo.war</code>, the package would have:


<pre>
<pre>
%{_datadir}/%{name}/foo.war/
webapps/%{name}/foo/
%{_datadir}/%{name}/foo.war/WEB-INF/lib/bar1.jar -> %{_javadir}/bar1.jar
webapps/%{name}/foo/WEB-INF/lib/bar1.jar -> %{_javadir}/bar1.jar
%{_datadir}/%{name}/foo.war/WEB-INF/lib/bar2.jar -> %{_javadir}/bar2.jar
webapps/%{name}/foo/WEB-INF/lib/bar2.jar -> %{_javadir}/bar2.jar
</pre>
</pre>


* '''What should the web app be called:  <code>foo.war</code> ,<code>foo.war-exploded</code> or just <code>foo</code>?  What if <code>foo</code> provides more than just a web app?  %{_datadir}/%{name}/foo/webapp or is specific to a particular server %{_datadir}/%{name}/foo/webapp-tomcat5?'''
== Directory structure ==
# '''In the above example, both, the package and war name are foo. However, that is not a necessity. The war can have any name. Thus multiple webapps within a package is a non issue. With regards to webapp dir name, what about <name>.war-exploded? It will prevent confusion as to whether or not it is a file'''
# '''regarding applications for specific servers, foo can still go in %{_datadir}/%{name}/... , with a foo-$server package that sets up the deployement for that server in which it works'''
# '''Application can use %{_datadir}/%{name} for its own purposes, therefore it might be a better idea to use something like %{_datadir}/webapps/%{name}/webapp-name''' (-- LubomirKundrak)
# '''I have a strong objections against calling the directory with webapp <code>webapp.war</code> or <code>webapp.war-exploded</code>. For <code>-exploded</code>} is unnecessary, as it's obvious from being a directory and <code>.war</code> stands for web application archive, and being exploded this is no longer an archive (at least not in traditional meaning''' (-- LubomirKundrak)
# '''If a web application is specific to a web server, why install it in %{datadir} and not in directory specific for that server? One objection might be a way to un-deploy the application by deleting a symlink would not be possible, but equivalent way is to just uninstall the subpackage''' (-- LubomirKundrak)
# '''I propose that we use the path /var/java/www/%{name}.war for all server deployments.  I don't see a problem running the application as exploded due to the nature of need to modify files like hibernate configurations and web.xml.  Many sysadmins use something like puppet or cfengine to override these files based on the environment they are going to be running in (ie dev, qa, stage, prod).  if you run this as a package, you will need to start the server, see it fail, shutdown, edit configs, restart the server.''' (-- LeeFaus)
# '''I am wondering where did the /var/java/www path originate from? /var is for variable data as defined by FHS, we should really stick with /usr/share, as is currently mandated for other web applications.''' (-- LubomirKundrak)
# '''I somewhat agree with the duplicate jars as mentioned above, the downside is you remove the advantages of the classloader in this situation.  If the %{_javadir} is loaded as a classpath and I need a newer version of a framework, I can't override it.  This is one of the things I disagree with in the JavaPackaging standards as well.  Java allows the developer to load frameworkA.1.0.1.jar and frameworkA.1.1.jar.  As long as frameworkA.1.1.jar is loaded first in the class loader, I will get it's functionality over frameworkA.1.0.1.jar.  This is critical for many Java Web Applications and developers exploit this functionality routinely.  There needs to be some rule about where it is ok to override this functionality and when it is not.''' (--LeeFaus)
# '''I am attaching a graphic of a sample of how I see symlinking to other directories on the filesystem to help make some of my suggestions clear''' (--LeeFaus)


== Sample Directory Listing ==
=== Server independent part ===
[[Image:PackagingDrafts_JavaWebApps_sample.dir.layout.png]]


According to [[Packaging/Guidelines#Web_Applications|existing practice]], the web application data should be placed to <code>%{_datadir}</code>.
The package can contain more than a single web application -- it can contain a GUI or CLI application, either of them possibly using %{_datadir}/%{name}, or multiple web applications.
A web application is possibly named differently from the package. Therefore use of %{_datadir}/%{_name} should be avoided.


Web applications should be installed at <code>%{_datadir}/%{name</code>} instead of into the webapps directory of the application server. The application can then be deployed by creating a symlink from the exploded web application to the deployment directory of a specific server. Installation directly into the webapp folder of a specific server would cause automatic deployment, and is not desirable for the following reasons:
A suitable name, what would prevent all sorts of naming conflicts would be <code>%{_datadir}/webapps/%{name}/foo</code>. Note that the name <code>webapps</code> was chosen after existing naming practice of Tomcat. <code>foo</code> stands for name of the web application archive stripped of <code>.war</code> suffix, since it's no longer an archive.


* In many situations the web application should be able to be deployed by various web servers (for example Tomcat or Jetty). By not installing the application in the webapps folder of a specific server allows the application to be shared among different servers.
{{admon/warning|Existing practice|Non-java based web applications such as <code>squirrelmail</code>, <code>phpMyAdmin</code> or <code>bugzilla</code> currently use <code>%{_datadir}/%{_name}</code>. Should we follow that practice, not taking the above paragraphs into account?}}


* Configuration changes can be done before deployment and the application can be undeployed without losing changes (undeployment is usually done by removing the application from the webapp directory, or in this case removing the symlink).
The configuration files should not go to <code>%{_datadir}</code>, but rather in <code>%{_sysconfdir}</code>, and be symbolically linked to where the web application expects it (<code>%{_datadir}</code>).


* There may be security reasons for not autodeploying the application (for example, needing to change the default password). This type of application should never be automatically deployed.
=== Server dependent deployment ===


If the packager wants to give the web application the option of automatic deployment through an RPM, they can optionally provide container-specific subpackages which depend on the container and link to the exploded application directory. e.g. <code>foo-tomcat5</code>, which would provide a symlink:
Deployment is done by symbolically linking the directory with unpacked web application into server's webapps directory.


<code>          %{_datadir}/tomcat5/webapps/foo -> %{_datadir}/%{name}/foo.war</code>
For web applications to be included in Fedora, they must be deployable on at least one of the Java servers provided in Fedora (as of Fedora 8, Jetty or Tomcat).
WAR files contain many different XML configuration files (for example <code>web.xml</code> and <code>context.xml</code>).  These must be marked as <code>%config(noreplace)</code> to prevent changes from being overwritten.
''' What about configuration files? If we want to support deployment of package foo across multiple servers, perhaps we should also make it so that config files for each container reside in a container specific dir?'''
1. I wonder if it's worth the overhead, given how likely configuration it is. Do any PHP web applications already deal with this? (-- LubomirKundrak)
----
''' Are any of the items below even valid any more? I don't know what this talk of avoiding <code>%{_datadir}/%{name</code>}, providing only for tomcat5, etc. is all about. The guidelines above make the following clear:'''
** '''Provide the exploded war in %{_datadir}/%{name}/'''
** '''For all servers that you wish to provide a deployement for, create a /path/to/serverwebapps/%{name} -> %{_datadir}/%{name}/....war-exploded'''
'''Now, if there is a reason to not place items in <code>%{_datadir}/%{name</code>} at all, that is an issue... is anyone opposed to the placement there?'''
* '''From the section that was here before:'''
* '''If you for some reason need to create a WAR package, place it in <code>%{_datadir}/%{name</code>}. Try to avoid those.'''
* '''Why should these be avoided?'''
* '''Because they are analogous to static linking. Many web application depends on jars from foreign packages and given jars (zips) can not contain symbolic links, you would have to copy those, and loose benefits of the packaging system. Therefore I propose to forbid packaging wars and eventuelly provide a tool to construct a war from webapp directory with <code>jpackage-utils</code>.''' (-- LubomirKundrak)
* '''Assume that tomcat5 is the only container, analogically to what is done with non-java web applications and Apache httpd.'''
* '''Since Jetty is also within the Fedora distribution, why should tomcat5 be the only container assumed? Is there an official web application policy for Fedora?'''
* '''This was proposed by me, and I no longer share that opinion since much smarter alternative was proposed. Feel free to delete it''' (-- LubomirKundrak)
----
'''TODO: change this example if the above changes to the policy are acceptable'''
== Example ==
== Example ==


<pre>
''To be written''
...
 
BuildRequires:  jpackage-utils
 
...
 
%package tomcat5
Summary:        %{name} web application for Tomcat 5
Group:          Applications/Internet
Requires:      %{name} tomcat5
 
%description tomcat5
%{name} web application
 
...
 
%install
%define webapp %{_localstatedir}/lib/tomcat5/webapps/%{name}
...
unzip -q %{name}.war -d $RPM_BUILD_ROOT%{webapp}
(IFS=:; for file in
%{_javadir}/%{name}.jar                        \
%{_javadir}/%{name}/something_else.jar
do
ln -sf $file $RPM_BUILD_ROOT%{webapp}/WEB-INF/lib
done)
build-jar-repository $RPM_BUILD_ROOT%{webapp}/WEB-INF/lib <jar1> <jar2>
 
...
 
%files tomcat5
%config(noreplace) %{webapp}/WEB-INF/web.xml
%dir %{webapp}
%dir %{webapp}/WEB-INF
</pre>


* '''%files section looking like this would produce rpmlint warning about duplicate listing of %config files.'''
== Random notes ==
* '''%files duplicates fixed.'''
* '''I wonder if this is going to fly for all webapps, there might be some for which enumerating the files might produce too long lists''' (-- LubomirKundrak)


* '''Paths output by build-classpath are absolute and symlinks that would be created this way are absolute.'''
Fedora 9's <code>build-jar-repository</code> will probably not be able to create symlinks. Would it be okay if we either choose the <code>abs2rel</code> way or tolerated absolute links until Fedora 10, and [https://bugzilla.redhat.com/show_bug.cgi?id=442033 add the feature]  until then.
* '''Absolute symlinks should be fixed by changing build-classpath to output relative symlinks.  In the meantime, either waive the rpmlint warning or use abs2rel like in java-1.6.0-openjdk.'''
* '''Fedora 9's <code>build-jar-repository</code> will probably not be able to create symlinks. Would it be okay if we either choose the <code>abs2rel</code> way or tolerated absolute links until Fedora 10, and [https://bugzilla.redhat.com/show_bug.cgi?id=442033 add the feature]  until then.''' (-- LubomirKundrak)


There are other java web archives such as EARs, SARs, HARs, CARs, ... which deal with Java Enterprise Edition (JEE) Application Servers. These will need to be treated in the same manner as WARs. A section will be available here once a JEE server is available in Fedora.
There are other java web archives such as EARs, SARs, HARs, CARs, ... which deal with Java Enterprise Edition (JEE) Application Servers. These will need to be treated in the same manner as WARs. A section will be available here once a JEE server is available in Fedora.

Revision as of 18:32, 20 June 2008

Packaging Java Web Applications

Important.png
Please contribute to discussion
Most of discussion points that were mentioned here were removed, with an effort to integrate parts that discussed deeply enough to make a conclusion in this draft. Look in the history to see what they were and feel free to raise them again if you feel otherwise. Feel free to comment on anything if you disagree, of have an idea how to improve the draft.
Idea.png
Java Guidelines
Please be sure to read Java Packaging Guidelines. They contain information that is generally useful when dealing with Java packages, and need to be complied with.
Important.png
Web Applications
We really need a separate section for web application policies within Fedora (for all web applications, not just Java related ones)

Web Application Archives

Web applications can be written in Java to be deployed on a Java web server (for example Tomcat and Jetty). These applications are bundled into what is referred to as a WAR file. Like a JAR file, a WAR file is similar to a zip archive and contains all data needed to run the application, this includes things like images, html pages, servlets, JAR files and configuration files.

The problem with WARs is that they contain JAR files which may already exist on the system. This means that JAR files would have to be maintained in multiple locations on the machine. Fortunately, most servers can use WAR files in an exploded format. This means that the WAR file is expanded into a directory structure instead of being an archive and we can symbolically link the JAR files as needed; e.g. package foo which provides foo.war, the package would have:

webapps/%{name}/foo/
webapps/%{name}/foo/WEB-INF/lib/bar1.jar -> %{_javadir}/bar1.jar
webapps/%{name}/foo/WEB-INF/lib/bar2.jar -> %{_javadir}/bar2.jar

Directory structure

Server independent part

According to existing practice, the web application data should be placed to %{_datadir}. The package can contain more than a single web application -- it can contain a GUI or CLI application, either of them possibly using %{_datadir}/%{name}, or multiple web applications. A web application is possibly named differently from the package. Therefore use of %{_datadir}/%{_name} should be avoided.

A suitable name, what would prevent all sorts of naming conflicts would be %{_datadir}/webapps/%{name}/foo. Note that the name webapps was chosen after existing naming practice of Tomcat. foo stands for name of the web application archive stripped of .war suffix, since it's no longer an archive.

Warning.png
Existing practice
Non-java based web applications such as squirrelmail, phpMyAdmin or bugzilla currently use %{_datadir}/%{_name}. Should we follow that practice, not taking the above paragraphs into account?

The configuration files should not go to %{_datadir}, but rather in %{_sysconfdir}, and be symbolically linked to where the web application expects it (%{_datadir}).

Server dependent deployment

Deployment is done by symbolically linking the directory with unpacked web application into server's webapps directory.

Example

To be written

Random notes

Fedora 9's build-jar-repository will probably not be able to create symlinks. Would it be okay if we either choose the abs2rel way or tolerated absolute links until Fedora 10, and add the feature until then.

There are other java web archives such as EARs, SARs, HARs, CARs, ... which deal with Java Enterprise Edition (JEE) Application Servers. These will need to be treated in the same manner as WARs. A section will be available here once a JEE server is available in Fedora.