SPRING BOOT - How to access classes from Super POM - java

I have created a parent project so I can have all the common dependencies, DTOs, services, helpers, etc. that I will use in all my common projects.
This parent project is imported as POM:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.whitehawk</groupId>
<artifactId>hawk-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hawk-parent</name>
<packaging>pom</packaging>
<description>Parent configuration for microservices</description>
In the other projects I have:
<parent>
<groupId>com.whitehawk</groupId>
<artifactId>hawk-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>customers</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>customers</name>
<description>Customers microservice</description>
The dependencies have been imported correctly, but I am not able to access for example my Role enum even if it has public access modifier.
public enum Role {
CUSTOMER,
ADMIN,
SUPERADMIN
}
Or my #UserRole annotation:
#Target({ElementType.METHOD, ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Inherited
public #interface UserRole {
Role[] value();
}
Any idea about what I am doing wrong?
Cheers!
Update:
Following suggestions, I added a new module: hawk-core
Its POM looks like:
<?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>
<parent>
<groupId>com.whitehawk</groupId>
<artifactId>hawk-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/>
</parent>
<artifactId>hawk-core</artifactId>
<name>hawk-core</name>
<description>Core libraries for microservices</description>
<packaging>jar</packaging>
</project>
And included this in the parent:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.whitehawk</groupId>
<artifactId>hawk-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hawk-parent</name>
<packaging>pom</packaging>
<description>Parent configuration for microservices</description>
<modules>
<module>hawk-core</module>
</modules>

I think there is misunderstanding here for 2 things:
1- packaging: this field is used as POM if you are not having classes to be package in jar/war file, this used for example for parent project which is not used as dependancies or packaged to be deployed.
2- dependancies: this decencies is used for adding lib packages you required for your project from sample you have here you are not including this, so the classes will not be seen in your project
suggest to have a parent project that not have any classes and have 2 modules one is your core classes to be jar as lib, and second one as spring boot you may refer to https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-build-systems.html#using-boot-maven-without-a-parent and have the first module as dependency in your second module to be like:
parent
|
|-core
|-pomt.xml
|-app
|-pomt.xml
|-pom.xml

Related

Parent POM vs Super POM - are they same?

I want to understand if Parent POM and Super POM are same or are there still differences.
Take below maven poms, I declare a parent pom as below:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo</groupId>
<artifactId>deps</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<!-- not relevant for this question -->
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.12</version>
</dependency>
</dependencies>
</project>
Now I declare a child pom as below:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo</groupId>
<artifactId>deps2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>com.demo</groupId>
<artifactId>deps</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<!-- not relevant for this question -->
</dependencies>
</project>
Now deps is the parent pom for deps2. I am not sure if I can also call deps as super pom for deps2.
Which of the below inheritance hierarchy is correct
dep2 --> deps end (NO Maven provided super pom)
dep2 --> deps --> Maven provided super pom end
Option 2, because all models implicitly inherit from the Super POM.
deps is a parent for deps, but not the Super POM.
This is according to the definitions on the website.
What is more ... if you inspect the effective POM, you will see that it will always inherit from the Super POM on the MVN website.

Spring boot properties vs maven pom packaging tag

I have been facing some problems with spring boot and maven.
It seems that the <packaging>pom</packaging> tag, when added to pom.xml, somehow makes spring completely unaware of the parent-level applications.properties configuration file. When running, spring still will show the banner and info-level logging regardless of the properties stated. Why would that be the case? Is there a way to add those properties to my parent such that all modules would operate under given configuration? Would this become an anti-pattern?
Main class:
package com.example.app; //could also be inside the app-client module
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
application.properties:
spring.main.banner-mode=off
logging.level.root=info
(parent) pom.xml:
<?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>
<packaging>pom</packaging>
<modules>
<module>app-client</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.</groupId>
<artifactId>app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>app</name>
<description>Demo app</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Totally agreeing with the comment of Andy on your question I like to point out, that the use of the packaging type pom is appropriate if you want to denote an artifact as some kind of module container are base project where you collect dependency information for your (sub-)modules.
However the #SpringBootApplication in your case shows us that you want to use your artifact for running business code. That on the other hand leads to packaging types like jar or war. Switch it to one of them and everything should run fine.
For more information please consult also the Maven reference for packaging.

Project build error: Non-resolvable parent POM fo

This is my first project using spring boot. So I tried to update the pom.xml with the parent as below:
<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.in28minutes.springboot</groupId>
<artifactId>first-springboot-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-in-10-steps</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
However, I got an error in line:
Project build error: Non-resolvable parent POM for
com.in28minutes.springboot:first-springboot-project:0.0.1-SNAPSHOT:
Could not find artifact
org.springframework.boot:spring-boot-starter-parent:pom:2.0.0.BUILD-SNAPSHOT
and 'parent.relativePath' points at wrong local POM
any help please !
There no such thing as 2.0.0-BUILD-SNAPSHOT, you might have copied this directly from a Spring Boot project?
The released version of Spring Boot can be seen here;
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent
If you want the latest verison, <version>2.0.6.RELEASE</version> will work.
If you want to use SNAPSHOT, or Milestone releases see the documentation
https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/getting-started-installing-spring-boot.html#getting-started-maven-installation
which specifies the required repos.
Change 2.0.0.BUILD-SNAPSHOT to 2.0.0.RELEASE

Properties defined in parent pom cannot be resolved/updated in child pom

The parent pom:
<modelVersion>4.0.0</modelVersion>
<groupId>xx.xxxx.xxxx.xx</groupId>
<artifactId>parent-pom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<properties_deinfed_in_parent_pom>1.0.2-SNAPSHOT</properties_deinfed_in_parent_pom>
</properties>
The child pom:
<parent>
<groupId>xx.xxxx.xxxx.xx</groupId>
<artifactId>parent-pom</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>child-pom</artifactId>
<packaging>war</packaging>
<version>${properties_deinfed_in_parent_pom}</version>
which includes the parent pom, if I change the property properties_deinfed_in_parent_pom in parent pom, the version in child pom won't be updated. The only way I can update is using -Dxxx=value in maven command. I also checked the effective pom, it's also not updated. So will this idea work as my expectation, or what I thought was wrong.
I use Maven 3.3.x, IntelliJ 2018.1
The parent pom need to have the list of modules specified. Add the following to the parent pom
<modules>
<module>child-pom</module>
</modules>

How to specify maven properties in a aggregator POM?

I have a project structure like below.In aggregator POM project1 and project 2 are defined as modules.Now if i want to add a maven property that can be accessed in all the projects how can i do it?.
What is the best project structure in this case.?
If i define property like <temp.dir>data</temp.dir> in the aggregator POM then it is not available in project1 pom.xml and project2 POM.xml.I have to duplicate the same property in both the POM's.
project
- project1
- - pom.xml ---- has parent POM as project A
- project2
- - pom.xml --- has parent POM as project B
- pom.xml (Aggregator POM)
UPDATE:To clarify more project1 pom and project 2 has different parent POM's.So aggregator POM cannot be set as parent.
You need to set the aggregator pom as the parent of project1 and project2.
eg. in project1 and project2 poms add:
<parent>
<groupId>com.agr</groupId>
<artifactId>project-aggregator</artifactId>
<version>1.0.0</version>
</parent>
EDIT:
I understand that project1 and project2 have different parent poms.
The only solution i know about to achieve what You want is to store the properties in parent pom.
I can think only of one solution, to make an inheritance chain:
Project2Parent:
<parent>
<groupId>com.test</groupId>
<artifactId>Project1Parent</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>Project2Parent</artifactId>
<version>0.0.1</version>
Aggregator:
<parent>
<groupId>com.test</groupId>
<artifactId>Project2Parent</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>Aggregator</artifactId>
<version>0.0.1</version>
Project1
<parent>
<groupId>com.test</groupId>
<artifactId>Aggregator</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>project1</artifactId>
<version>0.0.1</version>
Project2
<parent>
<groupId>com.test</groupId>
<artifactId>Aggregator</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>project2</artifactId>
<version>0.0.1</version>
Here is aggregator's pom:
<groupId>y</groupId>
<artifactId>y</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
<modules>
<module>y1</module>
<module>y2</module>
</modules>
<properties>
<x>1</x>
</properties>
This is y1 effective pom (generated by Eclipse):
<parent>
<groupId>y</groupId>
<artifactId>y</artifactId>
<version>0.0.1</version>
</parent>
<groupId>y1</groupId>
<artifactId>y1</artifactId>
<version>0.0.1</version>
<properties>
<x>1</x>
</properties>
As you can see property x declared in parent is inherited by child.

Categories