Tuesday, February 25, 2020

Maven multi-module project in IntelliJ IDEA - several ways to try when stuck with an issue . . .

"Nobody uses Maven, Maven uses you." - Venkat Subramaniyam

I heard at least few times Venkat saying that in his presentations on various topics in Conferences and at Java User Group meetups. I used to laugh with many when he would to say that after asking "Who uses Maven here?". I was happy NOT to be one to raise a hand for that question. I have been using Gradle for a longtime. Now, if I attend any of his sessions and happen to hear that question again, I will be one of those to raise a hand. "Welcome back!", Maven said and started using me ;(

I worked with Gradle-based projects and imported into IntelliJ, numerous times. I even brought multiple Gralde projects into multi-project Gradle builds under one project with proper project inter-dependencies. But I never had to break my head with issues for hours.

Environment: Java 13.01, Spring Boot 2.2.4.RELEASE, Maven 3.6.2, IntelliJ IDEA ULTIMATE 2019.3 on macOS High Sierra 10.13.6

The issue I ran into lately with a maven multi-module project

I recently had to start a new module in a multi-module maven project. The new module was a fairly simple Java application (executable jar) with just spring-boot-starter-batch dependency to start with and some other related dependencies as well. Suddenly, IntelliJ was unhappy by all means with the newly added module in dealing with dependencies and adding dependent libraries to the classpath for compilation. The module was just fine running maven tasks like compile, install, package etc. from the command line. I was even able to run the app from the executable jar created.

I literally ran out of all options dealing with this issue in IntelliJ. Several people seem to have faced similar issue and there was no consistent solution that worked for all. Some of the solutions that worked for some but not for all are:
  1) Invalidating caches and restarting IntelliJ (an option found under File menu item, beware that IntelliJ takes a while after restart to index depending on the size of all your projects imported into IntelliJ)
  2) Deleting the project from the initial welcome pane and importing again
  3) Deleting the project from the initial welcome pane, but instead of importing, opening it and going through steps.
  4) Clearing local maven cache all the way etc.

None of the above options worked for me. Phrases like: "That worked for me",  "This worked yesterday, doesn't work anymore." are quite commonly heard. This is a common pattern in Software Development. I call it a head-breaking pattern ;)

Insights of Maven multi-module project in IntelliJ

A multi-module maven project contains a root pom.xml with module specific pom.xml files. Easiest way is to import a maven project into IntelliJ IDEA is from the welcome pane. Click on Import Project and select the root pom.xml. If everything goes well, IntelliJ imports the project resolves each module's dependencies, compiles code and reports errors or issues. During this process it creates <module-name>.iml files under every module including the root project (the module-name is taken from the corresponding module's name property specified in it's pom.xml). If open any of these .iml XML files created, they contain dependency details with <orderEntry type="library" name="Maven: ..."/>. Also, from the dependencies, IntelliJ detects frameworks needed and sets up proper facets like Spring, JPA, Web etc. in getting all needed tool support for the module.

When stuck with an issue, there are many ways to add, delete, import specific module into IntelliJ IDEA

When there are issues with any specific module, that particular module can be deleted and added/imported again by few different ways in IntelliJ.

1) From the Project Tool Window (Did not not solve my iisue)

Right click the module and select Remove Module as shown below:



and import the removed module by adding the module to the project again as shown below:


2) From Project Settings - New Module (Did not not solve my issue)

Press Cmd + ; (⌘;) or go to File > Project Structure and delete module as shown below:


and add the module again by clicking + on the top. A window with two options pops up as shown below:



select New Module, then select Maven and go through steps from New Module Pane on the left as shown below:


Make sure Module SDK looks good, Next > Select Parent from the drop-down, enter same module name for Name: , and notice that the Location: gets updated with name as entered.

3) From Project Settings - Import Module (This solved my issue)

Press Cmd + ; (⌘;) or go to File > Project Structure and delete module as shown below:


and add the module again by clicking + on the top. A window with two options pops up as shown below:



select Import Module instead of the New Module. Select module's pom.xml, from the finder window opened and click open. Then, make sure correct directories of your module are marked for Mark as:  Sources (main/java), Tests(test/java), Resources(main/resources), Test Resources (if any) and click OK.

This properly updates IntelliJ's classpath in module's *.iml file that gets created and found under your module's root folder. Once imported, IntelliJ also recognizes frameworks appropriately from the dependencies. In my case it was just Spring framework/facet. When you right click on the module in your project structure pane, and mouseover the +Add option, you will see the list of frameworks/facets available as shown below:



Summary

We are living in times where a solution to an issue is just a google-search away. But sometimes, something that worked for others won't work for you. This is one such issue with which I was almost about to bang my head against the wall. After tirelessly exploring possible ways of deleting and creating modules, I finally found the option that worked for me consistently.

Software Development is not easy and will never become easy. This is a hard fact ;)


No comments:

Post a Comment