Multi-module Spring Boot and start-class - java

I have made my application multi-module with the plan of eventually splitting them into multiple repos.
I'm having problems figuring out how to make mvn spring-boot:run work with my layout (which may be the problem).
actually directory structure is
xenoterracide/
rpf/
rpf-application/
when I run mvn test from xenoterracide that passes fine, and when I start my Application class that works fine.
if I cd into rpf-application and run mvn compile it tells me that it can't find the dependencies, I'm guessing this is because things are meant to be run from the repository root.
[INFO] ------------------------------------------------------------------------
[INFO] Building rpf-application 0.1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[WARNING] The POM for com.xenoterracide:security-rbac-jpa:jar:0.1.0-SNAPSHOT is missing, no dependency information available
[WARNING] The POM for com.xenoterracide:http:jar:0.1.0-SNAPSHOT is missing, no dependency information available
[WARNING] The POM for com.xenoterracide:rpf-domain:jar:0.1.0-SNAPSHOT is missing, no dependency information available
[WARNING] The POM for com.xenoterracide:rpf-liquibase:jar:0.1.0-SNAPSHOT is missing, no dependency information available
if I try to set the start-class in the xenoterracide/pom.xml it tells me it can't find the class (because of course it's in rpf-application).
rpf-application/pom.xml
<parent>
<artifactId>rpf</artifactId>
<groupId>com.xenoterracide</groupId>
<version>0.1.0-SNAPSHOT</version>
<relativePath>../rpf/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>rpf-application</artifactId>
<properties>
<start-class>com.xenoterracide.RpfApplication</start-class>
</properties>
<dependencies>
<!-- internal -->
<dependency>
<groupId>com.xenoterracide</groupId>
<artifactId>security-rbac-jpa</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.xenoterracide</groupId>
<artifactId>http</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.xenoterracide</groupId>
<artifactId>rpf-domain</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.xenoterracide</groupId>
<artifactId>rpf-liquibase</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
...
rpf/pom.xml
<parent>
<artifactId>xenoterracide</artifactId>
<groupId>com.xenoterracide</groupId>
<version>0.1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>rpf</artifactId>
<packaging>pom</packaging>
<modules>
<module>../rpf-domain</module>
<module>../rpf-application</module>
<module>../rpf-liquibase</module>
</modules>
pom.xml
<modelVersion>4.0.0</modelVersion>
<groupId>com.xenoterracide</groupId>
<artifactId>xenoterracide</artifactId>
<packaging>pom</packaging>
<version>0.1.0-SNAPSHOT</version>
<modules>
<module>util</module>
<module>http</module>
<module>security-rbac-api</module>
<module>security-rbac-jpa</module>
<module>hibernate</module>
<module>entity-jpa</module>
<module>rpf</module>
<module>test-repositories</module>
<module>entity-api</module>
</modules>
<properties>
<!-- use UTF-8 for everything -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>1.1.2.RELEASE</version>
</parent>
how can I make mvn spring-boot:run work from either the root of the repository (xenoterracide) or from rpf-application?

I also have a multi-project Spring Boot app and you can't do it from the parent since there could be multiple modules and it would not know which to run. You can do it from the child module if you first install the rest of the project to local Maven repository. So from your xenoterracide run:
mvn install
Assuming that works it will put your SNAPSHOT versions into your local repository. You can then change to your rpf-application and then run:
mvn spring-boot:run
I've never really used this as a way to run it so maybe you can explain what your need is and we can see if there is another way that may be better. I did do it with my project and it works but you have to be conscious of where the working directory is for your environment specific configuration files.

Related

Why can't maven parse the expression in the parent's version?

I came across a problem with a maven project build.
My project structure is as follows
my-message
|
---my-message-api
|
--- my-message-provider
Below is the pom.xml code
my-message.pom
<parent>
<groupId>com.xiaofeng.my</groupId>
<artifactId>my-parent</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>my-message</artifactId>
<version>${my-message.version}</version>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<properties>
<my-message.version>0.0.1-SNAPSHOT</my-message.version>
</properties>
<modules>
<module>my-message-api</module>
<module>my-message-provider</module>
</modules>
my-message-api.pom
<parent>
<groupId>com.msh.my</groupId>
<artifactId>my-message</artifactId>
<version>${my-message.version}</version>
<relativePath>../pom.xml</relativePath>
</parent>
my-message-provider.pom
<parent>
<groupId>com.msh.my</groupId>
<artifactId>my-message</artifactId>
<version>${my-message.version}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>my-message-provider</artifactId>
<dependencies>
<dependency>
<groupId>com.msh.my</groupId>
<artifactId>my-message-api</artifactId>
<version>${my-message.version}</version>
</dependency>
</dependencies>
maven install output
Failed to execute goal on project my-message-provider: Could not resolve dependencies for project
com.msh.my:my-message-provider:jar:0.0.1-SNAPSHOT: Failed to collect dependencies at com.msh.my:my-message-api:jar:0.0.1-SNAPSHOT:
Failed to read artifact descriptor for com.msh.my:my-message-api:jar:0.0.1-SNAPSHOT: Could not find artifact com.msh.my:my-message:pom:${my-message.version}
in nexus (http://nexus_url:8081/nexus/content/groups/public)
Why can't maven parse the expression in the parent's version? please help me
Because you can't use a variable in the specification of a parent in a module. Maven needs to be able to resolve the whole model structure before it can resolve variables.

How to bundle/package latest version of custom library in maven web project without updating pom.xml?

I have a custom library - Dao.jar which contains the database persistence logic.
I push this jar to artifactory with new version each time there is a change in code as shown below :
mvn install:install-file -Dfile=C:\*****\target\Dao.jar -DgroupId=non-public.com.karthik -DartifactId=dao -Dversion=2.0 -Dpackaging=jar
I have another maven web project which has a dependency on this jar. This jar is also packaged/bundled in the maven webapp project/war.
<dependency>
<groupId>non-public.com.karthik</groupId>
<artifactId>dao</artifactId>
<version>2.0</version>
</dependency>
Currently, I am changing the version of dao dependency in the pom.xml & re-building the maven webapp project each time a new version of Dao.jar is available in the artifactory.
Is there any option to build the maven project with the latest version of Dao.jar without manually changing the dependency version in the pom.xml?
When Maven searches for a dependency, it first checks the local repository (~/.m2/repository). If it's not found, it tries other resources, such as remote repositories defined in the POM file or in the settings file (~/.m2/settings.xml).
By that logic, if you try to use a version of a local project that's not yet installed to the local repository, Maven will never be able to find it to use in another project.
To avoid changing version numbers all the time and manually building both projects. You could create a parent POM for both projects. The parent would then be able to recognize that one of the child projects depends on the other and build them in the correct order.
Based on Luciano's inputs, I have created a multi-module maven project/parent POM with 2 modules(dao & web)
Parent
<groupId>com.karthik</groupId>
<artifactId>test</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
..........
</dependencies>
</dependencyManagement>
<modules>
<module>web</module>
<module>dao</module>
</modules>
Child module # 1 - dao
<parent>
<groupId>com.karthik</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>dao</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>oracle</groupId>
<artifactId>ojdbc6</artifactId>
</dependency>
.........
</dependencies>
Child module # 2 - web(declared dao dependency in POM)
<parent>
<groupId>com.karthik</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>web</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>com.karthik</groupId>
<artifactId>dao</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
.........
</dependencies>
When I run mvn package command at root path of parent pom, both modules - web.war and dao.jar are built. This method ensures always the latest version of dao.jar is packaged in web.war.

Thymeleaf dependency causes "Error: Could not find or load main class" in Spring tool suite

I've just downloaded STS and started some maven project and it worked properly, but when I start using thymeleaf it doesn't work.
I see an exclamation mark on the project name, and I get this error Error: Could not find or load main class.
I tried adding its dependencies by myself in the POM, I get that error and it goes away once I remove them!
I also tried creating a "Spring Starter Project" and choosing dependencies "Web and Thymeleaf" to be added, right after the project is created I see a syntax error in the POM in the test dependency Failure to transfer org.springframework.boot:spring-boot-starter-test:jar
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
and when I remove it and its class, I get the same error above.
here is my POM now:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo-2</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Try to update your maven repository, try first:
mvn dependency:purge-local-repository
Description:
When run on a project, remove the project dependencies from the local
repository, and optionally re-resolve them. Outside of a project,
remove the manually given dependencies.
and then try:
mvn dependency:copy-dependencies
Description:
Goal that copies the project dependencies from the repository to a
defined location.
It seems to me that your local Maven repository doesn't include the thymeleaf dependecy.
The problem was solved after removing failed downloads:
from CMD:
cd %userprofile%\.m2\repository
for /r %i in (*.lastUpdated) do del %i
then updating the project.
It re-downloaded the dependencies and it worked just fine.

maven - Can't release project due to non released dependencies

I am using a multi-module pom setup and when using the release plugin I am unable to do so.
I get the error:
Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.5:prepare (default-cli) on project libraryparent: Can't release project due to non released dependencies :
com.xyz:libraryparent:pom:1.1-SNAPSHOT
in project 'utils' (com.xyz:utils:jar:1.1-SNAPSHOT)
the command I runs is:
mvn -B release:clean release:prepare release:perform -DdryRun=true -DdevelopmentVersion=1.2-SNAPSHOT -DreleaseVersion=1.1
Here is the major portions of the files that I think is relevant:
libraryparent
<modelVersion>4.0.0</modelVersion>
<groupId>com.xyz</groupId>
<artifactId>libraryparent</artifactId>
<version>1.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>parent library</name>
<description>A parent pom for all library modules</description>
<modules>
<module>../util</module>
<module>../streams</module>
</modules>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5</version>
<configuration>
<releaseProfiles>release</releaseProfiles>
<goals>deploy assembly:single</goals>
<!--
<autoVersionSubmodules>true</autoVersionSubmodules>
-->
</configuration>
</plugin>
util
<project .....>
<modelVersion>4.0.0</modelVersion>
<artifactId>util</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>com.xyz</groupId>
<artifactId>libraryparent</artifactId>
<relativePath>../libraryparent/pom.xml</relativePath>
<version>1.1-SNAPSHOT</version>
</parent>
</project>
streams
<project .....>
<modelVersion>4.0.0</modelVersion>
<artifactId>streams</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>com.xyz</groupId>
<artifactId>libraryparent</artifactId>
<relativePath>../libraryparent/pom.xml</relativePath>
<version>1.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.xyz</groupId>
<artifactId>util</artifactId>
<version>1.1-SNAPSHOT</version>
<!--
<version>${project.parent.version}</version>
-->
<classifier>j2me</classifier>
<optional>true</optional>
</dependency>
</dependencies>
</project>
I would suspect that the release plugin can set the versions to their release versions,etc.
Thanks.
The maven-release-plugin verifies if the parent and dependencies are part of the multimodule project. If it's not recognized it's either because of a different version or because of a typo in the groupId and/or artifactId. com.xyz is probably fake, so please check that value again.
Some may say that flat-projects (like this one) are not supported by the maven-release-plugin. However, there are a lot of integration-tests which do confirm that flat projects are supported.
I think I have just found the solution,
I will do a more complete test and post results shortly.
Change the maven-release-plugin goals from this:
<goals>deploy assembly:single</goals>
to this
<goals>deploy</goals>
...the end...

Maven Multi Module Project breaking compile-time class resolution

I've been previously managing a 3-module project as 3 seperate maven projects. As this project has been moving forward, I decided I ought to take advantage of the dependency management of maven2 to streamline integration between these 3 evolving modules.
I defined a super-project that deploys as POM. Some shared dependencies are defined here, and the modules are defined in the POM in the order of dependency from the least dependent module to the most dependent module. Each module has a POM definition back to the parent, and where it applies there are dependencies from one module to the deployed artifact of another module. I'll include possibly worthwhile pom.xml lines at the end.
On to the problem, I setup this project yesterday and was able to get each module building and working on its own. I then come back today to work on one of the modules now that some fresh requirements have come in and all of sudden everything is breaking. I'm editing the projects in Eclipse, and each time I modify a file, it no longer can resolve any of the classes defined within the same project. That is to say if I have a class foo.bar.class1 and it has an object of foo.bar.class2, Eclipse (and the compiler at large) complains that it cannot resolve class foo.bar.class2... Now this is blowing my mind because this other class is in the same project and package. Similar issues are also present for classes not in the same package.
Is there something broken in my maven setup, or does anyone have any idea why these projects can't even resolve classes in the same package??
-::POMs::-
Parent -> /path/to/project/mainApp
<modelVersion>4.0.0</modelVersion>
<groupId>com.moremagic</groupId>
<artifactId>mainApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Main App</name>
<modules>
<module>Broker</module>
<module>Soap</module>
<module>UI</module>
</modules>
Broker -> /path/to/project/mainApp/Broker
<parent>
<artifactId>mainApp</artifactId>
<groupId>com.moremagic</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.moremagic</groupId>
<artifactId>Broker</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
Soap -> /path/to/project/mainApp/Soap
<parent>
<artifactId>mainApp</artifactId>
<groupId>com.moremagic</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.moremagic</groupId>
<artifactId>SOAP</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
...
<dependency>
<groupId>com.moremagic</groupId>
<artifactId>Broker</artifactId>
<version>1.0-SNAPSHOT</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
...
UI -> /path/to/project/mainApp/UI
<parent>
<artifactId>mainApp</artifactId>
<groupId>com.moremagic</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.moremagic</groupId>
<artifactId>UI</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
...
<dependency>
<groupId>com.moremagic</groupId>
<artifactId>SOAP</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.moremagic</groupId>
<artifactId>Broker</artifactId>
<version>1.0-SNAPSHOT</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
...
It sounds like the problem is with your Eclipse setup and not Maven.
Does mvn compile work from the command-line within your projects? From both the parent project and each individual module (after doing mvn install for the dependencies)?
Are you using a Maven plugin for Eclipse, such as m2eclipse? Check that it is configured to load dependent projects from within Eclipse, rather than looking to the repository ("Enable Workspace Resolution"). What happens if you do Project > Clean to clean out all of the projects?

Categories

Resources