JPackage packaging policy

Package

Name

The package name, hereafter referred to as %{name}, is the complete name of the packaged software. %{name} must be in lowercase.

Exception: if it is a requirement that multiple versions of a package can be installed to a single machine, relevant part of the version number is appended to complete software name to form the package name.

Epoch

All packages must define an Epoch tag, starting from 0 and bumping only when everything else fails. Note that the Epoch must also be present in all versioned dependencies.

Version

The package version, hereafter referred to as %{version}, is the complete version of the packaged software.

If no exact version is available, as in non-tagged CVS snapshots, use the snapshot date in YYYYMMDD format.

Exception: non-numeric version extensions, such as "pre", "rc", "beta" etc, are prohibited as they may confuse RPM. Instead, they must be included in the package release tag.

Release

The package release, hereafter referred to as %{release}, is a strictly increasing number within a single %{version}, starting from 1 and followed by project specific jpp suffix. When %{version} increases, %{release} is reset back to the starting value.

Exception: when non-numeric version extensions are used, this number is preceded by the number 0, a dot, and the version extension to ensure proper release ordering.

Other tags

All JPackage RPMs should have the following tags in the specfile.

Vendor:             JPackage Project
Distribution:       JPackage

Do not hardcode the Packager tag into the specfile, set it in your ~/.rpmmacros instead. Additionally, don't use the DistURL tag as its semantics are unclear.

Granularity

Small is beautiful: prefer several modular subpackages when possible.

The main package must contain only basic files needed for running the software, with license agreement and basic documentation files.

Any optional files must be provided in a separate subpackage, with exact %{epoch}:%{version}-%{release} dependency to the main package.

Especially for library-style packages, any nice-to-have shell scripts must be packaged in a separate %{name}-scripts subpackage, with exact %{epoch}:%{version}-%{release} dependency to the main package, as well as practically always a dependency on jpackage-utils >= 0:1.5. This practice is recommended but not mandatory for all packages in general.

Any demo or sample files must be provided in a separate %{name}-demo subpackage, with exact %{epoch}:%{version}-%{release} dependency to the main package.

User manual must be provided in a separate %{name}-manual subpackage, with no dependency to the main package.

Each Javadoc tree must be provided in a separate %{name}-javadoc subpackage, with no dependency to the main package.

Sections

free section contains free software.

non-free section contains non-free and non-distributable software.

Dependencies

Practically all packages must have a build time dependency on jpackage-utils >= 0:1.5.

A free package must avoid optional non-free runtime dependencies. However, to ensure proper builds, all needed dependencies, free or not, must be listed as build requirements.

Files

Locations

In general, all installation locations must be FHS compliant.

Application archives must be installed under the %{_javadir} directory (defined in jpackage-utils macros) in the following way:

  • For simple software with just a few jars, directly to the top level, ie. %{_javadir}.
  • For simple software with many jars, into the %{_javadir}/%{name} directory.
  • For complex applications, in a %{_javadir}/%{name} subdirectory with proper internal structure.

Data and demo files must be installed into the standard %{_datadir}/%{name} directory.

Javadoc files must be installed into the %{_javadocdir}/%{name}-%{version} directory as %doc, accompanied with a %post scriptlet that will symlink the last one installed into non-versioned %{_javadocdir}/%{name}. The non-versioned symlink should be owned by all appropriate javadoc packages as a %ghost file.

%install
...
ln -s %{name}-%{version} $RPM_BUILD_ROOT%{_javadocdir}/%{name}

%post javadoc
rm -f %{_javadocdir}/%{name}
ln -s %{name}-%{version} %{_javadocdir}/%{name}

%files javadoc
%defattr(644,root,root,755)
%doc %{_javadocdir}/%{name}-%{version}
%ghost %doc %{_javadocdir}/%{name}

Manual packages must list all their files as documentation, using %doc (and %docdir where needed).

Names

The general idea is that given package name, one should be able to deduce jar name(s): package abcd should contain either a single %{_javadir}/abcd.jar jar, or multiple %{_javadir}/abcd/*.jar or %{_javadir}/abcd-*.jar jars.

Main jars stored directly under %{_javadir} must follow the %{name}-%{version}.jar naming pattern.

Secondary jars stored directly under %{_javadir} must follow the %{name}-subpackage-%{version}.jar naming pattern.

Jars stored in a %{_javadir}/%{name} subdirectory must follow the subpackage-%{version}.jar naming pattern.

All zip archives must be converted to jars, and a compatibility symlink be provided.

All legacy names must be converted to standard names, and a compatibility symlink be provided if there's substantial difference.

Compatibility symlinks follow the same versioning requirements as jars in general.

For every versioned jar or symlink, a corresponding unversioned symlink must be provided to allow version independent use.

Granularity

Once again, small is beautiful: prefer several modular jars when possible.

Avoid duplicate classes, and remove redundant jars.

Alternatives

Whenever necessary or beneficial, use the alternatives system.

Require /usr/sbin/update-alternatives, not a specific package name for maximum cross-distro compatibility.

Always use non-versioned jars in alternatives.

Install alternatives in the %post script.

Remove alternatives in the %preun script, but not when the package is being upgraded, only when it's being erased.

Make sure there aren't two packages with the same priority, as it is not documented which one will be chosen in automatic mode if there are multiple alternatives sharing the highest priority.

Building

In order to track source origin, it is preferable to use unmodified original archives, when available in a form suitable for building.

If possible, never use external binaries provided in upstream distributions (jars, executables, etc). Delete them to ensure that they won't interfere with the build process.

Running

All applications must use a standardized wrapper script, using the JPackage function library.

All servers must be shipped with usual service/init script, logrotate configuration, etc...

Classpath references in MANIFEST.MF files interfere with classpath, are not configurable, and don't work in JDK 1.1.x. They must be removed.