create custom sourcecode set and add it to the compilation and packaging

My overarching goal: learn gradle (best practices) while bending it in strange ways.

Background: I haven’t used java in over 5 years, but I was profficient in it; I haven’t used gradle professionally, nor kotlin (but I have groovy in the past year).


So I’m trying to get a specific directory layout to work, which is non-negociable for my goal, also non-negociable: using module-info.

The sample project: GitHub - flavius/skillmatrix-java: Hexagonal architecture and java best practices workshop

The sourcecode set is created, but I have trouble integrating it into the rest of the process (compile/build). I can see this with

./gradlew printSourceSetInformation

but this doesn’t work:

./gradlew build

debugged via

unzip -l skillmatrixapp/build/libs/skillmatrixapp.jar
Archive:  skillmatrixapp/build/libs/skillmatrixapp.jar
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2023-12-08 16:25   META-INF/
       25  2023-12-08 16:25   META-INF/MANIFEST.MF
---------                     -------
       25                     2 files

It’s not clear from your sample project if you really have a need for an additional domain source set. If you just care about the directory layout being src/domain/java for the project’s main sources, it makes more sense to just change that.

sourceSets {
    main {
        java {
            setSrcDirs(listOf("src/domain/java"))
        }
    }
}

If you need to keep the main source set and add domain source set, and want both in the JAR file, then you just need to add that source set output to the JAR, which can be done with

tasks.named<Jar>("jar") {
   from(sourceSets.get("domain").output)
}

Thanks, I managed to add two modules in the same jar as well by using the copySpec, so starting to get an intuition for the docs.

However, I’m struggling now with getting gradlew run to run the main cli class as an entry point.

Tried variations of this https://github.com/flavius/skillmatrix-java/blob/master/skillmatrixapp/build.gradle.kts#L57

Ideas?

The output

> Task :skillmatrixapp:run FAILED
Error occurred during initialization of boot layer
java.lang.module.FindException: Module skillmatrix.cli not found

But the modules are named differently than the directories.

The jar looks like this


Archive:  skillmatrixapp/build/libs/skillmatrixapp.jar
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2023-12-12 11:10   META-INF/
       25  2023-12-12 11:10   META-INF/MANIFEST.MF
        0  2023-12-12 11:10   domain/
      215  2023-12-12 11:10   domain/module-info.class
        0  2023-12-12 11:10   domain/com/
        0  2023-12-12 11:10   domain/com/flaviusas/
        0  2023-12-12 11:10   domain/com/flaviusas/skillmatrix/
        0  2023-12-12 11:10   domain/com/flaviusas/skillmatrix/domain/
        0  2023-12-12 11:10   domain/com/flaviusas/skillmatrix/domain/usecases/
      324  2023-12-12 11:10   domain/com/flaviusas/skillmatrix/domain/usecases/Hello.class
        0  2023-12-12 11:10   cli/
      159  2023-12-12 11:10   cli/module-info.class
        0  2023-12-12 11:10   cli/com/
        0  2023-12-12 11:10   cli/com/flaviusas/
        0  2023-12-12 11:10   cli/com/flaviusas/skillmatrix/
        0  2023-12-12 11:10   cli/com/flaviusas/skillmatrix/ui/
        0  2023-12-12 11:10   cli/com/flaviusas/skillmatrix/ui/cli/
      575  2023-12-12 11:10   cli/com/flaviusas/skillmatrix/ui/cli/Main.class
---------                     -------
     1298                     18 files

You cannot have multiple JPMS modules within one jar, thats afaik nothing Java supports. The module-info.class of a module must be in the root of the jar of that module, so Java does not find your modules when you try to run.

Right, thanks for pointing it out. Are there any alternative solutions?

I was researching around the lines of “still one jar, but upon executing, specifying explicitly multiple module paths into a jar”.

Or maybe a custom module loader? Apparently it involves a ModuleFinder class.

Actually, I don’t know, never tried that.
But why do you actually want to do that?
What is your use-case / what do you want to achieve?

I got quite close, there is one thing I need and this really is a task for gradle.

I need the file META-INF/MANIFEST.MF inside each top-level directory (which is a java module).

For example, this should be produced: skillmatrix.jar/domain/META-INF/MANIFEST.MF

The current code got some updates: GitHub - flavius/skillmatrix-java: Hexagonal architecture and java best practices workshop