0
votes

I have a small spring boot app that does user management.
I want to include this UserManagement app as a dependency (gradle) in my other spring-boot apps.

I do not want to run the UserManagement app as stand-alone application (it needs to share beans with parent application).

I am using gradle and the spring-boot plugin. I have included the UserManagement jar as a dependency in a spring-boot ExampleApp.

The UserManagement app runs an embedded-tomcat server on port 8081.
The ExampleApp runs an embedded-tomcat server on port 8080.

Everything works well, except for my UserManagement MVC UI.
When I hit the User-Management app on port 8081, my MVC templates are not found.

I can not seem to locate the MVC templates for the UserManagement app from the parent application, ExampleApp.
Is this even possible with spring-boot?

1

1 Answers

0
votes

Yes. You can do this. I am not sure how you are sharing beans, but I suppose you could do that too.

SpringApplicationBuilder
Since the “UserManagement” app is a dependency, I would assume you are calling a method to run it from your parent application

For example, you are probably doing something like this:

public class UserManagementApplication {
    private static UserManagementApplication instance = null;

    private final SpringApplicationBuilder springApplicationBuilder;
    private ConfigurableApplicationContext context;

    private UserManagementApplication() {
       this.springApplicationBuilder = new SpringApplicationBuilder(UserManagementApplication.class);
    }

    public static void start() {
        synchronized (UserManagementApplication.class) {
            if (instance == null) {
                /*
                 ******** If singleton instance is null ***************************************
                 ******** Create a new UserManagementApplication ******************************
                 */
                instance = new UserManagementApplication();
            }

            if (instance.context == null
                    || !instance.context.isActive()) {
                /*
                 ******** If the context is null or not active ********************************
                 ******** Create new SpringApplication and run it  ****************************
                 ******** Store the resulting ConfigurableApplicationContext in memory ********
                 */
                instance.context = instance.springApplicationBuilder.run(new String[]{});
            }
        }
    }

    public static void stop() {
        synchronized (UserManagementApplication.class) {
            if (instance == null
                    || instance.context == null
                    || !instance.context.isActive()) return;
            /*
             ******** If the context is active ********************************************
             ******** Close the context  **************************************************
             ******** Set context back to null ********************************************
             */

            instance.context.close();
            instance.context = null;
        }
    }

    public static ConfigurableApplicationContext getContext() {
        if (instance == null) return null;
        return instance.context;
    }
}

UserManagement gradle.build and locations

  1. Since you don’t need to run the “UserManagement” app as an executable jar, you can ditch the spring-boot plugin and make your own jar.
  2. Since your are using tomcat you can put templates and static resources in META and templates in WEB-INF.
    • Resources => src/main/resources/META-INF/resources/static/
    • Templates => src/main/resources/WEB-INF/templates/

For example, your gradle build could look something like this:

buildscript {
    ext {
        springBootVersion = '2.0.0.M7'
    }
    repositories {
        mavenCentral()
        maven { url "https://repo.spring.io/snapshot" }
        maven { url "https://repo.spring.io/milestone" }
        maven { url 'http://repo.spring.io/plugins-release' }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath 'io.spring.gradle:propdeps-plugin:0.0.9.RELEASE'
        classpath 'org.springframework:springloaded:1.2.6.RELEASE'
    }
}

ext {
    springBootVersion = '2.0.0.M7'
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'groovy'
// apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'propdeps'
apply plugin: 'propdeps-idea'

group = 'com.example.userManagement'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
    maven { url "https://repo.spring.io/snapshot" }
    maven { url "https://repo.spring.io/milestone" }
}

configurations {
    includeInJar
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.boot:spring-boot-starter-groovy-templates')
    compile('org.codehaus.groovy:groovy')

    includeInJar("org.webjars:bootstrap:4.0.0")
    includeInJar("org.webjars:jquery:3.3.1")
    configurations.compile.extendsFrom(configurations.includeInJar)
}

idea {
    module {
        inheritOutputDirs = true
    }
}

jar {
    from configurations.includeInJar.collect { it.isDirectory() ? it : zipTree(it) }
}

compileJava.dependsOn(processResources)

MVC config

Also, make sure your MVC config knows where the resources are.
For example, if you are extending the WebMvcConfigurerAdapter:

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/static/**").addResourceLocations("classpath:META-INF/resources/static/");
    registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:META-INF/resources/webjars/");
    registry.addResourceHandler("/**").addResourceLocations("classpath:META-INF/");
}

MVC templates

If you have a "my-bundle.min.js" file in src/main/resources/META-INF/resources/static/js, you can find it from your mvc template like this:

<script src="/resources/static/js/my-bundle.min.js"></script>



I hope this helps!