openSUSE:Packaging Java
Build Service Tutorial · Tips & Tricks · Cross Distribution Howto · Packaging checks
Desktop menu categories · RPM Macros · Scriptlets · Init scripts · How to write good changes
(Build)Requires
Java (mean the usual bundle of runtime, compiler et al) is splitted into JRE — Java Runtime Environment and JDK — Java development kit. The first contains java
command and is required for running of Java applications. As SUSE follows jpackage.org compatible naming scheme, runtime is represented by java
symbol. The SDK uses java-devel
. Both are versioned, so you can request a minimal version of Java to be used. Obviously you have to distinguish between GNU Java and others, so in a most common case, you will request Java higher than 1.6.0 (excluding gcj to be selected).
BuildRequires: java >= 1.6.0 Requires: java >= 1.6.0
This will be expanded to the default implementation on each product. Using of full package name is prohibited as it will break dependencies on each Java update in SUSE.
Starting the program
Often, java applications do not provide a startscript to start the program from command line or to be used in connection with a desktop entry/icon. In this case, use the following code snippet in %install - section of your spec - file
# startscript cat > %{name} << 'EOF' #!/bin/sh # # <Program Name> startscript # echo Starting %{name} version %{version} ... echo with options : \${@} java -jar %{_datadir}/%{name}/%{name}.jar \${@} EOF
then install the script to /usr/bin with the following two lines
install -d -m 755 %{buildroot}%{_bindir} install -m 755 %{name} %{buildroot}%{_bindir}/
Now you should be able to launch the program from the command line and refer to it in the desktop file, by just giving the name.
Java versions
Sun Java
Sun Java is not available in the openSUSE anymore. The last obsolete and insecure version we can distribute are in Java:sun:Factory. More recent releases have license prohibits us to distribute it.
Java repositories
- Java:packages - a devel project for all Java packages, you can find here the latest versions for Factory
- Java:openjdk6:Factory - devel project for openjdk
Examples
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 BuildArchitectures: 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 -qn columba-%version-src # remove the third party jars find . -type f -iname "*.jar" -delete %build %ant jar %install # jars install -dm 0755 "%buildroot/%_datadir/%name" install -m 0644 columba.jar "%buildroot/%_datadir/%name/" # lib #install -dm 0755 "%buildroot/%_datadir/%name/lib/jpa" #install -m 0755 lib/jpa/* "%buildroot/%_datadir/%name/lib/" cp -rp lib "%buildroot/%_datadir/%name/" install -dm 0755 "%buildroot/%_datadir/%name/native" cp -rp native/linux "%buildroot/%_datadir/%name/native/" install -dm 0755 "%buildroot/%_datadir/%name/plugins" cp -rp plugins/* "%buildroot/%_datadir/%name/plugins/" # startscript install -dm 0755 "%buildroot/%_bindir" cat >"%buildroot/%_bindir/%name" << EOF #!/bin/sh exec java -jar "%_datadir/%name/%name.jar" EOF chmod 0755 "%buildroot/%_bindir/%name" %files %doc AUTHORS CHANGES LICENSE README %_bindir/%name %_datadir/%name %changelog
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 openSUSE:Java_RPM_Macros. The convient scripts from jpackage-utils used for build (and run) are described on openSUSE:Java_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 BuildArchitectures: noarch BuildRequires: java-devel BuildRequires: ant BuildRequires: javapackages-tools %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/Javam %description javadoc This package contains a javadoc. %prep %setup -q # remove all third party jars find . -type f -iname "*.jar" -delete ### 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! #perl -i -pe 's{\r\n$}{\n}gs' %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 -dm 755 "%buildroot/%_javadir" # jars ### make name of jars version agnostics (cd "%buildroot/%_javadir/%name" && for jar in *-%{version}*; do ln -sf "$jar" "${jar/-%version/}"; done) # javadoc install -dm 755 "%buildroot/%_javadocdir/%name-%version" cp -pr api/* "%buildroot/%_javadocdir/%name-%version/" %files %_javadir/%{name}*.jar %files javadoc %_javadocdir/%name-%version %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 is no problem with using of the binary jars. But this is not very useful for package maintaners, and the convient approach in Linux distribution is the use of the system-wide jars (located in /usr/share/java) for build and run-time. There are some special cases (e.g. signed jars) for which is not possible to build own jar, but in the common case, there is no reason for using 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]
Troubleshooting
bytecode version error
Warning: this error exists only for SLE11 targets, more recent openSUSE releases do not limit the bytecode version.
If you get 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 the target to 1.5
-Dant.build.javac.source=1.5 -Dant.build.javac.target=1.5
For maven:
mvn-jpp -Dmaven.compile.target=1.5 -Dmaven.javadoc.source=1.5 ...
or suppress this test by:
export NO_BRP_CHECK_BYTECODE_VERSION=true
in the %install
section.