Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: maven rockcraft plugin #728

Draft
wants to merge 30 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
13f71d5
feat: maven rockcraft plugin
vpa1977 Oct 8, 2024
c76815f
test: only copy modules file
vpa1977 Oct 9, 2024
810587a
chore: fix comment in the test
vpa1977 Oct 9, 2024
7e864d5
chore: fix copyright year for maven plugin
vpa1977 Oct 9, 2024
9a65ae9
Merge branch 'main' into fix_maven
vpa1977 Oct 9, 2024
81b02fe
test: remove maven download spam
vpa1977 Oct 9, 2024
4aaa3e4
test: log actual vs expected content
vpa1977 Oct 9, 2024
19a5494
Merge branch 'fix_maven' of github.com:vpa1977/rockcraft into fix_maven
vpa1977 Oct 9, 2024
30d1320
test: use insecure-policy in copy args
vpa1977 Oct 10, 2024
a865428
test: drop startup server from the test
vpa1977 Oct 10, 2024
26440ec
doc: add rockcraft-specific maven docs
vpa1977 Oct 13, 2024
d47db08
lint(maven_plugin.rst): reformat file
vpa1977 Oct 13, 2024
84de8ae
test(plugin-maven): expand test comment
vpa1977 Oct 13, 2024
a732138
doc(maven-plugin): update labels and links
vpa1977 Oct 13, 2024
4014687
Merge branch 'main' into fix_maven
vpa1977 Oct 13, 2024
9c3985f
Merge branch 'main' into fix_maven
vpa1977 Oct 15, 2024
5224edf
Merge branch 'main' into fix_maven
vpa1977 Oct 17, 2024
bdaec03
fix: drop unused sitecustomize
vpa1977 Oct 21, 2024
b68dce7
Update tests/spread/rockcraft/plugin-maven/rockcraft.yaml
vpa1977 Oct 21, 2024
5d745ea
fix: put /usr/bin in front
vpa1977 Oct 22, 2024
940315a
test: fix override stage-> build
vpa1977 Oct 22, 2024
53d2e6a
Update tests/spread/rockcraft/plugin-maven/task.yaml
vpa1977 Oct 23, 2024
bb08f27
Update tests/spread/rockcraft/plugin-maven/task.yaml
vpa1977 Oct 23, 2024
cff2516
Merge branch 'main' into fix_maven
vpa1977 Oct 23, 2024
d326747
Revert "Update tests/spread/rockcraft/plugin-maven/task.yaml"
vpa1977 Oct 23, 2024
5bc22b6
lint: apply black
vpa1977 Oct 23, 2024
ea6196c
Merge branch 'main' into fix_maven
vpa1977 Nov 6, 2024
fae4383
fix: only drop /bin/java symlink
vpa1977 Nov 6, 2024
11550b9
Merge branch 'fix_maven' of github.com:vpa1977/rockcraft into fix_maven
vpa1977 Nov 6, 2024
b0b319b
Merge branch 'main' into fix_maven
vpa1977 Nov 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/reference/plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Rockcraft.
/common/craft-parts/reference/plugins/dump_plugin
/common/craft-parts/reference/plugins/go_plugin
/common/craft-parts/reference/plugins/make_plugin
/common/craft-parts/reference/plugins/maven_plugin
plugins/maven_plugin
/common/craft-parts/reference/plugins/meson_plugin
/common/craft-parts/reference/plugins/nil_plugin
/common/craft-parts/reference/plugins/npm_plugin
Expand Down
56 changes: 56 additions & 0 deletions docs/reference/plugins/maven_plugin.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
.. _rockcraft_maven_plugin:

Maven plugin
============

The Maven plugin builds Java projects using the Maven build tool.

After a successful build, this plugin will:

* Create ``jar/`` directory in ``$CRAFT_PART_INSTALL``.
* Hard link the ``.jar`` files generated in ``$CRAFT_PART_BUILD`` to
``$CRAFT_PART_INSTALL/jar``.


Keywords
--------

In addition to the common :ref:`plugin <part-properties-plugin>` and
:ref:`sources <part-properties-sources>` keywords, this plugin
provides the following plugin-specific keywords:

maven-parameters
~~~~~~~~~~~~~~~~
**Type:** list of strings

Used to add additional parameters to the ``mvn package`` command line.


Environment variables
---------------------

This plugin reads the ``http_proxy`` and ``https_proxy`` variables
from the environment to configure Maven proxy access. A comma-separated
list of hosts that should not be accessed via proxy is read from the
```no_proxy`` environment variable.

Please refer to `Configuring Apache Maven
<https://maven.apache.org/configure.html>`_ for a list of
environment variables used to configure Maven.


.. _rockcraft_maven-details-begin:

Dependencies
------------

The plugin expects Maven to be available on the system as the ``mvn``
executable.

Note that the Maven plugin does not make a Java runtime available in
the target environment. This must be handled by the developer when
defining the part, according to each application's runtime requirements.

.. _rockcraft_maven-details-end:

.. _`mvn`:
76 changes: 76 additions & 0 deletions rockcraft/plugins/maven_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright 2024 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""The Rockcraft Maven plugin."""
import logging
from textwrap import dedent

from craft_parts.plugins import maven_plugin
from overrides import override # type: ignore[reportUnknownVariableType]

logger = logging.getLogger(__name__)

# Template for the sitecustomize module that we'll add to the payload so that
vpa1977 marked this conversation as resolved.
Show resolved Hide resolved
# the pip-installed packages are found regardless of how the interpreter is
# called.
SITECUSTOMIZE_TEMPLATE = dedent(
"""
# sitecustomize added by Rockcraft.
import site
import sys

major, minor = sys.version_info.major, sys.version_info.minor
site_dir = f"/lib/python{major}.{minor}/site-packages"
dist_dir = "/usr/lib/python3/dist-packages"

# Add the directory that contains the venv-installed packages.
site.addsitedir(site_dir)

if dist_dir in sys.path:
# Make sure that this site-packages dir comes *before* the base-provided
# dist-packages dir in sys.path.
path = sys.path
site_index = path.index(site_dir)
dist_index = path.index(dist_dir)

if dist_index < site_index:
path[dist_index], path[site_index] = path[site_index], path[dist_index]

EOF
"""
).strip()


class MavenPlugin(maven_plugin.MavenPlugin):
"""A MavenPlugin plugin for Rockcraft.

This plugin extends Craft-parts' vanilla Maven plugin to properly
use and install the Java VM. Specifically:

- Do not link java executable to /bin/java
vpa1977 marked this conversation as resolved.
Show resolved Hide resolved
- Do not include staging area in the PATH
"""

@override
def _get_java_link_commands(self) -> list[str]:
"""Get the bash commands to provide /bin/java symlink."""
return []

@override
def get_build_environment(self) -> dict[str, str]:
env = super().get_build_environment()
env["PATH"] = "/usr/bin"
vpa1977 marked this conversation as resolved.
Show resolved Hide resolved
return env
3 changes: 2 additions & 1 deletion rockcraft/plugins/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import craft_parts
from craft_parts.plugins.plugins import PluginType

from .maven_plugin import MavenPlugin
from .poetry_plugin import PoetryPlugin
from .python_plugin import PythonPlugin

Expand All @@ -30,4 +31,4 @@ def register() -> None:

def get_plugins() -> dict[str, PluginType]:
"""Get a dict of Rockcraft-specific plugins."""
return {"poetry": PoetryPlugin, "python": PythonPlugin}
return {"poetry": PoetryPlugin, "python": PythonPlugin, "maven": MavenPlugin}
32 changes: 32 additions & 0 deletions tests/spread/rockcraft/plugin-maven/rockcraft.yaml
vpa1977 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: plugin-maven
vpa1977 marked this conversation as resolved.
Show resolved Hide resolved
base: bare
build-base: [email protected]

version: '0.1'
summary: A rock that bundles a Maven project.
description: A rock that bundles a Python project.
vpa1977 marked this conversation as resolved.
Show resolved Hide resolved
license: GPL-3.0
platforms:
amd64:

parts:
maven-sample:
plugin: maven
source: sample
maven-parameters: [ "-B" ]
stage-packages:
- openjdk-21-jre-headless_core
- base-files_base
build-packages:
- maven
- openjdk-21-jdk-headless
# replace chiselled image modules with jlink output
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you explain to me how this override-build is "replacing" the chiseled content with the jlink output? Wouldn't the cp command just "add" the jlink files to the existing files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notice:

    stage-packages:
     - openjdk-21-jre-headless_core

This adds ${CRAFT_PART_INSTALL}/usr/lib/jvm/java-21-openjdk-${CRAFT_ARCH_BUILD_FOR} as far as I understand.
cp out/lib/modules ${CRAFT_PART_INSTALL}/usr/lib/jvm/java-21-openjdk-${CRAFT_ARCH_BUILD_FOR}/lib
replaces the module file with the one generated by jlink.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah I see, yes you're right

❯ ls -lah root/usr/lib/jvm/java-21-openjdk-amd64/lib/
total 135M
drwxr-xr-x 3 tiago tiago 4,0K nov 14 08:51 .
drwxr-xr-x 5 tiago tiago 4,0K nov 14 08:51 ..
-rwxr-xr-x 1 tiago tiago  15K nov 14 08:51 jexec
-rwxr-xr-x 1 tiago tiago  19K nov 14 08:51 jspawnhelper
lrwxrwxrwx 1 tiago tiago   34 nov 14 08:51 jvm.cfg -> /etc/java-21-openjdk/jvm-amd64.cfg
-rw-r--r-- 1 tiago tiago  17K nov 14 08:51 libextnet.so
-rw-r--r-- 1 tiago tiago 178K nov 14 08:51 libjava.so
-rw-r--r-- 1 tiago tiago  39K nov 14 08:51 libjimage.so
-rw-r--r-- 1 tiago tiago  77K nov 14 08:51 libjli.so
-rw-r--r-- 1 tiago tiago  17K nov 14 08:51 libjsig.so
-rw-r--r-- 1 tiago tiago  65K nov 14 08:51 libnet.so
-rw-r--r-- 1 tiago tiago 108K nov 14 08:51 libnio.so
-rw-r--r-- 1 tiago tiago  63K nov 14 08:51 libverify.so
-rw-r--r-- 1 tiago tiago  45K nov 14 08:51 libzip.so
-rw-r--r-- 1 tiago tiago 135M nov 14 08:51 modules
drwxr-xr-x 2 tiago tiago 4,0K nov 14 08:51 server
-rw-r--r-- 1 tiago tiago 102K nov 14 08:51 tzdb.dat

# in order to ensure that only java.base module is present in
# runtime
override-stage: |
vpa1977 marked this conversation as resolved.
Show resolved Hide resolved
craftctl default
rm -rf out
jlink --no-header-files --no-man-pages --strip-debug \
--add-modules java.base \
--output out
cp out/lib/modules ${CRAFT_STAGE}/usr/lib/jvm/java-21-openjdk-${CRAFT_ARCH_BUILD_FOR}/lib
30 changes: 30 additions & 0 deletions tests/spread/rockcraft/plugin-maven/sample/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sample</name>
<properties>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>8</maven.compiler.source>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<manifest>
<mainClass>test.Test</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package test;

public class Test {
public static void main(String[] args) {
System.out.println("hello world");
}
}
23 changes: 23 additions & 0 deletions tests/spread/rockcraft/plugin-maven/task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
summary: Maven plugin tests
execute: |
SCENARIO="plugin-maven"
ROCK_FILE="${SCENARIO}_0.1_amd64.rock"
IMAGE="${SCENARIO}:0.1"

# Build the rock & load it into docker
run_rockcraft pack
ls
echo expecting ${ROCK_FILE}
test -f ${ROCK_FILE}
rockcraft.skopeo copy --insecure-policy oci-archive:${ROCK_FILE} docker-daemon:${IMAGE}
docker images
rm ${ROCK_FILE}

# Run the packaged project
docker run --rm $IMAGE exec /usr/lib/jvm/java-21-openjdk-amd64/bin/java -jar /jar/sample-0.0.1-SNAPSHOT.jar | MATCH "hello world"
vpa1977 marked this conversation as resolved.
Show resolved Hide resolved

docker system prune -a -f

# Rebuild the java project
vpa1977 marked this conversation as resolved.
Show resolved Hide resolved
touch sample/src/main/java/test/Test.java
rockcraft pack
Loading