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