Maven Multi Module insists on duplicating datasource application.properties in business module
Asked Answered
J

2

4

I have spring boot maven java multi module structure. My structure is:

product (parent pom module)
..product-data (child pom module)
..product-business (has dependency for product-data) 
..product-rest (has dependency for product-business) 
..product-entities (child pom module)

product-data will return entity object to product-business and product-business will return entity object to product-rest and product-rest returns json object.

product-data runs fine. But as soon as I run product-business, I get error "Cannot determine embedded database driver class for database type NONE". Spring looks for spring.datasource.... properties under my product-business/src/main/resources/application.properties file. If I define all the properties here then error goes away and I get the data from product-data.

But!! I have already defined the properties under product-data/src/main/resources/ application.properties file. Why do I have to duplicate the same properties in my product-business module? The whole purpose is to separate layers. product-data is responsible for fetching the data and it should find the spring.datasource... properties under its own structure. Why does it forces me to duplicate the properties in business module too? I am sure I am missing something. Does someone has any clue?

I have gone through many similar questions on SO but most of them were missing the properties so that doesn't solves my problem. I assume my pom files are not the suspect because once I copy paste the properties from product-data to product-business then error goes away. But incase if you still want to see my pom:

Parent product POM

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.owner</groupId>
    <artifactId>product</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <nopeasti.version>1.0.0-SNAPSHOT</nopeasti.version>
    </properties>

    <dependencies>

    </dependencies>

    <modules>
        <module>product-data</module>
        <module>product-business</module>
        <module>product-rest</module>
        <module>product-entities</module>
    </modules>
</project>

product-data POM

<project>
    <artifactId>product-data</artifactId>
    <packaging>jar</packaging>
    <parent>
        <groupId>com.owner</groupId>
        <artifactId>product</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <dependencyManagement>
         <dependencies>
            <dependency>
                <!-- Import dependency management from Spring Boot -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>1.5.8.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.0.0.M6</version>
            </plugin>
        </plugins>
    </build>
</project>

product-business POM

<project>
    <artifactId>product-business</artifactId>
    <packaging>jar</packaging>
    <parent>
        <groupId>com.owner</groupId>
        <artifactId>product</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <dependencyManagement>
         <dependencies>
            <dependency>
                <!-- Import dependency management from Spring Boot -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>1.5.8.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <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>
        <dependency>
            <groupId>com.owner</groupId>
            <artifactId>product-data</artifactId>
            <scope>compile</scope>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.0.0.M6</version>
            </plugin>
        </plugins>
    </build>
</project>
Jegar answered 15/11, 2017 at 21:36 Comment(4)
Error that I get: APPLICATION FAILED TO START Description: Cannot determine embedded database driver class for database type NONE Action: If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).Jegar
You should use the spring-boot-maven-plugin with the same version as the imported spring boot dependencies...the do not fit together...Shayshaya
product-data and product-business both uses same version of spring bootJegar
@Jegar have you found solution for your problem? I am facing the same issueJaneljanela
J
4

According to this,

It is not advisable to put application.properties in a library because there might be a clash at runtime in the application that uses it (only one application.properties is ever loaded from the classpath)

To solve this and still maintain decoupled architecture, I created another file data.properties under resources folder of product-data module and specified @PropertySource annotation in the config file. Here is the config file of product-data module. The spring.datasource properties were defined in this file. Then there was no need for spring.datasource properties in other 2 modules.

@ComponentScan
@EnableAutoConfiguration
@SpringBootConfiguration
@PropertySource(value = "data.properties")
public class NopeastiDataConfig {
    // no main needed here as this is library consumed by business layer
}

Further read here: Externalized Configuration

Jegar answered 26/11, 2017 at 19:15 Comment(1)
But then how do you override some of the properties in a context mindful way?Bassesalpes
J
2

You can use spring.config.name property to override default value application and put there more property file names.

E.g.:

spring.config.name=entities,business,application

In such case you can have entities.properties in entities module, business.properties in business module and application.properties in rest or app module. The last config name (application) has highest priority and the first one (entities) has lowest priority.

Jariah answered 18/1, 2021 at 23:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.