Index | Thread | Search

From:
Ian Darwin <ian@darwinsys.com>
Subject:
Ports support for building Java progs with Maven, Take II(b) ("portgen for Java")
To:
ports <ports@openbsd.org>
Date:
Thu, 17 Sep 2026 16:56:35 -0600

Download raw body.

Thread
This is a parallel to portgen, specifically for Java. It's designed to 
build (the skeleton of) a port that will build and install a Java app 
that is built from source using Maven.

I worked on this several hackathons ago, but never got it finished. This 
week I rewrote and worked on it to be more robust (the previous version 
tried to parse the output of `mvn dependency:list`; the current tells 
Maven to `go-offline` which makes it download all the deps, and uses 
that to generate a list to download in the Makefile).

I'm sending it at this stage to see if anybody thinks it's a good or bad 
approach, or has any suggestions on the non-obvious work still to be 
done (the Makefile template is obviously not ready for prime time).

One thing I'm a bit stuck on is the "system dependencies" - when given 
the temporary <localRepository>, Maven will download about 80 MB of its 
own Jar files in addition to the deps for the target program. I could 
save those in /usr/local someplace (I *think* they only change when 
Maven version is updated; this would be a separate rdep port (named like 
"maven-system-deps"?)). If we could fix this, portgen_java's run of 
Maven would only download jar files that are needed specifically for the 
app. I think this complication can be left for later - the download is 
"only" about 80MB and only a small number of ports are predicted to use 
it before we get to this issue.

The port to install portgen_java is attached as tar.gz. You can look at 
the code of the program at 
https://github.com/IanDarwin/portgen_java (pull requests welcome if you 
use that and feel ambitious; otherwise comments or diffs also welcome).

Thanks for looking.

----- portgen_java README -----

= portgen_java

A simple Java program to generate an OpenBSD port to build a package 
from a Java
program that has a pom file but doesn't offer precompiled packages or 
for which
those are not trusted by the porter.

This it cannot go into base because it depends on a Java port (e.g., 
jdk-25) being installed.

== Usage

     portgen_java [-f][-d][-v][-k] source-dir

The given `source-dir` must be a project that has a pom file, and should 
have an
`assembly:single` task to build a finished jar.

Options:

* -d - debugging output
* -f - force removal of the generated port directory before starting
* -k - keep the temporary local repostiroy (it is by default deleted at 
the end)
* -v - verbose - information less detailed than the debugging output.

== What it does

Checks for, and reads, the pom file in the target directory. Extracts 
the name and version.

Runs maven with some options to make it download all the dependencies 
into a new temporary dir.
Gets the list of required files from the temporary dir.

Plugs the name and version into a minimal `Makefile`, along with the 
list of deps as `DISTFILES1`,
and saves the Makefile under `/usr/ports/mystuff/java/NAME/Makefile`, 
where `NAME` is
the name element at the top of the `pom` file.

== What it does not do

Due to the huge variability of Java programs,
the generated `Makefile` will need considerable editing.

This program doesn't yet generate (but these are trivial):

* for programs, a run script in /usr/local/bin and a desktop file for 
GUI start;
* for services, an `/etc/rc.d` file.

== Future Work

=== Work around limitations ("bugs") in Maven itself

The familiar `mvn` command is just a skeleton. Running it on an trivial 
"Hello World" java
demo project downloads about 80MB of "standard" dependencies plus any 
that are needed by the app.

Maven further does not distinguish between a user and system "local"
directories, so there's no way to just package these standard deps
separately from the app-specific ones and have Maven find them.
However, if there were a separate port/package of these deps, a future
version of this program could just cp -r that into the temp folder.

I tried to work around this using the `<repository>` elements in a 
`<profile>` in `settings.xml`,
but these seem to be only used for resolving from, not saving into, 
unlike `<localRepository>`,
of which you can have only one (in the XML schema). That experiment is 
in the file
`settings-global.xml`.

=== Base Portgen is written in Perl

Perl can call Java, using `Inline::Java` - if we had that in base, this 
could be
called directly from the existing portgen.

Alternately, if somebody wants to manually (not using AI) translate this 
into Perl,
it could be added as a module into the standard perl-based `portgen` in 
base.
But then you get to take over as maintainer!

----- End of README -----