Search code examples
javagradlemodulestructure

Should Multi module Java projects have Multiple Gradle Project


I'm starting to get into java modularity and I am wondering if a multi-module project should be split into sub-Gradle projects. If this is or isn't the case, what would the directory structure look like? I've seen some conflicting examples of structures for non-Gradle projects such as:

reverse/dns/module/module-info.java 
                ./packages..
reverse/dns/module/module-info.java 
                ./packages..

and

reverse.dns.module/
            module-info.java // module-info is in the root directory and its name corresponds to parent folder
            reverse/dns/module/packages..

Would it look something like this?

Really I would just like to know how to structure a Gradle project if I were to have two modules. I intend to use jlink also to create images if that conflicts with anything.


Solution

  • I asked a variation of this question:

    I'm using gradle and the jlink plugin and have an application that I want to split into two modules, are the modules supposed to be under the src/main/java directory or should it be refactored to src/mod1/ and src/mod2? Another question that comes from this is testing and where to place junit test classes. I'm mostly wondering about the directory structure of all of this. Thanks!

    to Nick Maiorano and received this response:

    For your first question, the Java compiler and runtime have no opinion on this. They support either types of directory structures. But Java editors like Intellij and Eclipse kind of force you into having separate source roots for each module. If you plan on having different teams maintaining their own modules, then you'll have to have seperate roots and you would use their modules just like a 3rd party library with module dependencies through a jar or jmod file. Otherwise you could have different modules under a single source but you'd be fighting against Eclipse's/Intellij's module support (but it is possible).

    Your second question is much easier: unit test classes should be in the same module as their test subjects. They should have access to every class in the module so it makes sense that they be part of the module. They should be in a separate directory but the same package name as their test subjects (so that they're not blocked from accessing package private methods).

    This fits the way I decided to architect the application by having two separate Gradle sub-projects, each of them having their own src/main/java directory. My final directory structure looks like this:

    wit-core/
    ├── build.gradle
    ├── core.vim
    └── src
        ├── main
        │   └── java
        │       ├── dev
        │       │   └── joshpetit
        │       │       └── wit
        │       │           └── core
        │       │               ├── base
        │       │               ├── interpret
        │       │               └── model
        │       └── module-info.java
        └── test
            └── java
                └── dev
                    └── joshpetit
                        └── wit
                            └── core
                                ├── base
                                └── utils
    wit-gui/
    ├── build.gradle
    ├── Session.vim
    └── src
        ├── main
        │   └── java
        │       ├── dev
        │       │   └── joshpetit
        │       │       └── wit
        │       │           └── gui
        │       │               └── launcher
        │       └── module-info.java
        └── test
            └── java
                └── dev
                    └── joshpetit
                        └── wit
                            └── gui
                                └── launcer
    

    Lots of thanks to the people who parsed this question through with me!

    If anyone else is still wondering about this, I do recommend following @FranciscoMatea's advice and referencing junit's project structure.