Java/Packaging/Cookbook
From openSUSE
Contents |
Java Packaging Tutorial
This is a step by step introduction on how to build software packages of Java applications and libraries for openSUSE and others using the openSUSE Build Service.
First steps : Get prepared
- Register your Build Service account.
- Become familiar with the Build Service web application.
- Add the openSUSE Tools repository and install osc.
- Add the repositories you want to build for. A good starting point is 'openSUSE 10.3'. We will leave cross-platform package building for an advanced tutorial.
- Add a package in the build service for the software you want to package.
- 'Name' is how the package should be named, e.g. "ultimatesoftware" (which would produce a package "ultimatesoftware-VERSION-RELEASE.ARCH.rpm"
- 'Title' is the short description visible in YaST Software Management's package list.
- 'Description' is the long description shown separately.
- Tick the box 'Create RPM SPEC file template' to get SPEC file template. You can use it later as a starting point.
Get source and patch files
- add the tarball containing the source code of your program to the project using [add file]. The source code archive can be uploaded from a local computer or directly from the project homepage by specifying the URI.
Work on the Specfile
A template spec-file is already created for you and added as <packagename>.spec to your project. If there is an existing spec file already, you can use this by adding it to the project files.
Building the package
It is advised to do a local build first to check wheter everything is working properly. You also get an immediate feedback if the build fails (which will probably happen with first attempts). Once the package is building locally, you can then update your openSUSE build project folder with all the changes.
- Local build
osc build openSUSE_10.3 ARCH <packagename>.spec
once this is successful, commit the changes to your project folder with
osc commit
then go to the website and mark the package for rebuild. There will be a feedback in you package folder if the build was successful.
Sun Java
Sun Java is not available in the standard repository, so you must add the NonFree repository, which contains the Sun JDK. Just type
osc meta prj [your project] -e
and add the repository
<repository name="openSUSE_10.3">
<path project="openSUSE:10.3" repository="standard"/>
<!-- the NonFree repository -->
<path project="openSUSE:10.3:NonFree" repository="standard"/>
...
BuildRequires
java-devel- a prefered symbol. In 11.0+ is expanded to java-1_6_0-openjdk-devel, which is based on sources of java-1_6_0-sun-devel. For older releases is this symbol often expanded to an opensource Java implementation (e.g. gcj), which often needs some source code adjustments to build properly with.java-1_5_0-sun-devel- an explicit require of the Sun JDK and compiler. This option produces less errors, because the vast majority of Java developers use this JDK. This option needs to add the NonFree repository (see above)java-1_6_0-openjdk- the "OpenJDK Java" implementation is available in 11.0+; this is the GPL version of Sun's Java.
Example:A standalone application
As an example, we shall use "columba", an e-mail client that is completely written in Java. An example spec-file can be seen below.
columba.spec
Name: columba
Summary: eMail client written in Java
Version: 1.4
Release: 1
License: GNU General Public License (GPL)
Group: Productivity/Networking/Email/Clients
Source: http://prdownloads.sourceforge.net/columba/columba-%{version}-src.zip
URL: http://www.columbamail.org
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires:unzip
BuildRequires:update-alternatives java-1_5_0-sun-devel
BuildRequires:ant
Requires: java >= 1.5.0
BuildArch: noarch
%description
Columba is an Email Client written in Java, featuring a user-friendly
graphical interface with wizards and internationalization support. Its
a powerful email management tool with features to enhance your
productivity and communication.
So, take control of your email before it takes control of you!
Feature Highlights
* Clean and Response User Interface
* Cross Platform
* Internationalization
* Unlimited Functionality using Plugins
* Safe and Secure
* Glueing together Third-Party Tools
* Multiple Accounts and Profiles
%prep
%setup -q -n "columba-%{version}-src"
# remove the third party jars
find . -iname '*.jar' | xargs rm -rf
%build
%ant jar
%install
# jars
%__install -d -m 0755 "%{buildroot}%{_datadir}/%{name}"
%__install -m 0644 columba.jar "%{buildroot}%{_datadir}/%{name}/"
# lib
#%__install -d -m 0755 "%{buildroot}{_datadir}/%{name}/lib/jpa"
#%__install -m 0755 lib/jpa/* "%{buildroot}%{_datadir}/%{name}/lib/"
%__cp -rp lib "%{buildroot}%{_datadir}/%{name}/"
%__install -d -m 0755 "%{buildroot}%{_datadir}/%{name}/native"
%__cp -rp native/linux "%{buildroot}%{_datadir}/%{name}/native/"
%__install -d -m 0755 "%{buildroot}%{_datadir}/%{name}/plugins"
%__cp -rp plugins/* "%{buildroot}%{_datadir}/%{name}/plugins/"
# startscript
%__install -d -m 0755 "%{buildroot}%{_bindir}"
cat > "%{buildroot}%{_bindir}/%{name}" << EOF
#!/bin/sh
exec java -jar %{_datadir}/%{name}/%{name}.jar
EOF
%__chmod 0755 "%{buildroot}%{_bindir}/%{name}"
%clean
%__rm -rf "%{buildroot}"
%files
%defattr(-, root, root)
%doc AUTHORS CHANGES LICENSE README
%{_bindir}/%{name}
%{_datadir}/%{name}
%changelog
* Wed Nov 14 2007 - PACKAGERNAME@opensuse.org
- initial RPM for columba on openSUSE
Example: a Java library
The columba was a standalone application. For the packaging of the libraries, there're some differences. The following skeleton for Java libraries is derived from jpackage.org spec files. The're some special macros like %{_javadir} - for details see Java/Packaging/RPM_Macros. The convient scripts from jpackage-utils used for build (and run) are described on Java/Packaging/jpackage-utils.
### the skeleton for packaging of the java libraries
### many of these techniques are based on approach of jpackage.org spec files
Name:
Version:
Release:
Summary:
Group: Development/Libraries/Java
License:
URL:
Source:
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildArch: noarch
BuildRequires: java-devel
BuildRequires: ant
BuildRequires: jpackage-utils
%description
### Many of Java packages contains a javadoc and this is universal notation
### usefull for majority of Java packages
%package javadoc
Summary: Javadoc for %{name}
Group: Development/Libraries/Java
Requires(post): /bin/ln
Requires(post): /bin/rm
Requires(postun): /bin/rm
%description javadoc
This package contains a javadoc.
%prep
%setup -q
# remove all third party jars
find . -iname '*.jar' | xargs rm -rf
### Many of Java software comes from Windows, so this sed edit the files with
### Windows encoding - the shell scripts probably not works with the Windows end of lines!
#sed -i -e 's/.$//'
%build
### Sometimes is necessary to set the CLASSPATH before build
### build-classpath is a standard tool from jpackage-utils
#export CLASSPATH=$(build-classpath foo)
ant
%install
### create of the directory for installing the jars
install -d -m 755 $RPM_BUILD_ROOT/%{_javadir}
# jars
### make name of jars version agnostics
(cd $RPM_BUILD_ROOT%{_javadir}/%{name} && for jar in *-%{version}*; do ln -sf ${jar} ${jar/-%{version}/}; done)
# javadoc
install -d -m 755 $RPM_BUILD_ROOT/%{_javadocdir}/%{name}-%{version}
cp -pr api/* $RPM_BUILD_ROOT/%{_javadocdir}/%{name}-%{version}
ln -s %{name}-%{version} $RPM_BUILD_ROOT/%{_javadocdir}/%{name} # ghost symlink
%clean
rm -rf $RPM_BUILD_ROOT
%post javadoc
rm -f %{_javadocdir}/%{name}
ln -s %{name}-%{version} %{_javadocdir}/%{name}
%postun javadoc
if [ "$1" -eq 0 ]; then
rm -f %{_javadocdir}/%{name}
fi
%files
%defattr(-,root,root,0755)
%{_javadir}/%{name}*.jar
%files javadoc
%defattr(-,root,root)
%{_javadocdir}/%{name}-%{version}
%ghost %{_javadocdir}/%{name}
%changelog
Third party jars
The Java upstream includes a libraries as a jars into the source archives. This approach has purpose for developers, which tends to quick build of the projects withouth needs to download/or compile all dependent files. Due the platform independence there's no problem with using of the binary jars. But this is not very usefull for package maintaners and the convient approach in Linux distribution is use of the system jars (widely located in /usr/share/java) for build and run-time. There're some special cases (eg. signed jars) is not possible to build own jar, but in the common case, there's no reason for use the third party binaries.
Including external binaries is evil because:
- They are useless for people trusting only self-built software. - They are useless for people who already have those binaries. - It makes tracking dependencies a nightmare. - It makes archives bigger.
(from [jpackage.org:Request to Java developers]
Building it
We use the osc command-line tool to perform a local build now, as repeated builds to correct errors go faster when using --noinit.
osc build openSUSE_10.3 x86_64 columba.specOnce the package builds, we check it into the buildservice with
osc commit
Troubleshooting
bytecode version error
If you got an error
ERROR: the files above contain java bytecode for something later than java 1.5, ERROR: please set the javac target to 1.5 or lower
you can set a target to 1.5
-Dant.build.javac.source=1.5 -Dant.build.javac.target=1.5
or suppress this test by
export NO_BRP_CHECK_BYTECODE_VERSION=true
in %install section. This check is necessary for SLE and for packages in Build Service this can be suppressed.

