openSUSE:Packaging Java

Jump to: navigation, search


The Packaging Java 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.

(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.