How to maven-publish a Gradle project JAR with provided scope - maven

Given a Gradle web project that is to be published as a JAR (so that it can be a dependency of another Gradle web project, which has a different release cycle).
The maven-publish plugin is used:
apply plugin: 'war'
apply plugin: 'maven'
apply plugin: 'maven-publish'
The web project has a providedCompile dependency:
providedCompile 'javax.servlet:javax.servlet-api:3.0.1'
A jar is published using mavenJava:
publishing {
publications {
// mavenJava publishes a jar file
mavenJava(MavenPublication) {
from components.java
}
}
repositories {
mavenLocal()
}
}
The problem is that javax.servlet-api has a runtime scope in the resulting Maven POM:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>runtime</scope>
</dependency>
Runtime scope makes no sense for the servlet-api, it is even harmful. How can the scope be set to provided in the pom.xml?

With the help of pom.withXml (see this Gradle sample) it's possible to transform Gradle's providedCompile into provided scope for Maven's POM:
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
// providedCompile -> provided scope
pom.withXml {
asNode().dependencies.'*'.findAll() {
it.scope.text() == 'runtime' && project.configurations.providedCompile.allDependencies.find { dep ->
dep.name == it.artifactId.text()
}
}.each() {
it.scope*.value = 'provided'
}
}
}
}
repositories {
mavenLocal()
}
}
What the pom.withXml section does is going through all dependencies of type providedCompile within the Gradle project configuration and changing the scope to be written into the Maven pom.xml from runtime to provided.
The generated pom.xml now has the provided scope set for the javax.servlet-api:
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
[...]
<dependencies>
[...]
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

Related

Dependency management in gradle with mavenBom

I have a java library that is imported in gradle like this
sourceControl {
gitRepository("git#github.com/mytest/commonslib.git") {
producesModule("com.lib:commonslib")
}
}
the lib contains a pom.xml with all dependencies.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lib</groupId>
<artifactId>commonslib</artifactId>
<version>0.1.10</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
...
now i would like to import this pom to handle the dependend libraries.
But it does not work when i used it like this.
dependencyManagement {
imports {
mavenBom 'com.lib:commonslib:0.1.10'
}
}
I got the error: Could not resolve commonslib.pom (project :commonslib). Any hint whats wrong? Is it even possible to use producesModule and mavenBom in compbination?

Could not resolve dependencies for project ... : Could not find artifact

My project has 3 submodules and it's project structure like the image below.
I am going to build moyamo-api-server [moyamo] by both maven and gradle.
moyamo has moyamo-event-domain and moyamo-common as dependencies, and moyamo-event-domain is one of submodules of moyamo-event-module. After I started moyamo-api-server in intellij as a maven project, though it has also gradle setting, I imported moyamo-common by importing its pom.xml (moyamo-common also has gradle), and imported moyamo-event-domain by importing build.gradle (moyamo-event-module and moyamo-event-domain don't have pom.xml). Importing meant here that "File/New/Module from Existing Source".
Basically when I reload maven in pom of moyamo-api-server, I cannot resolve net.infobank.moyamo:moyamo-event-domain:0.0.1-SNAPSHOT. After comment dependency of moyamo-event-domain in pom.xml of moyamo-api-server, pom sync works.
But when I run "mvn clean install" on terminal of moyamo-api-server, I get the error [ERROR] Failed to execute goal on project moyamo: Could not resolve dependencies for project net.infobank:moyamo:pom:0.0.1-SNAPSHOT: Could not find artifact net.infobank:moyamo-common:jar:0.0.1-SNAPSHOT -> [Help 1], and warning [WARNING] The POM for net.infobank:moyamo-common:jar:0.0.1-SNAPSHOT is missing, no dependency information available
I checked that moyamo has moyamo-common as a dependency at project structure.
It's the description so far for maven build.
When I tried to build by gradle, encountered this error.
I share POM of moyamo-api-server and 3 gradles.
moyamo-api-server / 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>net.infobank</groupId>
<artifactId>moyamo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>moyamo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
<org.mapstruct.version>1.3.1.Final</org.mapstruct.version>
<org.projectlombok.version>1.18.12</org.projectlombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
...
<dependency>
<groupId>net.infobank</groupId>
<artifactId>moyamo-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!-- springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- springfox-swager-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>net.infobank.moyamo</groupId>-->
<!-- <artifactId>moyamo-event-domain</artifactId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- <systemPath>${basedir}/../moyamo-event-module/moyamo-event-domain/build/libs/moyamo-event-domain-1.0-SNAPSHOT.jar</systemPath>-->
<!--<!– <systemPath>${basedir}/target/lib/moyamo-event-domain-1.0-SNAPSHOT.jar</systemPath>–>-->
<!-- </dependency>-->
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
<!-- moyamo-event-domain dependency ./lib 에 추가.-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<includeScope>system</includeScope>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<configuration>
<rules>
<dependencyConvergence/>
</rules>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.8</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-asciidoctor</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs
</outputDirectory>
<resources>
<resource>
<directory>
${project.build.directory}/generated-docs
</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<!--rest docs end -->
</plugins>
</build>
</project>
moyamo-api-server / build.gradle
jar { enabled = false }
bootJar { enabled = true }
bootRun {enabled = true}
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
}
sourceCompatibility = '1.8'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-amqp'
implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j:1.0.2.RELEASE'
implementation 'org.springframework.amqp:spring-rabbit-test'
testImplementation 'org.springframework.amqp:spring-rabbit-test'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
developmentOnly "org.springframework.boot:spring-boot-devtools"
testImplementation 'org.springframework.security:spring-security-test'
implementation 'org.hibernate:hibernate-spatial'
implementation 'org.hibernate:hibernate-ehcache'
implementation 'org.hibernate:hibernate-search-orm'
implementation 'org.hibernate:hibernate-search-elasticsearch'
implementation 'org.apache.commons:commons-lang3:3.11'
implementation 'com.auth0:java-jwt:3.10.2'
implementation 'commons-io:commons-io:2.6'
implementation 'io.findify:s3mock_2.12:0.2.5'
implementation 'io.springfox:springfox-swagger-ui:2.9.2'
implementation 'io.springfox:springfox-swagger2:2.9.2'
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:2.2.2.RELEASE'
runtimeOnly 'mysql:mysql-connector-java:8.0.19'
testImplementation 'junit:junit:4.12'
implementation 'com.sksamuel.scrimage:scrimage-core:4.0.5'
compileOnly 'org.projectlombok:lombok:1.18.12'
annotationProcessor 'org.projectlombok:lombok:1.18.12'
implementation 'com.google.code.gson:gson:2.8.6'
}
moyamo-common / build.gradle
bootJar { enabled = false }
jar { enabled = true }
/*
* This file was generated by the Gradle 'init' task.
*/
ext {
set('springCloudVersion', "2020.0.1")
set('mapstructVersion', "1.3.1.Final")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.hibernate:hibernate-search-orm'
implementation 'org.hibernate:hibernate-ehcache'
implementation 'org.hibernate:hibernate-search-elasticsearch'
implementation 'org.hibernate:hibernate-spatial'
implementation 'com.bedatadriven:jackson-datatype-jts:2.2'
implementation "org.mapstruct:mapstruct"
annotationProcessor "org.mapstruct:mapstruct-processor"
testAnnotationProcessor "org.mapstruct:mapstruct-processor:"
implementation 'io.github.resilience4j:resilience4j-micrometer:1.1.0'
implementation 'io.github.resilience4j:resilience4j-metrics:1.1.0'
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:2.2.2.RELEASE'
implementation 'io.micrometer:micrometer-registry-prometheus:1.2.0'
implementation 'com.auth0:java-jwt:3.10.2'
implementation 'commons-io:commons-io:2.6'
implementation 'io.findify:s3mock_2.12:0.2.5'
implementation 'org.springframework.cloud:spring-cloud-aws-context:2.2.6.RELEASE'
implementation 'io.springfox:springfox-swagger-ui:2.9.2'
implementation 'io.springfox:springfox-swagger2:2.9.2'
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.apache.shiro:shiro-all:1.2.3'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.11.0'
implementation 'org.apache.commons:commons-lang3:3.11'
implementation 'com.sksamuel.scrimage:scrimage-core:4.0.5'
implementation 'org.apache.poi:poi:4.1.2'
runtimeOnly 'mysql:mysql-connector-java:8.0.19'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.amqp:spring-rabbit-test'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'junit:junit:4.12'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
moyamo-event-module / build.gradle
bootJar { enabled = false }
jar { enabled = true }
/*
* This file was generated by the Gradle 'init' task.
*/
ext {
set('springCloudVersion', "2020.0.1")
set('mapstructVersion', "1.3.1.Final")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.hibernate:hibernate-search-orm'
implementation 'org.hibernate:hibernate-ehcache'
implementation 'org.hibernate:hibernate-search-elasticsearch'
implementation 'org.hibernate:hibernate-spatial'
implementation 'com.bedatadriven:jackson-datatype-jts:2.2'
implementation "org.mapstruct:mapstruct"
annotationProcessor "org.mapstruct:mapstruct-processor"
testAnnotationProcessor "org.mapstruct:mapstruct-processor:"
implementation 'io.github.resilience4j:resilience4j-micrometer:1.1.0'
implementation 'io.github.resilience4j:resilience4j-metrics:1.1.0'
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:2.2.2.RELEASE'
implementation 'io.micrometer:micrometer-registry-prometheus:1.2.0'
implementation 'com.auth0:java-jwt:3.10.2'
implementation 'commons-io:commons-io:2.6'
implementation 'io.findify:s3mock_2.12:0.2.5'
implementation 'org.springframework.cloud:spring-cloud-aws-context:2.2.6.RELEASE'
implementation 'io.springfox:springfox-swagger-ui:2.9.2'
implementation 'io.springfox:springfox-swagger2:2.9.2'
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.apache.shiro:shiro-all:1.2.3'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.11.0'
implementation 'org.apache.commons:commons-lang3:3.11'
implementation 'com.sksamuel.scrimage:scrimage-core:4.0.5'
implementation 'org.apache.poi:poi:4.1.2'
runtimeOnly 'mysql:mysql-connector-java:8.0.19'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.amqp:spring-rabbit-test'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'junit:junit:4.12'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
rootProject.name = 'moyamo-event-module'
include 'moyamo-event-domain'
include 'moyamo-event-server'
moyamo-event-module / moyamo-event-domain / build.gradle
plugins {
id 'java'
}
jar { enabled = true }
//bootJar { enabled = false}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
compileOnly 'org.projectlombok:lombok:1.18.10'
annotationProcessor 'org.projectlombok:lombok:1.18.10'
}
test {
useJUnitPlatform()
}
I hope to have moyamo-api-server built by both Maven and Gradle.
The weird thing is that in moyamo-parent (root project), which has moyamo-api-server as a dependency, I can build entire project successfully by run "./gradlew clean build -x test" and get each project built by jar or war.
moyamo-parent has only gradle.
But moyamo-api-server cannot be built indenpendently.
So I add moyamo-parent gradle here for clear understanding my trouble.
moyamo-parent / build.grale & settings.gradle
buildscript {
ext {
springBootVersion = '2.4.7'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'io.spring.dependency-management'
allprojects {
group = 'net.infobank.moyamo'
version = '0.0.1-SNAPSHOT'
}
repositories {
mavenCentral()
}
subprojects {
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'java'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "2020.0.3")
set('mapstructVersion', "1.3.1.Final")
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-amqp'
implementation 'org.springframework.boot:spring-boot-starter-validation'
runtime("org.springframework.boot:spring-boot-properties-migrator")
compile("org.mapstruct:mapstruct:${mapstructVersion}")
compileOnly("org.mapstruct:mapstruct-processor:${mapstructVersion}")
annotationProcessor("org.mapstruct:mapstruct-processor:${mapstructVersion}")
implementation group: 'com.drewnoakes', name: 'metadata-extractor', version: '2.16.0'
compileOnly 'org.projectlombok:lombok:1.18.12'
annotationProcessor 'org.projectlombok:lombok:1.18.12'
implementation 'org.hibernate:hibernate-spatial:5.2.14.Final'
implementation 'org.hibernate:hibernate-ehcache:5.4.13.Final'
implementation 'org.hibernate:hibernate-search-orm:5.11.9.Final'
implementation 'org.hibernate:hibernate-search-elasticsearch:5.11.9.Final'
implementation 'org.elasticsearch.client:elasticsearch-rest-client:6.8.12'
implementation 'org.elasticsearch.client:elasticsearch-rest-client-sniffer:5.6.16'
}
task initSourceFolders {
sourceSets*.java.srcDirs*.each {
if (!it.exists()) {
it.mkdirs()
}
}
sourceSets*.resources.srcDirs*.each {
if (!it.exists()) {
it.mkdirs()
}
}
}
}
project(':moyamo') {
dependencies {
compile project(':moyamo-common')
compile project(':moyamo-event-domain')
implementation 'org.springframework.boot:spring-boot-starter-amqp'
}
}
project(':moyamo-admin') {
dependencies {
compile project(':moyamo-common')
implementation 'org.springframework.boot:spring-boot-starter-amqp'
}
}
project(':moyamo-scheduler') {
dependencies {
compile project(':moyamo-common')
compile project(':moyamo-event-domain')
implementation 'org.springframework.boot:spring-boot-starter-amqp'
}
}
//def common = project(':moyamo-common')
//def domain = project(':moyamo-event-domain')
/*configure ([common]) {
apply plugin: "io.spring.dependency-management"
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.12'
annotationProcessor 'org.projectlombok:lombok:1.18.12'
}
}*/
rootProject.name = 'moyamo-parent'
include ':moyamo', //moyamo-api-server
':moyamo-event-domain',
':moyamo-common',
':moyamo-admin',
':moyamo-scheduler'
for (project in rootProject.children) {
project.projectDir = file("../moyamo-event-module/${project.name}")
}
project(':moyamo').setProjectDir(new File(settingsDir, '../moyamo-api-server'))
project(':moyamo-common').setProjectDir(new File(settingsDir, '../moyamo-common'))
project(':moyamo-admin').setProjectDir(new File(settingsDir, '../moyamo-admin'))
project(':moyamo-scheduler').setProjectDir(new File(settingsDir, '../moyamo-scheduler'))
I need your helps, thanks in advance.

How to allow spring boot applications to use custom jar having spring cloud dependency

I have many spring boot microservices and I have developed a new project that has Spring-Vault as a dependency. This new project (say vault-client-spring) is developed in order to have common configuration for setting up of Vault and use it in all of the microservices and I have published the jar in private maven hosted repository in my organization.
My problem is when I add this jar as dependency in any microservices, the application is not starting throwing the following error. The Spring-Cloud-Vault dependencies are not imported to my consuming projects. I've also added the necessary properties requrired starting with prefix spring.cloud.vault in bootstrap.yml file.
Here's my build.gradle file for vault-client-spring.
group = 'com.mygroup'
version = '0.0.1'
buildscript {
ext {
springBootVersion = '2.4.4'
springDepsMgmtVersion = '1.0.11.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
classpath "io.spring.gradle:dependency-management-plugin:${springDepsMgmtVersion}"
}
}
apply plugin: 'java-library'
apply plugin: 'idea'
apply plugin: 'maven-publish'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
bootJar {
enabled = false
}
jar {
archivesBaseName = 'vault-client-spring'
enabled = true
}
ext {
springCloudVersion = '2020.0.2'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-vault-config'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier('sources')
from sourceSets.main.allSource
}
publishing {
publications {
mavenJava(MavenPublication) {
artifact jar
artifact sourcesJar
}
}
repositories {
maven {
credentials {
username 'PRIVATE-USER'
password 'PRIVATE-PASSWORD'
}
url 'PRIVATE MAVEN URL'
}
}
}
Here's the build.gradle file for a microservice using this jar.
plugins {
id 'org.springframework.boot' version '2.4.3'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.mygroup'
version = ''
sourceCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
maven { url 'PRIVATE MAVEN URL' }
}
bootJar {
setArchivesBaseName("microservice-one")
version("")
}
dependencies {
implementation 'com.mygroup:vault-client-spring:0.0.1' // here's the dependency
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
compileJava {
compileJava.inputs.files(processResources)
}
test {
useJUnitPlatform()
}
The generated POM file.
<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.mygroup</groupId>
<artifactId>vault-client-spring</artifactId>
<version>0.0.1</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.2</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.4</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
</project>
The error I'm facing is as follows..
Caused by: java.io.FileNotFoundException: class path resource [org/springframework/vault/config/AbstractVaultConfiguration.class] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180) ~[spring-core-5.3.4.jar:5.3.4]
at org.springframework.core.type.classreading.SimpleMetadataReader.getClassReader(SimpleMetadataReader.java:55) ~[spring-core-5.3.4.jar:5.3.4]
at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:49) ~[spring-core-5.3.4.jar:5.3.4]
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:103) ~[spring-core-5.3.4.jar:5.3.4]
at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.createMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:86) ~[spring-boot-2.4.3.jar:2.4.3]
at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.getMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:73) ~[spring-boot-2.4.3.jar:2.4.3]
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:81) ~[spring-core-5.3.4.jar:5.3.4]
at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:696) ~[spring-context-5.3.4.jar:5.3.4]
at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getSuperClass(ConfigurationClassParser.java:1010) ~[spring-context-5.3.4.jar:5.3.4]
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:341) ~[spring-context-5.3.4.jar:5.3.4]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:250) ~[spring-context-5.3.4.jar:5.3.4]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:199) ~[spring-context-5.3.4.jar:5.3.4]
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:304) ~[spring-context-5.3.4.jar:5.3.4]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:250) ~[spring-context-5.3.4.jar:5.3.4]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:207) ~[spring-context-5.3.4.jar:5.3.4]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:175) ~[spring-context-5.3.4.jar:5.3.4]
... 14 common frames omitted
How to solve this error? I'm working for the first time in Spring Cloud native projects
I found it myself. Since I'm developing as "library", I have to allow Spring-Vault dependencies to get included in consuming applications. As per Gradle's java-library plugin, I used api dependency. The consuming applications can able to access and bootstrap them.

Gradle mapping for `compile project(:dependency)` maven dependencies?

I'm having multi-project Gradle config:
-- root (folder 'gradle_test')
L--wrapper (depends on some 3rd-party maven libs)
L--module1 (depends on wrapper)
L--app
I need module1 jar (and wrapper jar as transitive dependency) to be published in local maven repo.
root build.gradle:
// for maven
ext {
groupId = 'mygroup'
version = '3.0'
}
wrapper build.gradle:
apply plugin: 'maven'
...
// maven pom
install {
repositories.mavenInstaller {
pom.groupId = rootProject.ext.groupId
pom.artifactId = 'wrapper'
pom.version = rootProject.ext.version
}
}
module1 build.gradle:
dependencies {
compile project(':wrapper')
...
}
// maven pom
install {
repositories.mavenInstaller {
pom.groupId = rootProject.ext.groupId
pom.artifactId = 'module1'
pom.version = rootProject.ext.version
}
}
Howeven when installing module1 into local maven cache i can see dependency to 'wrapper' module is generated incorrectly (version is not specified). module1 pom.xml in repo:
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>module1</artifactId>
<version>3.0</version>
<dependencies>
<dependency>
<groupId>gradle_test</groupId> // error 1: gradle project name (instead of overriden mvn groupId)
<artifactId>wrapper</artifactId>
<version>unspecified</version> // error 2: not set at all
<scope>compile</scope>
</dependency>
</dependencies>
</project>
In other words Gradle does not use maven module groupId/artifactId/version for maven dependencies mapped from compile project(:wrapper) declaration.
How can i do/fix it?
I had to write for wrapper and module1:
// mvn
group = rootProject.ext.groupId
version = rootProject.ext.version
and you can remove:
install {
repositories.mavenInstaller {
...
}
}
since Gradle will use project.group as mvn module groupId and project.version as mvn module version:
https://docs.gradle.org/current/userguide/maven_plugin.html#sec:maven_pom_generation

Not able to register a service as Eureka Client

I'm trying to register a Microservice as Eureka Client in order to discover other Microservices, however, I follow the tutorial but nothing shows up in the Eureka Server. Below are code snippets:
My demo application: a spring boot application running on localhost:9001, I want it become a Eureka Client, i.e., register itself as an instance and meanwhile has ability to discover other instances (I used the generic #EnableDiscoveryClientannotation and Spring Netflix Eureka is on the classpath):
#RestController
#SpringBootApplication
#EnableDiscoveryClient
public class DemoApplication {
#RequestMapping("/")
String home() {
return "This is a Demo project";
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
application.yml:
server:
port: 9001
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
The Eureka Server should be no problem since I have another Miscroservice running on localhost:8080 is successfully registered in the server. Just in case here is the application.yml for the Eureka Server:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
Anyone see any problems here?
The important thing is select the right import. I lost hours before realizing that:
This is the bare dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-eureka-client</artifactId>
</dependency>
This is the starter pack dependency wanted in most case:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
If you import the bare dependency, no errors or logs will show up but the service will not register to Eureka server.
Bottom line, make sure to double double check the dependencies: maybe you need the "starter pack" dependency for a Spring boot component.
Problem solved, I didn't include dependency 'com.netflix.eureka:eureka-client:1.1.147' in my build.gradle.
Do the following in pom.xml
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
In Spring boot configuration do the following:
#EnableDiscoveryClient
#SpringBootApplication
public class ServiceApplication
service.application.properties
spring.application.name=rating-data-service
server.port=8083
eureka.client.eureka-server-port=8761 // on which port server is running
#eureka.client.register-with-eureka=false
#eureka.client.fetch-registry=false
server.application.properties
server.port=8761
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
Add above lined in your pom.xml and if you are using gradle use below code :
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka', version: '1.4.6.RELEASE'
Inside add pom.xml spring-cloud-netflix-eureka-client
Client build.gradle needs to be somewhat like below one
plugins {
id 'org.springframework.boot' version '2.2.2.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
}
ext {
set('springCloudVersion', "Hoxton.SR1")
}
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
test {
useJUnitPlatform()
}
application.properties file of client should contain following content -
spring.application.name=movie-catalog-service // Your service name
server.port=8081 // on which port you are running
eureka.client.eureka-server-port=8761 // on which port server is running
Eureka Server build.gradle needs to be somewhat like below one
plugins {
id 'org.springframework.boot' version '2.2.5.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "Hoxton.SR3")
}
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
test {
useJUnitPlatform()
}
application.properties of Eureka Server file should be somewhat like this
server.port=8761 // port on which server is running
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
Reference : https://spring.io/guides/gs/service-registration-and-discovery/
If we include both starter one and without starter as seen in dependency tree netflix-eureka-client is missing eureka-client itself.
So, adding missing dependency make sense. I think netflix-eureka-client should depend eureka-client normally, but not for some reason :)
<dependency>
<groupId>com.netflix.eureka</groupId>
<artifactId>eureka-client</artifactId>
</dependency>
Try to use #EnableEurekaServer and this dependencies for eureka application:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
And use #EnableEurekaClient for eureka client applications with dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.eureka</groupId>
<artifactId>eureka-client</artifactId>
</dependency>
And say for client application where is eureka located
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
screenshot

Resources