Hi Kaibo,

I'd like to suggest an alternative to using a local Maven repository for
making Portage-built artifacts available to Maven builds.

Maven also makes it possible to use a "Maven extension" for providing
artifacts that do not come from a remote Maven repository. If a Maven
extension provides an implementation of a "WorkspaceReader", Maven will
query that implementation for artifacts before checking any repository
for the artifacts. (An example of such an extension is used by
M2Eclipse, the Maven integration for the Eclipse IDE, which provides
artifacts built from Java projects within Eclipse.)

Using such a Maven extension would provide greater flexibility than a
local Maven repository, because ebuilds could modify artifact resolution
for their Maven builds by configuring the extension. (I believe that
this would be trickier when using a local Maven repository, in
particular with multiple ebuilds running in parallel.)

I don't know what a similar mechanism in Gradle would be, but I'd guess
that Gradle provides similar extension points.

When thinking about Java builds within portage some weeks ago, I
actually wrote a very simple such extension, to see if this approach
actually works (see
https://github.com/hsudbrock/portage-maven-workspace-reader), and it did
work fine. (This extension resolves artifacts that were "registered" by
other ebuilds by putting a file in a specific directory, where the file
contains the location of the artifact on the hard disk - but this is
just a very simple "proof of concept".)

What do you think about this alternative idea?

Best wishes,
Henning

On 15.03.21 14:02, Kaibo Ma wrote:
Hi all,
This is an RFC copied from a bug (https://bugs.gentoo.org/776007
<https://bugs.gentoo.org/776007>), and I have added a new section
because I realized maven local would not be a good destination for
system-wide packages.

-----

0. Motivation

Java packaging has become more difficult on Gentoo because maven/Gradle,
the two main build systems for java, is unsupported. When java packages
migrated from their ant builds to maven/Gradle, most of the packages
have not been updated since. I know that in Java overlay, the packaging
practices in general is to patch the pom.xml files to work with local
jars, but it does not work with Gradle and can be difficult when working
with large projects.

1. Challenges

  - maven modules/artifacts do not work well with java-config. They
generally have a group, which resolves name collisions, but java-config
currently does not have a group variable.

  - it will be hard to reinvent the wheel. If the solution was to
rewrite pom.xml/build.gradle files, it would have to resolve the
dependencies correctly with all the version constraints instead of
relying on the build system. Currently, for java-config packages can
only depend on a specific slot of a library, but some might work with
newer versions of their dependencies.

  - plugins are also hard to create in Gradle. Custom resolution of
dependencies or specifying a custom repository is not easy because it
involves "internal" API without much documentation. Fedora's XMvn
project can be used as a starting point but at the time of writing, XMvn
is outdated and missing some implementations for newly added interface
methods in Gradle's API.

2. Proposed idea

Maven/Gradle both have an offline mode which restricts them from
fetching online files. For java libraries, they will be published to the
local maven repository, which makes it available for other java programs
using maven/gradle that depends on the library.

Packages that still use java-pkg-simple.eclass can be kept because they
are generally not available in maven, so it is rare for other packages
to depend on them. The eclass and java-config should be updated for some
packages that depend on other packages that get published to mavenLocal,
but this seems like a rare case. Those packages can also just get
converted to a maven/project using patches.

For applications, the launcher scripts should also be changed to parse
local artifacts with POM files.
If this were to be implemented, newer (revisions/subslots? Or old slots
with -new at the end?) packages would be incompatible with older
versions of packages.

3. ERRATA

The local maven repository would not be a good fit since it is on a
per-user basis (~/.m2). The correct way would be to define a path for
installing (such as /usr/share/.m2), and pass that to build tools as a
URL (file:///usr/share/.m2).

Feel free to reply if you have any questions or improvements.
Kaibo Ma

Reply via email to