Search code examples
javaspring-bootgradlemulti-module

Multimodule gradle project I get Error: Not Found (Spring with module dependency)


When studying and implementing a multimodule project with Java and Gradle, I am having the following error when making a request:

Postman

{
     "status": 404,
     "error": "Not Found",
     "message": "No message available",
     "path": "/tasks/hello"
}

When running the command "./gradlew :task-service:bootRun" the project seems to start normally "Tomcat started on port(s): 8080 (http) with context path''. But when making requests, I get "not found". I can't say where the error is, but I realize that the import of the "domain" module is not correct or I don't know how to configure it. Can you help me?

The project and its modules - group 'com.nyuro'

nyuro-backend (root-project)
 *domain
 *task-service

The "domain" module contains entities, such as the Task class. Services will be Spring Boot app with @Controller, @Service, @Repository. In this example "task-service".

Here are the main snippets of settings. I hope that's enough to point me out some configuration error. Or here is the code on github: Project Link Here

settings.gradle(nyuro-backend)

rootProject.name = 'nyuro-backend'
include 'domain'
include 'task-service'

build.gradle(nyuro-backend)

plugins {
    id 'java'
    id 'application'
}

group 'com.nyuro'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}

test {
    useJUnitPlatform()
}

build.gradle(:domain)

plugins {
    id 'java'
    id 'application'
}

group 'com.nyuro'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
    implementation 'jakarta.persistence:jakarta.persistence-api:3.1.0'
}

test {
    useJUnitPlatform()
}

build.gradle(:task-service)

plugins {
    id 'java'
    id 'application'
    id 'org.springframework.boot' version '3.1.0'
    id 'io.spring.dependency-management' version '1.1.0'
}

group = 'com.nyuro'
version = '0.0.1-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    runtimeOnly 'com.mysql:mysql-connector-j'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation project(':domain')
}

tasks.named('test') {
    useJUnitPlatform()
}

TaskServiceApplication.java

@EntityScan({"com.nyuro.domain"})
@EnableJpaRepositories({"com.nyuro.domain"})
@ComponentScan({"com.nyuro.domain"})
@SpringBootApplication
public class TaskServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(TaskServiceApplication.class, args);
    }

}

There seems to be a problem importing the domain.models.Task module. I also did several tests on @EntityScan, @EnableJpaRepositories, @ComponentScan imports. No satisfactory result.


Solution

  • Your 404 Not Found error comes solely from your Controller not being picked up because of custom ComponentScan annotation on SpringBootApplication but let me raise a few more points:

    1. You should not commit .gradle, .idea, build, etc. directories to Git. Create a .gitignore file to ignore them - you have one but its inside task-service, you should have one in root directory ideally (but you can have more specific to some particular sub-projects)
    2. You have 2 gradle wrappers (in root and task-service) - the one in task-service should be removed
    3. I don’t think you need task-service/settings.gradle file as well. I realise you probably started with a single-module project and turned it into a multi-module one.
    4. You are making ComponentScan and EntityScan on com.nyuro.domain but you have no classes in this package (domain classes are in module package), most importantly @SpringBootApplication already does component scan on the package it is located in. You should remove @ComponentScan(“com.nyuro.domain”) as it prevents you Controller which is not under that package from being picked up by Spring (SpringBootApplication is in com.nyuro.taskservice and controller in com.nyuro.taskservice.controllers so the default component scan will pick it up as its a sub-package). If you want to scan additional packages you will have to add task-service package as well - @ComponentScan({"com.nyuro.domain", "com.nyuro.taskservice"}).
    5. You database setup is not working for me, I had to remove it to make this app start