I have an interesting concern. I am used to multi-module Maven projects. Now I am investigating how to do the same but also using Jigsaw. Am right that every single Maven Module can have only one Jigsaw module? In IDE I can't create the second one inside the same Maven module.
So, is there any convention or workaround so far how to combine both sides of modules?
When Project Jigsaw developed the Java Platform Module System it decided that a modular JAR is a regular JAR with a module descriptor, a module-info.class, in its root folder. That means a JAR can only define a single module. There have been request for multi-module JARs, but the feature was deferred to a future release.
That one-to-one relationship between JPMS modules and JARs taken together with Maven's one-to-one relationship between Maven modules and JARs leads to the fact that a Maven module can only contain a single JPMS module.
(I created a module system tutorial and a corresponding demo project that uses a multi-module Maven build to create modules - maybe they're helpful to you.)
Related
Let's say I have a maven project which has some maven modules inside.
My main module depends on the other modules, so when I compile the main module they should be compiled together.
The question is, how to add these modules as dependencies to the main module?
I know if I have a custom lib that I want to use with maven, let's say a utilities project, I have to compile the jar of the project, do a mvn install:install-file on it to install it on the local repository and then add it to the pom.xml.
Do I have to do this with all my modules and add the dependency to the pom.xml on my main module? Because if it should be done like this, there will be a lot of work to do when changing code on the other modules.
What is the best practice to use avoid the trouble of compiling/installing the modules to local repository?
The question is, how to add these modules as dependencies to the main module?
The same way you add any other dependency to your maven project. By adding group id, artifact id and version to <dependency> element
Do I have to do this with all my modules and add the dependency to the pom.xml on my main module?
If your main module depends on some module A then only the pom of the main module should contain dependency declaration towards module A. You do that for all the dependencies of your module.
I don't know what you mean by "a lot of work when changing the code on other modules". Maven has nothing to do with code changes, it just builds the projects whatever they look like at the given moment...
What is the best practice to use avoid the trouble of compiling/installing the modules to local repository?
Any project that you invoke mvn install on gets built and it's jar copied to local repository. That's all you need to do to get the jar into the repo. This will also put all the dependent jars, if available, into the local repo.
As for best practices for multi module projects:
If your parent project (the one that has modules inside) has <modules> section that lists the modules of your application, and modules are in subdirectories of your parent project, then you simply mvn install (or whatever you want to do) the parent project and that will cause all the modules to be built in order defined by declared dependencies between them. That means that if your main module has dependency on module A, then module A will be built before the main module. This way you can build and install all your modules with one command. On the other hand this approach makes more tight coupling between modules which is not desired in some cases, so it depends on your use case whether it is a good approach or not.
I'm developing library with Maven system, which is published in the Nexus repository.
In the nexus (and the maven build as well), the project produces the final jar named <projectName>-<version>.jar - this is exactly what I want.
Now, I decided to split the library into maven modules and therefore top level pom.xml have <packaging>pom</packaging>. The build also do not produce final <projectName>-<version>.jar, instead it produces <moduleName>-<version>.jar for each module.
What I want to achieve is to have the project split into modules and be able to produce final <projectName>-<version>.jar containing defined modules. Is this possible?
Is it possible to solve this issue migrating to the Gradle?
When you decided to split the library into multi modules it means that you decided to build them independently. So it's expected that each module creates it's own <moduleName>-<version>.jar.
Now when you use the created modules as dependencies for the bigger module with scope of compile maven would automatically add them to lib of the project.
So in your case you don't need to change packaging to pom and just add the modules as dependency in the pom.xml file and let maven to create the final jar for you.
Also if you want use pom packaging there is a good question here which might help you.
I've seen projects where one single project divided into modules, and each module is maven project itself. These modules integrated through one module which contains references to all other modules. To launch project user must import all modules in IDE. So, why people using this approach? Isn't much easier to package all modules to jar and include as dependencies to some module? Is there any benefit to use projects instead jars? Drawbacks of using projects are: user needs to keep all modules in IDE, may accidentally change source code, and if IDE starts to compile all that modules it takes a lot of time.
If you accidentally change one file, only this file gets recompiled, that's not a big deal.
Usually, you need to modularize your project to cut interdependencies and make everything more controllable. Often, the parent project doesn't even have any source files of its own; instead, it is only used to aggregate the modules. Modules are just used here to separate a big project into pieces.
You could develop those pieces as separate projects, but to implement a change in one module and make it available for other modules that use it, you'd have to build that module and actualize a dependency in the client module. That's cumbersome. It's much more practical to keep them as one big project where you just change the code you need to change, and it's available to all the modules that depend on it.
My project depends on an external library, which consists of a number of maven projects.
Do I have to define each of the projects in the library to be a module in my project's parent pom.xml? Is there a way to define the library as a whole in my project without individually listing all the projects?
My project directly depends on only one project in the library, but that project depends on other projects in the library.
Do I need to define all the projects in the library in my project's dependencies?
Ideally, in parent pom you define modules i.e, external libraries which you want to build. When you build the parent pom, it will build all modules which are defined in parent pom. And further, modules will build other dependencies/modules.
You need a composite pom -- a pom which just declares a bunch of dependencies. You depend on it, and transitively, you get its dependencies.
See this discussion for more information.
I have a collection of 3 existing Eclipse projects that I want to make into Maven projects and I'm having a hard time understanding the relationship between the GroupID, ArtifactID and my Java Packaging, and the different directory structure that is created for Maven vs. Java projects. I'm pretty new to J2EE and completely new to Maven, so any advice is welcome! Let me describe my projects first.
The first project is IDMU_JAR. The base Java packaging is com.foo.util.merge and it contains Java classes like Template and Bookmark and the target jar file is com.foo.util.merge.jar
The second project is IDUM_WAR. The base class in this project is com.foo.util.merge.web and it references the IDMU_JAR project and contains only a few Servlets that expose the functionality in IDMU_JAR.
The third project is IDMU_EAR. Currently this is just a device for creating a deployment EAR that contains IDMU_JAR, WAR and it's dependencies.
My questions are:
Is my J2EE packaging and naming "typical" or have I already gone against best practices?
Am I better off creating the Maven Project and then converting it to a Faceted project and picking the facets, or should I be creating the Java Utility/WAR/EAR projects and then converting them to Maven projects?
This appears to have a big impact on the directory structure of the project, is this important?.
Does my Eclipse Project name have to match the Maven Artifact ID?
You can configure pretty much anything in maven from file structure to project special configuration. But If it's not absolutly necessery you should stick with maven defaults.
You can start with that project template:
javaee-essentials-pom
For the project namings:
GroupID: com.foo
ArtifactID: idmu-utils, idmu-war, idmu-ear
package: jar, war, ear
With Eclipse:
Start by using the template I provided. Importing as maven project from Eclipse should resolve all facets available automatically.