Skip to content

Java Development Environment

Thomas Florio edited this page Mar 24, 2026 · 40 revisions

Prerequisites and Preliminaries

Before it is possible to start working on the code, the following preparations need to be done:

Deployment

Install sumaform and start a virtual machine with the current version of Uyuni.

There are instructions if you don't want to use Terraform but those are not recommended for general development.

Git

Where <development_branch_name> will be master by default.

To create a new topic branch and switch to it use the following command:

git checkout -b master-<topic_name>

Use my-great-feature as the topic name if you work on a feature, or include a reference for bugs (like bsc1234567).


Configure the development machine

The project is using maven to build. If you are looking for the old ant/ivy approach see Configuring the development environment with ant and ivy

Install Java, ssh, rsync, maven and obs-to-maven. On openSUSE you can:

sudo zypper in java-17-openjdk-devel cpio openssh rsync maven

obs-to-maven can be found in systemsmanagement:Uyuni:Utils. Add the repository for your distribution and then install this package.

  • For SUSE related systems, install the package with the zypper command:
        sudo zypper addrepo obs://systemsmanagement:Uyuni:Utils systemsmanagement:uyuni:utils
        sudo zypper install obs-to-maven
  • For other systems, use your preferred package manager. Full list of supported systems.

Maven Project structure

Uyuni is composed of multiple Maven modules. The structure is:

  • uyuni-java-parent (directory microservices/uyuni-java-parent)
    • uyuni-java-common (directory microservices/uyuni-java-common)
      • attestation-core
      • attestation-module
      • attestation-module-snpguest
      • attestation-module-secureboot
    • coco-attestation (directory microservices/coco-attestation)
    • branding (directory branding)
    • spacewalk-java (directory java)
      • doclets
      • core
      • webapp

Due to RPM packaging requirements, this Maven structure is not reflected directly in the directory structure.

Working on spacewalk-java

Since this is now a multi-module project, in order to compile spacewalk-java in isolation (i.e., running mvn commands from the java/ directory), its module dependencies must first be installed in your local repository.

To avoid dependencies conflict, these steps should be executed before opening the project in an IDE (which might resolve the artifacts from maven central and not from obs).

  1. install uyuni-java-parent:
mvn -f microservices/uyuni-java-parent/ install --non-recursive
  1. install branding:
mvn -f branding/ install 
  1. initialize spacewalk-java, in order to download the proper dependencies from OBS
mvn -f java initialize

At this point, you should be able to build the spacewalk-java by simply calling mvn package from your java/ directory and open the project with any maven-aware IDE/editor.

The local repository

Currently it's only possible to build the project by getting the dependencies from OBS. During the initialize phase, all the dependencies are automatically fetched using obs-to-maven and stored in a local repository:

  • This process relies on the external script java/scripts/maven/download-to-local-repository.sh
  • You can call this script directly or explicitly using its Maven execution ID:
~/workspaces/uyuni/java> mvn exec:exec@download-dependencies --non-recursive

The script checks the obs-to-maven configuration for changes before running, but its execution can be forced by defining the property obs-to-maven.force when calling Maven:

~/workspaces/uyuni/java> mvn package -Dobs-to-maven.force

Note: The local repository created by Ant and the one created by Maven are different and live in separate directories. This is because, to enable future use of Maven on OBS, artifacts must have the proper groupId instead of the generic suse we used for Ant.

Running JUnit tests

The unit test execution is disabled by default due to the time it takes to complete. Before running the tests, you need to:

  • start the test database container by running make -f Makefile.docker dockerrun_pg or make -f Makefile.docker podmanrun. You can also run the container manually using docker/podman directly:
~/workspace/uyuni> podman run --interactive --tty --rm \
    -p 5432:5432 \
    -v ~/workspace/uyuni:/manager \
    registry.opensuse.org/systemsmanagement/uyuni/master/docker/containers/uyuni-master-pgsql-4eclipse

  • configure the rhn.conf file in buildconf/test, if needed. Please note that starting the database by using make will overwrite your current test configuration with the defaults of buildconf/test/rhn.conf.postgresql-example.

When the database is started, you should be able to run a single test directly from your IDE of choice, or using maven on the command line:

~/workspace/uyuni/java/core> mvn test -DskipTests=false -Dtest=AclManagerTest

where the property skipTests force the execution of the tests and the name of test to run can be specified using the test property. Omitting the latter, will run all the test suite. Ensure you are running the command on the correct maven module (core in this specific case).

Please note: currently running all unit test with maven might lead to some failures due to the different order of execution, compared to the old ant approach. We are currently working on fixing this behaviour.

Deploying the code

Deployment is now integrated with the Maven deploy phase and is handled by the script java/scripts/maven/deploy.sh. Currently, only the deployment of the webapp is integrated into the build. The new process works as before by defining a deploy.host property, while the mode is now remote-container by default, but can be modified using deploy.mode as usual:

~/workspaces/uyuni/java> mvn deploy -Ddeploy.host=uyuni-server.dev.local

The deployment script already supports also deploying the frontend code and the salt files and can be called directly:

~/workspaces/uyuni> npm --prefix web run build -- --check-spec=false
~/workspaces/uyuni> java/scripts/maven/deploy.sh frontend --host uyuni-server.dev.local

Please check deploy.sh --help for all its possible parameters

Generating XML RPC docs (aka apidoc)

During the build, it's possible to activate the generation of the API documentation by specifing the property generate.apidocs on the command line:

~/workspaces/uyuni/java> mvn package -Dgenerate.apidocs

Precompiling the JSP

During the build, it's possible to compile all the JSP so that tomcat won't need to do that at runtime. To activate this compilation, specify the property precompile.jsp:

~/workspaces/uyuni/java> mvn package -Dprecompile.jsp

Troubleshooting: moving from javax to jakarta libraries

With the migration towards Tomcat 11, the dependencies from javax to jakarta packages had to be moved as well. Unfortunately, the artifacts on both versions have the same groupid/artifactid/version, but they have incompatible jars. Maven caches the dependencies in the directory ~/.m2 (and Ivy in ~/.ivy for the ivy build). Therefore, moving from one version to the other can create compilation conflicts due to these incompatible jars.

The workaround consist on wiping the Maven and Ivy cache directories and rebuild the project again, so that the correct jars can be automatically downloaded. This has to be applied also if one wants to revert to an older commit that still uses the javax libraries after a compilation with the newer jakarta ones.

The following are the suggested steps:

# wipe the Maven cache 
rm -rf ~/.m2/

# wipe the ivy cache
rm -rf ~/.ivy2/

# clean the obs-to-maven cache
rm -rf <uyuni home dir>/java/.obs-to-maven-cache/
# clean ivy jars
rm -rf <uyuni home dir>/java/buildconf/ivy/repository/
# clean jars
rm -rf <uyuni home dir>/java/lib/

# clean build intermediate files
rm -rf <uyuni home dir>/java/build/
# clean build intermediate repository
rm -rf <uyuni home dir>/java/repository/

# clean maven target files
rm -rf <uyuni home dir>/java/webapp/target/
rm -rf <uyuni home dir>/java/doclets/target/
rm -rf <uyuni home dir>/java/branding/target
rm -rf <uyuni home dir>/microservices/uyuni-java-common/target/
rm -rf <uyuni home dir>/microservices/coco-attestation/attestation-core/target/
rm -rf <uyuni home dir>/microservices/coco-attestation/attestation-module-secureboot/target
rm -rf <uyuni home dir>/microservices/coco-attestation/attestation-module-snpguest/target/
rm -rf <uyuni home dir>/microservices/coco-attestation/attestation-module/target/

After this cleanup, the normal maven compilation will download the right jar libraries

# install uyuni-java-parent
mvn -f microservices/uyuni-java-parent/ install --non-recursive

# install branding
mvn -f branding/ install

# initialize spacewalk-java
mvn -f java initialize

To build with Ant, or to build an old branch not supporting Maven and using the old javax libraries:

# Retrieves dependencies through ivy 
ant -f manager-build.xml ivy

# Compiles and builds the branding jar
ant -f manager-build.xml refresh-branding-jar

# Compiles the main codebase
ant -f manager-build.xml compile

Clone this wiki locally