Java Developer Guide/Using java-pkg-simple.eclass
java-pkg-simple.eclass is an eclass that provides a way to build Java packages on Gentoo in a simplistic manner. This is package system independent. Most packages can be built using java-pkg-simple.eclass global variables in the ebuild. Using such one can omit the entire src_prepare()
, src_compile()
and src_install()
sections in most cases.
In case the package uses Maven as the build system, you can also use Gentoo tool app-portage/java-ebuilder to generate the ebuild skeleton. Though this application is still in experimental phase and some of its features are not yet supported by java-pkg-simple.eclass, it can give you fast overview of the package and also an ebuild skeleton to start with. You can also participate in improving the tool to make it more usable.
Basic Java ebuild skeleton
Users of vim get a basic skeleton automatically as shown below (provided by app-vim/gentoo-syntax):
user $
mkdir -p repository/dev-java/foobar && cd $_
user $
vim foobar-1.0.ebuild
# Copyright 2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 EAPI=8 JAVA_PKG_IUSE="doc source test" MAVEN_ID="" MAVEN_PROVIDES="" JAVA_TESTING_FRAMEWORKS="junit-4" inherit java-pkg-2 java-pkg-simple DESCRIPTION="" HOMEPAGE="" SRC_URI="" S="${WORKDIR}/${P}" LICENSE="" SLOT="0" KEYWORDS="~amd64" CP_DEPEND="" DEPEND="${CP_DEPEND} >=virtual/jdk-1.8:*" RDEPEND="${CP_DEPEND} >=virtual/jre-1.8:*"
MAVEN_ID=
in case of a single-jar ebuilds or MAVEN_PROVIDES=
in case of a multi-jar ebuild are evaluated by java-ebuilder.
More detailed ebuild skeletons can be generated from packages providing pom.xml (Project Object Model) files by using the java-ebuilder.
Preparing sources
java-pkg-simple.eclass uses the normal src_unpack()
and src_prepare()
ebuild phase functions. Within src_prepare()
, it is essential to call java-pkg-2_src_prepare and, until EAPI 8 in case there is a PATCHES array, also default.
PATCHES=(
"${FILESDIR}"/${P}-foo.patch
"${FILESDIR}"/${P}-bar.patch
)
src_prepare() {
default # https://bugs.gentoo.org/780585
java-pkg-2_src_prepare # for any actions (cp, rm, mv, sed or other) except patches
...
}
Due to java-pkg-simple_src_install defining exactly what is getting installed in the src_install()
phase, it is except some very rare cases not needed to remove bundled .jar or .class files. However, running java-pkg_clean can make packaging easier, not getting confused by stuff not created from the ebuild.
src_prepare() {
java-pkg_clean ! -path "./shared/data/*" # keep icudata.jar, icutzdata.jar, testdata.jar
java-pkg-2_src_prepare
}
Missing dependencies
If compilation doesn't succeed out of the box then usually one or more dependencies are missing. Grepping the build.log should then give a condensed summary:
user $
grep 'does not exist' build.log | cut -d':' -f4-7 | sort | uniq
package com.thoughtworks.xstream does not exist package com.thoughtworks.xstream.converters does not exist package com.thoughtworks.xstream.io does not exist package freemarker.template does not exist package org.nibblesec.tools does not exist
Typical examples using java-pkg-simple.eclass
inherit java-pkg-2 java-pkg-simple
...
# One or more directories with sources in them relative to ${S}.
# It is mandatory.
JAVA_SRC_DIR="src/main/java"
# List of java packages to put on the classpath.
# It is mandatory in case the package has dependencies.
# No need to set this for dependencies listed in CP_DEPEND
JAVA_GENTOO_CLASSPATH="xalan:2,log4j:0"
# This is used to add raw jars to the classpath,
# jars either bundled or installed outside portage.
# It contains paths to jars, not package names.
# Paths can be absolute or relative to the package build system.
# Paths are colon separated.
JAVA_GENTOO_CLASSPATH_EXTRA="lib/bundled.jar:/path/to/system.jar"
# In case the package does not use UTF-8 encoding, you can specify
# the used encoding.
# It is used for javac and javadoc commands.
JAVA_ENCODING="ISO-8859-1"
# Optional additional arguments to be passed to javac.
JAVAC_ARGS="-Xms:64m"
# Optional additional arguments to be passed to javadoc.
JAVADOC_ARGS="-J-Xmx180m"
# This is used to add "Main-Class: " to MANIFEST.MF and also
# triggers the creation of a launcher. It can not be used in
# cases where the launcher requires optional arguments.
JAVA_MAIN_CLASS="com.biglybt.ui.Main"
One of the most common directory structures has src and resources directories like
work
└── commons-codec-1.15-src
├── pmd.xml
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── org
│ └── resources
│ └── org
└── test
├── java
│ └── org
└── resources
└── org
This would accordingly need
JAVA_RESOURCE_DIRS="src/main/resources"
JAVA_SRC_DIR="src/main/java"
JAVA_TEST_RESOURCE_DIRS="src/test/resources"
JAVA_TEST_SRC_DIR="src/test/java"
resulting in an ebuild like
# Copyright 1999-2022 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=8
JAVA_PKG_IUSE="doc source test"
MAVEN_ID="commons-codec:commons-codec:1.15"
JAVA_TESTING_FRAMEWORKS="junit-4"
inherit java-pkg-2 java-pkg-simple
DESCRIPTION="Implementations of common encoders and decoders in Java"
HOMEPAGE="https://commons.apache.org/proper/commons-codec/"
SRC_URI="mirror://apache/commons/codec/source/${P}-src.tar.gz -> ${P}.tar.gz"
S="${WORKDIR}/${P}-src"
LICENSE="Apache-2.0"
SLOT="0"
KEYWORDS="~amd64 ~arm ~arm64 ~ppc64 ~x86 ~amd64-linux ~x86-linux"
DEPEND="
>=virtual/jdk-1.8:*
test? (
>=dev-java/commons-lang-3.11:3.6
)
"
RDEPEND=">=virtual/jre-1.8:*"
JAVA_AUTOMATIC_MODULE_NAME="org.apache.commons.codec"
JAVA_RESOURCE_DIRS="src/main/resources"
JAVA_SRC_DIR="src/main/java"
JAVA_TEST_GENTOO_CLASSPATH="junit-4,commons-lang-3.6"
JAVA_TEST_RESOURCE_DIRS="src/test/resources"
JAVA_TEST_SRC_DIR="src/test/java"
Tests
Tests can run only when JAVA_PKG_IUSE has the test flag and JAVA_TESTING_FRAMEWORKS is filled.
Conditional test exclusions - JAVA_TEST_EXCLUDES
Tests can be excluded using the JAVA_TEST_EXCLUDES eclass variable. In cases where exclusions should apply only to certain Java versions it can be done using the ver_test function as shown in the following example. Disadvantage: Loosing tests if the excluded test class has more only one test.
src_test() {
local vm_version="$(java-config -g PROVIDES_VERSION)"
if ver_test "${vm_version}" -ge 17; then
...
JAVA_TEST_EXCLUDES+=(
org.assertj.core.internal.classes.Classes_assertHasMethods_Test
org.assertj.core.util.xml.XmlStringPrettyFormatter_prettyFormat_Test
)
fi
java-pkg-simple_src_test
}
Conditional test exclusions - junit assume
A more sophisticated way to conditionally skip single tests is using junit assume as is demonstrated in commit #eabdf0892f
External tools
While in many if not most cases build.xml, pom.xml, build.gradle can be easily translated into ebuild it could get more chellenging when it comes to code generation be it java code, parsers or other code. There are already examples in the main ebuild repository of how it can be done solely in the ebuild without using external tools or even writing scripts for them.