mvn exec works, but Run 'Application' does not - maven

I have a simple maven project using Micronaut. I'm trying to create a new module and make the typical 'WelcomeController', and communicate that module with the parent pom.
I can run it command-line via mvn exec:exec but running it with the IDE (IntelliJ IDEA) doesn't work for me. I got the following error:
Error: Could not find or load main class com.example.Application
Caused by: java.lang.ClassNotFoundException: com.example.Application
Child pom:
<parent>
<groupId>com.example.reports</groupId>
<artifactId>tnt-assignment-back</artifactId>
<version>0.1</version>
</parent>
<artifactId>tnt-rest</artifactId>
<description>Rest module for tnt-assignment</description>
<properties>
<exec.mainClass>com.example.reports.Application</exec.mainClass>
</properties>
Parent pom:
<parent>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-parent</artifactId>
<version>2.2.1</version>
</parent>
<groupId>com.example.reports</groupId>
<artifactId>tnt-assignment-back</artifactId>
<version>0.1</version>
<packaging>pom</packaging>
<modules>
<module>tnt-rest</module>
</modules>
Any ideas? I've tried many things but still don't go. Thanks.

It looks like you are trying to run com.example.Application from the IDE and maven is configured to run com.example.reports.Application.

Related

Is it possible to specify multiple main class in pom file?

I am using Spring-boot to develop an application. The reason I need to specify multiple main classes is that, my program runs as a 'tool'. By starting with different main classes, I can finish tasks. I currently specify one main class in this way:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>com.lu.qe.ClassificationService</mainClass>
</configuration>
</plugin>
Then I can start my application by running at a terminal:
mvn spring-boot:run
This only runs the "ClassificationService" main class. I also want to be able to possibly run another main class, like "ClassificationService_2". In such a case, how to achieve this? Is it possible to let 'mvn spring-boot:run' take a parameter?
From command line argument main class can be pass but it will fail to run because multiple main class will be found..
mvn spring-boot:run -Dloader.main=DemoApplication
But I think you can manage it by defining multiple profiles and then in command line you can pass profile argument..not checked but should work.
<profiles>
<profile>
<id>profile1</id>
<properties>
<spring.boot.mainclass>com.MainClass1</spring.boot.mainclass>
</properties>
</profile>
<profile>
<id>profile2</id>
<properties>
<spring.boot.mainclass>com.MainClass2</spring.boot.mainclass>
</properties>
</profile>
</profiles>
I'm also developing a 'tool' that requires multiple main classes. springboot does not support this demand but I found maven parent pom feature exactly satisfy my requirement.
step 1 - to change a pom.xml to a parent pom, change the packaging type to 'pom', a parent pom looks like this:
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
step 2 - create another pom file let's say service1.xml, and set this, pay attention to the relativePath element:
<parent>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>./pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>service1</artifactId>
<version>0.0.1-SNAPSHOT</version>
step3 - then you can specify the pom file when run a mvn command
mvn -f service1.xml spring-boot:run
mvn -f service1.xml clean package

Maven Multi Module Project looking for modules in repository instead of Building them

I have a multi-module MVN project, which has 1 aggregator pom, another parent pom, and 3 other modules, as follows:
project-all
-project-parent
-project-common
-project-maintainance
-project-webApp
project-WebApp has a dependency on project-common and project-maintenance.
When I run a clean install on project-all, it tries to download the modules from repositories instead of building them.
My understanding of a multi-module project is that it runs an install on all the modules as well, but that is not what is happening.
If I run a clean install on all the modules separately, the project-all clean install works fine. It also works when I run the mvn build in Eclipse with the Resolve Workspace Artifacts option selected.
However, both of these options are not viable options, since the idea of using a multi-module project is to run multiple poms from a single location.
Am I missing something, what would be the process of asking mvn to build those modules instead of looking for them in the repository.
Pom for project-all:
<?xml version="1.0" encoding="UTF-8"?>
<groupId>com.midtier.api</groupId>
<artifactId>project-all</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<name>project-all</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<modules>
<module>project-parent</module>
<module>project-data</module>
<module>project-maintenance</module>
<module>project-WebApp</module>
</modules>
POM for project-parent:
<?xml version="1.0" encoding="UTF-8"?>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<groupId>com.midtier.api</groupId>
<artifactId>project-parent</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<name>${project.artifactId}</name>
<description>${project.artifactId}</description>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<elasticsearch.version>6.2.4</elasticsearch.version>
<jsonsimple.version>1.1.1</jsonsimple.version>
<slf4j-version>1.7.25</slf4j-version>
</properties>
<dependencyManagement>
<!--Dependencies Here-->
</dependencyManagement>
Pom for project-Webapp:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<parent>
<groupId>com.midtier.api</groupId>
<artifactId>project-parent</artifactId>
<version>1.0</version>
</parent>
<groupId>com.rbc.midtier.api</groupId>
<artifactId>project-webapp</artifactId>
<packaging>jar</packaging>
<version>${project.parent.version}</version>
<name>${project.artifactId}</name>
<description>${project.artifactId}</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.midtier.api</groupId>
<artifactId>project-data</artifactId>
</dependency>
<dependency>
<groupId>com.midtier.api</groupId>
<artifactId>project-maintenance</artifactId>
</dependency>
</dependencies>
</project>
project-data and project-maintenance are similar to project-web app but they don't have any internal dependencies.
Again, what I want to do is, just run the clean install command on all, and not have to worry about building any of the modules individually.
I think the problem is that you define the parent as a module. When you run „clean“ the parent used by the other modules is still not available so Maven tries to find it within the repository. Better define the parent information within the project-all pom because during the build phase the parent has to be available.

spring boot multi modules package

I am trying to use Maven to package Spring Boot with multi modules,Here my main module pom.xml :
<modules>
<module>my-data-services</module>
<module>my-message-services</module>
<module>my-common</module>
</modules>
<groupId>com.my</groupId>
<artifactId>my-multi-services</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>....</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
my-common pom.xml:
<parent>
<artifactId>my-multi-services</artifactId>
<groupId>com.my</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-common</artifactId>
<packaging>jar</packaging>
<dependencies>....</dependencies>
and my-data-services pom.xml:
<parent>
<artifactId>my-multi-services</artifactId>
<groupId>com.my</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-data-services</artifactId>
<dependencies>
<dependency>
<groupId>com.my</groupId>
<artifactId>my-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
my-common module is just a common utils lib not a runnable module,but when i trying to mvn clean package,exception throws below:
Execution default of goal org.springframework.boot:spring-boot-maven-p
lugin:1.4.2.RELEASE:repackage failed: Unable to find main class
then i add a main class,this module can package,but its not a lib jar, its like a runnable spring boot jar
-BOOT-INF
|
-META-INF
|
-org
and the exception throws
Failed to execute goal org.apache.maven.plugins:maven-compiler- plugin:3.1:compile (default-compile) on project my-data-services: Compilation failure: Compilation failure: package com.my.common.utils does not exist;
com.my.common.utils is in module my-common
How do i fix this problem, and in spring boot multi modules project,how to package a common utils lib without BOOT-INF
This happens because your modules will have the 'spring-boot-maven-plugin' added to them because it's defined in their parent.
What you need to do is move everything into submodules, even your application starter class. How I do this usually:
my-parent-module
my-service-module
my-common-module
my-web-module (or my-runtime-module in a non-web app)
The my-parent-module will have 'spring-boot-starter-parent' as it's parent but it not going to have an src folder because everything is moved into submodules.
The my-web-module will depend on the other modules and will have the 'spring-boot-maven-plugin'. You will be able to run the app with 'mvn spring-boot:run' in the my-web-module folder.

Maven: POM modules and submodules hierarchy

My project is structured like this:
.
|--module
| `-- pom.xml
| --submodule
| `-- pom.xml
`-- pom.xml
The POM's (simplified):
Project:
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>project</artifactId>
<name>Project</name>
<groupId>org.myorg</groupId>
<version>1.0.6-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>module</module>
</modules>
(...)
</project>
Module:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.myorg</groupId>
<artifactId>project</artifactId>
<version>1.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>module</artifactId>
<name>Module</name>
<groupId>org.myorg</groupId>
<version>1.0.6-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>submodule</module>
</modules>
(...)
</project>
Submodule:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.myorg</groupId>
<artifactId>module</artifactId>
<version>1.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>submodule</artifactId>
<name>Submodule</name>
<groupId>org.myorg</groupId>
<version>1.0.6-SNAPSHOT</version>
<packaging>jar</packaging>
(...)
</project>
When run maven install in POM's project or module the project is built sucessfully. But, when run in submodule occours this error:
Failed to execute goal on project submodule: Could not find artifact org.myorg:project:pom:1.0.6-SNAPSHOT
Why my submodule not find the POM project? The relative path is specified.
The first thing which i noticed is that every sub-module which has a parent contains the line:
<relativePath>../pom.xml</relativePath>
which is useless, cause it's default in maven or in other word just remove it.
Furthermore in a multimodule build you shouldn't define the version. In case if the groupId is always the same you can omit the groupId as well, cause the current module inherits the version from it's parent.
module: pom.xml
<project>
<parent>...
</parent>
<artifactId>module</artifactId>
<packaging>pom</packaging>
<name>Module</name>
<modules>
<module>submodule</module>
</modules>
(...)
</project>
Apart from that you can't go into a sub-module and call
mvn install
If you like to install a separate module of a multi-module build you should use a thing like this:
mvn -amd -pl submodule install
which will do what you like to do, but usually you should install a full mulit-module build unless you exactly know what you are doing.
The options -amd is an abbrevation for --also-make-dependents. The -pl is an abbreviation for --projects to define a list of project which should be made during the call.
First you need to run mvn install on root project it will creates the artifact in your local maven repo. From the second time on wards you can run sub module only. If you don't run on root project maven wont create any artifact for your project so when you run on sub module it unable to find the artifact from the maven repo.

How do I setup maven sub-projects with inter-dependencies?

I'm having a hard time setting up a set of related maven projects with interdependencies between them.
Here's my simplified case:
pom.xml -- parent pom
\base\
pom.xml
src\main\java\Base.java -- this is just a simple class
\derived\
pom.xml
src\main\java\Derived.java -- this is a simple class that needs Base class to compile successfully, and has a main function
My goals are:
be able to compile, on my machine, all projects:
i.e. mnv clean compile is successful in \
be able to compile, on my machine, just one project:
i.e. mnv clean compile is successful in \base\ and \derived\ (though this may not work by design: Inter Project Dependencies in Maven)
[edit: found the answer for this one: base needs to be published locally before derived in compiled: i.e. in \base, do mvn clean compile install instead of doing just doing mvn clean compile. Once this is done, doing mvn clean compile in \derived works fine. Still, it would be great to do this without touching global state, i.e. without having to install base -- so if anyone knows a way of achieving this, please add it as an answer]
be able to run derived project on my machine (mvn exec:run or equivalent) direcly from the source tree:
i.e. mvn exec:run in \derived\ should compile (if needed) and run the derived.jar
the "shared component" use case: push the base artifact to the shared repository, where other people can consume it as a maven dependency (i.e. compile time dependency):
i.e. mvn clean compile ??? will push this to the shared repository specified in ~/.m2/config.xml
the "image directory" use case: push the derived artifact and its depedencies to a local directory, where it can be run via "java -jar ..." or it can exposed as an ftp/http share for other people to get it. I.e., use cases like those:
mvn clean compile ??? will push derived.jar and dependencies (like base.jar) to ~/.m2/maven.repo/.../derived or equivalent, and then I can cd ~/.m2/maven.repo/.../derived and run java -jar derived.jar to run it.
mvn clean compile ??? will push base.jar to ~/.m2/maven.repo/.../base (or derived.jar to its corresponding dir), which is already exposed as a download point via local web or ftp server.
How do I do the goals above?
Here's the relevant section from parent pom:
...
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo</groupId>
<artifactId>parentpom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>parentpom</name>
<modules>
<module>base</module>
<module>derived</module>
</modules>
...
Here's the relevant section from base pom.xml:
...
<parent>
<groupId>com.foo</groupId>
<artifactId>parentpom</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo.base</groupId>
<artifactId>base</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>base</name>
...
Here's the relevant section from derived pom.xml:
...
<parent>
<groupId>com.foo</groupId>
<artifactId>parentpom</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo.derived</groupId>
<artifactId>derived</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>derived</name>
<dependencies>
<dependency>
<groupId>com.foo</groupId>
<artifactId>base</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
...
Thank you in advance for your help.
Your parent pom looks good but your module/derived poms don't: There are several issues which will produce some problems etc.
First you are using different groupId's for the derived/base module. If you have a multi-module build you shouldn't do this. Furthermore, the version of derived/base is inherited by the parent and shouldn't be set explicit which means you should have something like the following:
<modelVersion>...</...>
...
<parent>
<groupId>com.foo</groupId>
<artifactId>parentpom</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>base</artifactId>
<packaging>jar</packaging>
<name>base</name>
The groupId is usually inherited. But sometimes you have a larger number of modules that may be sub-modules of sub-modules which results in a structure like this:
+--- parent (pom.xml)
+--- mod1 (pom.xml)
+--- mod11 (pom.xml)
+--- mod12 (pom.xml)
+--- mod2 (pom.xml)
In Such cases, the mod1 itself is a a pom packaging module:
<modelVersion>...</...>
...
<groupId>com.company.project<groupId>
<artifactId>parent</artifactId>
<packaging>pom</packaging>
<modules>
<module>mod1</module>
<module>mod2</module>
</modules>
mod1:
<parent>
<groupId>com.company.project<groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.company.project.mod1</groupId>
<artifactId>mod1</artifactId>
<packaging>pom</packaging>
<modules>
<module>mod11</module>
<module>mod12</module>
</modules>
mod11:
<parent>
<groupId>com.company.project.mod1</groupId>
<artifactId>mod1</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>mod11</artifactId>
<packaging>pom</packaging>
<modules>
<module>mod11</module>
<module>mod12</module>
</modules>
If you need to make a dependency between modules the solution is:
<parent>
<groupId>com.company.project.mod1</groupId>
<artifactId>mod1</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>mod11</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<!-- This shouldn't be a dep which is packaging: pom -->
<groupId>${project.groupId}</groupId>
<artifactId>mod2</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
To compile the whole project with all sub modules in one just go to parent folder and:
mvn clean package
will compile etc. If you like to compile only a single project you can do this by (from parent):
mvn -pl mod1
which will work only if you have installed the whole project once before. Another solution is:
mvn -am -pl mod1
To make the artifacts acessible for others the simplest solution is to install a repository manager and do:
mvn deploy
All others can use and artifact as a SNAPSHOT dependency.

Resources