0

What I'm trying to do is to extract all of spring-boot-starters to a separate app, pack all of it into a single JAR (using gradle shadow plugin) and then deploy it to local nexus artifacts repository, so I can import it and all of its dependencies to my spring boot application.

Here is build.gradle of app that contains spring-boot-starters:

buildscript {
    ext {
        springBootVersion = '2.1.0.RELEASE'
    }
    repositories {
        mavenCentral()
        jcenter()
        maven {
            url "http://localhost:8081/repository/testowe/"
            credentials {
                username 'admin'
                password 'admin123'
            }
        }
    }
    dependencies {
        classpath 'com.github.jengelman.gradle.plugins:shadow:4.0.4'
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

subprojects {
    apply plugin: 'java-library'
    apply plugin: 'idea'
    apply plugin: 'java'
    apply plugin: 'com.github.johnrengelman.shadow'
    apply plugin: 'maven-publish'
    apply plugin: 'io.spring.dependency-management'
    apply plugin: 'org.springframework.boot'

    version = '1.0'
    sourceCompatibility = 1.11

    jar { enabled = true }
    shadowJar { classifier(null) }

    repositories {
        jcenter()
        mavenCentral()
        maven {
            url "http://localhost:8081/repository/testowe/"
            credentials {
                username 'admin'
                password 'admin123'
            }
        }
    }

    publishing {
        publications {
            shadow(MavenPublication) { publication ->
                project.shadow.component(publication)
            }
        }
        repositories {
            maven {
                url "http://localhost:8081/repository/testowe/"
                credentials {
                    username 'admin'
                    password 'admin123'
                }
            }
        }
    }

    dependencies {
        compile('org.springframework.boot:spring-boot-starter-web') {
            transitive = true
        }
        compile('org.springframework.boot:spring-boot-starter-actuator') {
            transitive = true
        }
        compile('org.springframework.boot:spring-boot-starter-data-jpa') {
            transitive = true
        }
        compile('org.springframework.boot:spring-boot-starter-security') {
            transitive = true
        }
        compile('org.springframework.boot:spring-boot-starter-test') {
            transitive = true
        }

    }
}

Here is build.gradle of spring-boot app that I want to run with all spring-boot-starter dependencies coming from built JAR:

buildscript {
    ext {
        springBootVersion = '2.1.0.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

sourceCompatibility = 11

repositories {
    mavenCentral()
    maven {
        url "http://localhost:8081/repository/testowe/"
        credentials {
            username 'admin'
            password 'admin123'
        }
    }
}

dependencies {
//    When I'm running app with starters placed here everything works fine
//    implementation('org.springframework.boot:spring-boot-starter-data-jpa')
//    implementation('org.springframework.boot:spring-boot-starter-security')
//    implementation('org.springframework.boot:spring-boot-starter-test')
//    implementation('org.springframework.boot:spring-boot-starter-web')

//    When I'm trying to run it with my JAR it doesn't work
    implementation("pl.mplan:web-common:1.0")

    compile group: 'org.javassist', name: 'javassist', version: '3.23.2-GA'
    compile group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'

    runtimeOnly('org.postgresql:postgresql')
    compileOnly('org.projectlombok:lombok')
    testImplementation('org.springframework.boot:spring-boot-starter-test')

    compile("com.querydsl:querydsl-core:4.2.1")
    compile("com.querydsl:querydsl-jpa:4.2.1")
    compile("com.querydsl:querydsl-apt:4.2.1:jpa")

}

compileJava {
    options.annotationProcessorGeneratedSourcesDirectory = file("$projectDir/generated/java")
}

idea {
    module {
        sourceDirs += file("$projectDir/generated/java")
    }
}

When I'm trying to run app with gradle bootRun task here's what I get:

17:55:32.169 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Retrieved dependent beans for bean 'objectPostProcessor': [org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration]
17:55:32.169 [main] DEBUG org.springframework.beans.factory.support.DisposableBeanAdapter - Invoking destroy() on bean with name 'objectPostProcessor'
17:55:32.175 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:386)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230)
    at pl.mplan.brew.it.BrewItBackendApplication.main(BrewItBackendApplication.java:12)
Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getWebServerFactory(ServletWebServerApplicationContext.java:204)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:178)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:152)
    ... 8 common frames omitted

(I'm using gradle 4.8 and shadow plugin 4.0.4)

Any ideas how to fix it? Thanks in advance!

PMaciek
  • 11
  • 1
  • *... extract all of spring-boot-starters to a separate app, pack all of it into a single JAR and then deploy it to local nexus artifacts repository, so I can import it and all of its dependencies ...* - This is a weird thing to do. – barfuin Sep 21 '19 at 18:51
  • @barfuin Maybe - I'm just trying to solve the task I was given at work. My boss wants to have this separate module with starters dependencies, some configuration and utilities classes in common, reusable module packed into single jar, so we can import use it in many apps. – PMaciek Sep 22 '19 at 07:58
  • Why does it has to be a fat jar, and not just a normal one with transitive dependencies declared in the POM? – Bjørn Vester Sep 23 '19 at 09:24
  • I want it to be a fat jar to provide all of classes/configurations etc coming from spring boot starter dependencies. – PMaciek Sep 23 '19 at 10:10
  • I still don't see why you need a fat jar for that. What is it that you can't accomplish with a normal one? It can contain all your custom classes and configuration files, and transitive dependencies such as Spring Boot starters will just be declared in the POM file. – Bjørn Vester Sep 24 '19 at 10:19

0 Answers0