Problems with Spring Boot + Spock + Rest Assured - spring-boot

I have a simple test with Spring Boot, Spock and Rest Assured.
package com.xxx.mako.rrhh.persona.infrastructure.controller
import com.xxx.mako.IntegrationTest
import com.xxx.mako.MakoApplication
import io.restassured.http.ContentType
import org.junit.experimental.categories.Category
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.context.TestPropertySource
import org.springframework.test.context.jdbc.Sql
import spock.lang.Specification
import io.restassured.RestAssured
import io.restassured.builder.ResponseSpecBuilder
import static io.restassured.RestAssured.*
import static org.hamcrest.Matchers.*
#ActiveProfiles("test")
#SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
classes = MakoApplication.class
)
#TestPropertySource(locations = "classpath:application-test.yml")
#Category(IntegrationTest.class)
#Sql(scripts = ["classpath:/createTablePersona.sql", "classpath:/insertTablePersona.sql"])
class PersonaRestAssuredSpec extends Specification {
final static URL_REST_SERVICE = "/mako/api/rest/personas/v1"
final static validToken = createHeaders("admin", "admin00")
final static invalidToken = createHeaders("dummy", "dummy")
final static SC_OK = 200
final static SC_UNAUTHORIZED = 401
#Value('\${server.http.port}')
private int port
def setup() throws Exception {
RestAssured.port = port
}
def "findById"() {
given:
def request = given().accept(ContentType.JSON).header("Authorization", token)
when: "A rest for obtain the Persona object with idPersona, token"
def response = request.with().get(URL_REST_SERVICE + "/" + idPersona)
then: "We expected status and specification like in the parameterized list in where clause"
response.then().statusCode(status).spec(specification)
where:
idPersona || token || status || specification
1000 || invalidToken || SC_UNAUTHORIZED || expect().body("error", equalTo("Unauthorized"))
2 || validToken || SC_OK || expect().body("id", equalTo("2"))
}
private static String createHeaders(String username, String password) {
String auth = username + ":" + password
String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes("utf-8"))
String authHeader = "Basic " + encodedAuth
return authHeader
}
}
When I execute the tests I obtain this error:
Condition failed with Exception:
response.then().statusCode(status).spec(specification)
| | | | | |
| | | 401 | <io.restassured.internal.ResponseSpecificationImpl#6f6a7463 expectedStatusCode=null expectedStatusLine=null bodyMatchers=io.restassured.assertion.BodyMatcherGroup#1e53135d assertionClosure=io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure#7674a051 headerAssertions=[] cookieAssertions=[] requestSpecification=io.restassured.internal.RequestSpecificationImpl#3a7704c contentType=null restAssuredResponse=null bodyRootPath= rpr=io.restassured.internal.ResponseParserRegistrar#6754ef00 config=io.restassured.config.RestAssuredConfig#619bd14c response=null expectedResponseTime=null responseLogDetail=null forceDisableEagerAssert=false contentParser=null logRepository=io.restassured.internal.log.LogRepository#323e8306>
| | | groovy.lang.MissingMethodException: No signature of method: io.restassured.internal.ContentParser.parse() is applicable for argument types: (io.restassured.internal.RestAssuredResponseImpl, io.restassured.internal.ResponseParserRegistrar...) values: [io.restassured.internal.RestAssuredResponseImpl#51efdb72, io.restassured.internal.ResponseParserRegistrar#6754ef00, ...]
| | | Possible solutions: wait(), grep(), any()
| | | at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure.validate(ResponseSpecificationImpl.groovy:478)
| | | at io.restassured.internal.ResponseSpecificationImpl.validate(ResponseSpecificationImpl.groovy:92)
| | | at io.restassured.internal.ValidatableResponseOptionsImpl.spec(ValidatableResponseOptionsImpl.java:288)
| | | at io.restassured.internal.ValidatableResponseImpl.spec(ValidatableResponseImpl.groovy:76)
| | | at com.xxx.mako.rrhh.persona.infrastructure.controller.PersonaRestAssuredSpec.findById(PersonaRestAssuredSpec.groovy:47)
| | <io.restassured.internal.ValidatableResponseImpl#76cbee13 responseSpec=io.restassured.internal.ResponseSpecificationImpl#59d09ff3 extractableResponse=io.restassured.internal.RestAssuredResponseImpl#51efdb72 response=io.restassured.internal.RestAssuredResponseImpl#51efdb72 config=io.restassured.config.RestAssuredConfig#619bd14c>
| <io.restassured.internal.ValidatableResponseImpl#76cbee13 responseSpec=io.restassured.internal.ResponseSpecificationImpl#59d09ff3 extractableResponse=io.restassured.internal.RestAssuredResponseImpl#51efdb72 response=io.restassured.internal.RestAssuredResponseImpl#51efdb72 config=io.restassured.config.RestAssuredConfig#619bd14c>
<io.restassured.internal.RestAssuredResponseImpl#51efdb72 logRepository=io.restassured.internal.log.LogRepository#7bc6b117 groovyResponse=io.restassured.internal.RestAssuredResponseOptionsGroovyImpl#2de07c57>
at com.xxx.mako.rrhh.persona.infrastructure.controller.PersonaRestAssuredSpec.findById(PersonaRestAssuredSpec.groovy:47)
Caused by: groovy.lang.MissingMethodException: No signature of method: io.restassured.internal.ContentParser.parse() is applicable for argument types: (io.restassured.internal.RestAssuredResponseImpl, io.restassured.internal.ResponseParserRegistrar...) values: [io.restassured.internal.RestAssuredResponseImpl#51efdb72, io.restassured.internal.ResponseParserRegistrar#6754ef00, ...]
Possible solutions: wait(), grep(), any()
at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure.validate(ResponseSpecificationImpl.groovy:478)
at io.restassured.internal.ResponseSpecificationImpl.validate(ResponseSpecificationImpl.groovy:92)
at io.restassured.internal.ValidatableResponseOptionsImpl.spec(ValidatableResponseOptionsImpl.java:288)
at io.restassured.internal.ValidatableResponseImpl.spec(ValidatableResponseImpl.groovy:76)
... 1 more
Condition failed with Exception:
response.then().statusCode(status).spec(specification)
| | | | | |
| | | 200 | <io.restassured.internal.ResponseSpecificationImpl#7de43652 expectedStatusCode=null expectedStatusLine=null bodyMatchers=io.restassured.assertion.BodyMatcherGroup#7fe0ca60 assertionClosure=io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure#fdf029a headerAssertions=[] cookieAssertions=[] requestSpecification=io.restassured.internal.RequestSpecificationImpl#63896cf7 contentType=null restAssuredResponse=null bodyRootPath= rpr=io.restassured.internal.ResponseParserRegistrar#3f838072 config=io.restassured.config.RestAssuredConfig#619bd14c response=null expectedResponseTime=null responseLogDetail=null forceDisableEagerAssert=false contentParser=null logRepository=io.restassured.internal.log.LogRepository#46c9ee28>
| | | groovy.lang.MissingMethodException: No signature of method: io.restassured.internal.ContentParser.parse() is applicable for argument types: (io.restassured.internal.RestAssuredResponseImpl, io.restassured.internal.ResponseParserRegistrar...) values: [io.restassured.internal.RestAssuredResponseImpl#263e512e, io.restassured.internal.ResponseParserRegistrar#3f838072, ...]
| | | Possible solutions: wait(), grep(), any()
| | | at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure.validate(ResponseSpecificationImpl.groovy:478)
| | | at io.restassured.internal.ResponseSpecificationImpl.validate(ResponseSpecificationImpl.groovy:92)
| | | at io.restassured.internal.ValidatableResponseOptionsImpl.spec(ValidatableResponseOptionsImpl.java:288)
| | | at io.restassured.internal.ValidatableResponseImpl.spec(ValidatableResponseImpl.groovy:76)
| | | at com.xxx.mako.rrhh.persona.infrastructure.controller.PersonaRestAssuredSpec.findById(PersonaRestAssuredSpec.groovy:47)
| | <io.restassured.internal.ValidatableResponseImpl#7c680fe1 responseSpec=io.restassured.internal.ResponseSpecificationImpl#288b8663 extractableResponse=io.restassured.internal.RestAssuredResponseImpl#263e512e response=io.restassured.internal.RestAssuredResponseImpl#263e512e config=io.restassured.config.RestAssuredConfig#619bd14c>
| <io.restassured.internal.ValidatableResponseImpl#7c680fe1 responseSpec=io.restassured.internal.ResponseSpecificationImpl#288b8663 extractableResponse=io.restassured.internal.RestAssuredResponseImpl#263e512e response=io.restassured.internal.RestAssuredResponseImpl#263e512e config=io.restassured.config.RestAssuredConfig#619bd14c>
<io.restassured.internal.RestAssuredResponseImpl#263e512e logRepository=io.restassured.internal.log.LogRepository#62c42a3 groovyResponse=io.restassured.internal.RestAssuredResponseOptionsGroovyImpl#6a8bcb64>
at com.xxx.mako.rrhh.persona.infrastructure.controller.PersonaRestAssuredSpec.findById(PersonaRestAssuredSpec.groovy:47)
Caused by: groovy.lang.MissingMethodException: No signature of method: io.restassured.internal.ContentParser.parse() is applicable for argument types: (io.restassured.internal.RestAssuredResponseImpl, io.restassured.internal.ResponseParserRegistrar...) values: [io.restassured.internal.RestAssuredResponseImpl#263e512e, io.restassured.internal.ResponseParserRegistrar#3f838072, ...]
Possible solutions: wait(), grep(), any()
at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure.validate(ResponseSpecificationImpl.groovy:478)
at io.restassured.internal.ResponseSpecificationImpl.validate(ResponseSpecificationImpl.groovy:92)
at io.restassured.internal.ValidatableResponseOptionsImpl.spec(ValidatableResponseOptionsImpl.java:288)
at io.restassured.internal.ValidatableResponseImpl.spec(ValidatableResponseImpl.groovy:76)
... 1 more
I have this dependencies in gradle:
testRuntimeClasspath - Runtime classpath of compilation 'test' (target (jvm)).
+--- javax.inject:javax.inject:1
+--- org.springdoc:springdoc-openapi-ui:1.3.9
| +--- org.springdoc:springdoc-openapi-webmvc-core:1.3.9
| | +--- org.springdoc:springdoc-openapi-common:1.3.9
| | | +--- org.springframework.boot:spring-boot-autoconfigure:2.2.6.RELEASE -> 2.4.1
| | | | \--- org.springframework.boot:spring-boot:2.4.1
| | | | +--- org.springframework:spring-core:5.3.2
| | | | | \--- org.springframework:spring-jcl:5.3.2
| | | | \--- org.springframework:spring-context:5.3.2
...
| | +--- org.junit.jupiter:junit-jupiter-api:5.7.0
| | | +--- org.junit:junit-bom:5.7.0 (*)
| | | +--- org.apiguardian:apiguardian-api:1.1.0
| | | +--- org.opentest4j:opentest4j:1.2.0
| | | \--- org.junit.platform:junit-platform-commons:1.7.0
| | | +--- org.junit:junit-bom:5.7.0 (*)
| | | \--- org.apiguardian:apiguardian-api:1.1.0
| | +--- org.junit.jupiter:junit-jupiter-params:5.7.0
| | | +--- org.junit:junit-bom:5.7.0 (*)
| | | +--- org.apiguardian:apiguardian-api:1.1.0
| | | \--- org.junit.jupiter:junit-jupiter-api:5.7.0 (*)
| | \--- org.junit.jupiter:junit-jupiter-engine:5.7.0
| | +--- org.junit:junit-bom:5.7.0 (*)
| | +--- org.apiguardian:apiguardian-api:1.1.0
| | +--- org.junit.platform:junit-platform-engine:1.7.0
| | | +--- org.junit:junit-bom:5.7.0 (*)
| | | +--- org.apiguardian:apiguardian-api:1.1.0
| | | +--- org.opentest4j:opentest4j:1.2.0
| | | \--- org.junit.platform:junit-platform-commons:1.7.0 (*)
| | \--- org.junit.jupiter:junit-jupiter-api:5.7.0 (*)
| +--- org.mockito:mockito-core:3.6.28
| | +--- net.bytebuddy:byte-buddy:1.10.18 -> 1.10.10
| | +--- net.bytebuddy:byte-buddy-agent:1.10.18
| | \--- org.objenesis:objenesis:3.1
| +--- org.mockito:mockito-junit-jupiter:3.6.28
| | +--- org.mockito:mockito-core:3.6.28 (*)
| | \--- org.junit.jupiter:junit-jupiter-api:5.4.2 -> 5.7.0 (*)
| +--- org.skyscreamer:jsonassert:1.5.0
| | \--- com.vaadin.external.google:android-json:0.0.20131108.vaadin1
| +--- org.springframework:spring-core:5.3.2 (*)
| +--- org.springframework:spring-test:5.3.2
| | \--- org.springframework:spring-core:5.3.2 (*)
| \--- org.xmlunit:xmlunit-core:2.7.0
+--- junit:junit:4.11
| \--- org.hamcrest:hamcrest-core:1.3 -> 2.2
| \--- org.hamcrest:hamcrest:2.2
+--- org.codehaus.groovy:groovy:3.0.7
+--- org.codehaus.groovy:groovy-json3.0.7 FAILED
+--- org.codehaus.groovy:groovy-xml3.0.7 FAILED
+--- org.spockframework:spock-core:2.0-M4-groovy-3.0
| +--- org.junit:junit-bom:5.7.0 (*)
| +--- org.codehaus.groovy:groovy:3.0.6 -> 3.0.7
| +--- org.junit.platform:junit-platform-engine -> 1.7.0 (*)
| +--- org.junit.platform:junit-platform-testkit -> 1.7.0
| | +--- org.junit:junit-bom:5.7.0 (*)
| | +--- org.apiguardian:apiguardian-api:1.1.0
| | +--- org.assertj:assertj-core:3.16.1 -> 3.18.1
| | +--- org.opentest4j:opentest4j:1.2.0
| | \--- org.junit.platform:junit-platform-launcher:1.7.0
| | +--- org.junit:junit-bom:5.7.0 (*)
| | +--- org.apiguardian:apiguardian-api:1.1.0
| | \--- org.junit.platform:junit-platform-engine:1.7.0 (*)
| +--- org.hamcrest:hamcrest:2.2
| +--- org.jetbrains:annotations:19.0.0
| +--- org.ow2.asm:asm:9.0
| +--- net.bytebuddy:byte-buddy:1.10.16 -> 1.10.10
| +--- cglib:cglib-nodep:3.3.0
| \--- org.objenesis:objenesis:3.1
+--- org.spockframework:spock-spring:2.0-M4-groovy-3.0
| +--- org.junit:junit-bom:5.7.0 (*)
| +--- org.codehaus.groovy:groovy:3.0.6 -> 3.0.7
| +--- org.spockframework:spock-core:2.0-M4-groovy-3.0 (*)
| +--- org.springframework:spring-test:4.3.5.RELEASE -> 5.3.2 (*)
| +--- org.springframework:spring-beans:4.3.5.RELEASE -> 5.3.2 (*)
| \--- org.springframework:spring-context:4.3.5.RELEASE -> 5.3.2 (*)
+--- org.hamcrest:hamcrest-core:2.2 (*)
+--- io.rest-assured:rest-assured:4.3.3
| +--- org.codehaus.groovy:groovy:3.0.7
| +--- org.codehaus.groovy:groovy-xml:3.0.7 -> 2.5.14
| | \--- org.codehaus.groovy:groovy:2.5.14 -> 3.0.7
| +--- org.apache.httpcomponents:httpclient:4.5.3 -> 4.5.13
| | +--- org.apache.httpcomponents:httpcore:4.4.13 -> 4.4.14
| | \--- commons-codec:commons-codec:1.11 -> 1.15
| +--- org.apache.httpcomponents:httpmime:4.5.3 -> 4.5.13
| | \--- org.apache.httpcomponents:httpclient:4.5.13 (*)
| +--- org.hamcrest:hamcrest:2.1 -> 2.2
| +--- org.ccil.cowan.tagsoup:tagsoup:1.2.1
| +--- io.rest-assured:json-path:4.3.3
| | +--- org.codehaus.groovy:groovy-json:3.0.7 -> 2.5.14
| | | \--- org.codehaus.groovy:groovy:2.5.14 -> 3.0.7
| | +--- org.codehaus.groovy:groovy:3.0.7
| | \--- io.rest-assured:rest-assured-common:4.3.3
| | +--- org.codehaus.groovy:groovy:3.0.7
| | \--- org.apache.commons:commons-lang3:3.11
| \--- io.rest-assured:xml-path:4.3.3
| +--- org.codehaus.groovy:groovy-xml:3.0.7 -> 2.5.14 (*)
| +--- org.codehaus.groovy:groovy:3.0.7
| +--- io.rest-assured:rest-assured-common:4.3.3 (*)
| +--- org.apache.commons:commons-lang3:3.11
| +--- org.ccil.cowan.tagsoup:tagsoup:1.2.1
| +--- jakarta.xml.bind:jakarta.xml.bind-api:2.3.3 (*)
| \--- com.sun.xml.bind:jaxb-impl:2.3.3
| \--- jakarta.xml.bind:jakarta.xml.bind-api:2.3.3 (*)
+--- io.rest-assured:rest-assured-common:4.3.3 (*)
+--- io.rest-assured:json-path:4.3.3 (*)
+--- io.rest-assured:xml-path:4.3.3 (*)
+--- net.bytebuddy:byte-buddy:1.10.10
\--- org.objenesis:objenesis:3.1
I don't understand why appear this versions:
| +--- org.codehaus.groovy:groovy-xml:3.0.7 -> 2.5.14 (*)
+--- org.codehaus.groovy:groovy-json:3.0.7 -> 2.5.14
When I explicity puts 3.0.7. I don't understand this such kind of problems between the last version of Rest Assured and Groovy 3.
Thanks in advance for a solution.

Just a guess, but it looks like you forgot the : between the artifactId and the version.
+--- org.codehaus.groovy:groovy-json3.0.7 FAILED
+--- org.codehaus.groovy:groovy-xml3.0.7 FAILED
org.codehaus.groovy:groovy-json3.0.7 should be org.codehaus.groovy:groovy-json:3.0.7.
Without an MCVE this is a much as I can glean from my cristal ball.

Yes was my fault I ommited in the gradle file the ':' in this dependencies.
Now:
testImplementation("org.codehaus.groovy:groovy:${groovyVersion}")
testImplementation("org.codehaus.groovy:groovy-json:${groovyVersion}")
testImplementation("org.codehaus.groovy:groovy-xml:${groovyVersion}")
testImplementation("org.spockframework:spock-core:${groovySpockVersion}")
testImplementation("org.spockframework:spock-spring:${groovySpockVersion}")
// optional dependencies for using Spock
Now the test runs ok:
> Configure project :
executing dev liquibase
executing int liquibase
executing pre liquibase
executing pro liquibase
> Task :test
com.xxx.mako.rrhh.persona.infrastructure.controller.PersonaRestAssuredSpec
? findById [idPersona: 1000, token: Basic ZHVtbXk6ZHVtbXk=, status: 401, specification: <io.restassured.internal.ResponseSpecificationImpl#30476d7a expectedStatusCode=null expectedStatusLine=null bodyMatchers=io.restassured.assertion.BodyMatcherGroup#4903a252 assertionClosure=io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure#339460d8 headerAssertions=[] cookieAssertions=[] requestSpecification=io.restassured.internal.RequestSpecificationImpl#7f3c8b4b contentType=null restAssuredResponse=null bodyRootPath= rpr=io.restassured.internal.ResponseParserRegistrar#41c555c config=io.restassured.config.RestAssuredConfig#50d966bf response=null expectedResponseTime=null responseLogDetail=null forceDisableEagerAssert=false contentParser=null logRepository=io.restassured.internal.log.LogRepository#40db5edc>, #0] (11s)
? findById [idPersona: 2, token: Basic YWRtaW46YWRtaW4wMA==, status: 200, specification: <io.restassured.internal.ResponseSpecificationImpl#6dc2c46b expectedStatusCode=null expectedStatusLine=null bodyMatchers=io.restassured.assertion.BodyMatcherGroup#cd2d276 assertionClosure=io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure#6f2591d5 headerAssertions=[] cookieAssertions=[] requestSpecification=io.restassured.internal.RequestSpecificationImpl#7d5a6a85 contentType=null restAssuredResponse=null bodyRootPath= rpr=io.restassured.internal.ResponseParserRegistrar#6c008d9 config=io.restassured.config.RestAssuredConfig#50d966bf response=null expectedResponseTime=null responseLogDetail=null forceDisableEagerAssert=false contentParser=null logRepository=io.restassured.internal.log.LogRepository#5ff3ba6a>, #1] (1.5s)
? findById (48.9s)
Thank you very much #Leonard Brünings

Related

Replace transitive dependency of Gradle plugin

The axion-release Gradle plugin has a dependency on the unmaintained com.jcraft:jsch:0.1.55 lib. The com.github.mwiede:jsch fork is a drop-in replacement for jcraft jsch providing the same namespace. How can I replace the plugin's dependency?
This does not appear to work:
buildscript {
dependencies {
classpath('pl.allegro.tech.build:axion-release-plugin:1.14.2') {
exclude group: 'com.jcraft', module: 'jsch'
}
}
configurations.classpath {
resolutionStrategy {
force 'com.github.mwiede:jsch:0.2.4'
}
}
}
This will remove com.jcraft.jsch from the classpath but that does not replace it with the maintained lib:
buildscript {
configurations.classpath {
resolutionStrategy {
exclude group: 'com.jcraft', module: 'jsch'
}
}
}
This also does not work
buildscript {
dependencies {
classpath('pl.allegro.tech.build:axion-release-plugin:1.14.2') {
exclude group: 'com.jcraft', module: 'jsch'
}
classpath 'com.github.mwiede:jsch:0.2.4'
}
I have tried substitution
buildscript {
dependencies {
classpath "pl.allegro.tech.build:axion-release-plugin:1.14.2"
}
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute module("com.jcraft:jsch") using module("com.github.mwiede:jsch:0.2.4") because "of https://stackoverflow.com/q/74355649/2290153"
}
}
}
and buildEnvironment gives:
classpath
\--- pl.allegro.tech.build:axion-release-plugin:1.14.2
+--- org.eclipse.jgit:org.eclipse.jgit:5.13.1.202206130422-r
| +--- com.googlecode.javaewah:JavaEWAH:1.1.13
| \--- org.slf4j:slf4j-api:1.7.30
+--- org.eclipse.jgit:org.eclipse.jgit.ssh.jsch:5.13.1.202206130422-r
| +--- org.eclipse.jgit:org.eclipse.jgit:5.13.1.202206130422-r (*)
| +--- com.jcraft:jsch:0.1.55 -> com.github.mwiede:jsch:0.2.4
| +--- com.jcraft:jzlib:1.1.1
| \--- org.slf4j:slf4j-api:1.7.30
+--- com.jcraft:jsch:0.1.55 -> com.github.mwiede:jsch:0.2.4
+--- com.jcraft:jsch.agentproxy.core:0.0.9
+--- com.jcraft:jsch.agentproxy.jsch:0.0.9
| +--- com.jcraft:jsch:0.1.49 -> com.github.mwiede:jsch:0.2.4
| \--- com.jcraft:jsch.agentproxy.core:0.0.9
+--- com.jcraft:jsch.agentproxy.sshagent:0.0.9
| \--- com.jcraft:jsch.agentproxy.core:0.0.9
+--- com.jcraft:jsch.agentproxy.pageant:0.0.9
| +--- com.jcraft:jsch.agentproxy.core:0.0.9
| +--- net.java.dev.jna:jna:4.1.0
| \--- net.java.dev.jna:jna-platform:4.1.0
| \--- net.java.dev.jna:jna:4.1.0
+--- com.jcraft:jsch.agentproxy.usocket-jna:0.0.9
| +--- com.jcraft:jsch.agentproxy.core:0.0.9
| +--- net.java.dev.jna:jna:4.1.0
| \--- net.java.dev.jna:jna-platform:4.1.0 (*)
+--- com.jcraft:jsch.agentproxy.usocket-nc:0.0.9
| \--- com.jcraft:jsch.agentproxy.core:0.0.9
+--- com.github.zafarkhaja:java-semver:0.9.0
+--- org.eclipse.jgit:org.eclipse.jgit.ssh.apache:5.13.1.202206130422-r
| +--- org.eclipse.jgit:org.eclipse.jgit:5.13.1.202206130422-r (*)
| +--- org.apache.sshd:sshd-osgi:2.7.0
| | +--- org.slf4j:slf4j-api:1.7.30
| | \--- org.slf4j:jcl-over-slf4j:1.7.30
| | \--- org.slf4j:slf4j-api:1.7.30
| +--- org.apache.sshd:sshd-sftp:2.7.0
| | +--- org.apache.sshd:sshd-core:2.7.0
| | | +--- org.apache.sshd:sshd-common:2.7.0
| | | | +--- org.slf4j:slf4j-api:1.7.30
| | | | \--- org.slf4j:jcl-over-slf4j:1.7.30 (*)
| | | +--- org.slf4j:slf4j-api:1.7.30
| | | \--- org.slf4j:jcl-over-slf4j:1.7.30 (*)
| | +--- org.slf4j:slf4j-api:1.7.30
| | \--- org.slf4j:jcl-over-slf4j:1.7.30 (*)
| +--- net.i2p.crypto:eddsa:0.3.0
| \--- org.slf4j:slf4j-api:1.7.30
+--- org.eclipse.jgit:org.eclipse.jgit.ui:5.13.1.202206130422-r
| \--- org.eclipse.jgit:org.eclipse.jgit:5.13.1.202206130422-r (*)
\--- org.eclipse.jgit:org.eclipse.jgit.gpg.bc:5.13.1.202206130422-r
+--- org.eclipse.jgit:org.eclipse.jgit:5.13.1.202206130422-r (*)
+--- org.bouncycastle:bcpg-jdk15on:1.69
| \--- org.bouncycastle:bcprov-jdk15on:1.69
+--- org.bouncycastle:bcprov-jdk15on:1.69
+--- org.bouncycastle:bcutil-jdk15on:1.69
| \--- org.bouncycastle:bcprov-jdk15on:1.69
+--- org.bouncycastle:bcpkix-jdk15on:1.69
| +--- org.bouncycastle:bcprov-jdk15on:1.69
| \--- org.bouncycastle:bcutil-jdk15on:1.69 (*)
\--- org.slf4j:slf4j-api:1.7.30
btw, the transitive dependency comes with jGit, and there was an issue using the fork at https://github.com/mwiede/jsch/issues/85, but it's solved now.

Find all directories that contain only hidden files and/or hidden directories

Issue
I have been struggling with writing a Bash command that is able to recursively search a directory and then return the paths of every sub-directory (up to a certain max-depth) that contains exclusively hidden files and/or hidden directories.
Visual Explanation
Consider the following File System excerpt:
+--- Root_Dir
| +--- Dir_A
| | +--- abc.txt
| | +--- 123.txt
| | +--- .hiddenfile
| | +--- .hidden_dir
| | | +--- normal_sub_file_1.txt
| | | +--- .hidden_sub_file_1.txt
| |
| +--- Dir_B
| | +--- abc.txt
| | +--- .hidden_dir
| | | +--- normal_sub_file_2.txt
| | | +--- .hidden_sub_file_2.txt
| |
| +--- Dir_C
| | +--- 123.txt
| | +--- program.c
| | +--- a.out
| | +--- .hiddenfile
| |
| +--- Dir_D
| | +--- .hiddenfile
| | +--- .another_hiddenfile
| |
| +--- Dir_E
| | +--- .hiddenfile
| | +--- .hidden_dir
| | | +--- normal_sub_file_3.txt # This is OK because its within a hidden directory, aka won't be checked
| | | +--- .hidden_sub_file_3.txt
| |
| +--- Dir_F
| | +--- .hidden_dir
| | | +--- normal_sub_file_4.txt
| | | +--- .hidden_sub_file_4.txt
Desired Output
The command I am looking for would output
./Root_Dir/Dir_D
./Root_Dir/Dir_E
./Root_Dir/Dir_F
Dir_D because it only contains hidden files.
Dir_E because it only contains a hidden file and a hidden directory at the level I am searching.
Dir_F because it only contains a hidden directory at the level I am searching.
Attempts
I have attempted to use the find command to get the results I am looking for but I can't seem to figure out what other command I need to pipe the output to or what other options I should be using.
I think the command that will work would look something like this:
$ find ./Root_Dir -mindepth 2 -maxdepth 2 -type d -name "*." -type -f -name "*." | command to see if these are the only files in that directory
Parsing find's output is not a good idea; -exec exists, and sh can do the filtering without breaking anything.
find . -type d -exec sh -c '
for d; do
for f in "$d"/*; do
test -e "$f" &&
continue 2
done
for f in "$d"/.[!.]* "$d"/..?*; do
if test -e "$f"; then
printf %s\\n "$d"
break
fi
done
done' sh {} +
You can adjust the depth using whatever extension your find provides for it.
Assuming this structure, you don't need find.
Adjust your pattern as needed.
for d in $ROOT_DIR/Dir_?/; do
lst=( $d* ); [[ -e "${lst[0]}" ]] && continue # normal files, skip
lst=( $d.* ); [[ -e "${lst[2]}" ]] || continue # NO hidden, so skip
echo "$d"
done
I rebuilt your file structure in my /tmp dir and saved this as tst, so
$: ROOT_DIR=/tmp ./tst
/tmp/Dir_D/
/tmp/Dir_E/
/tmp/Dir_F/
Note that the confirmation of hidden files uses "${lst[2]}" because the first 2 will always be . and .., which don't count.
You could probably use for d in $ROOT_DIR/*/.
I suspect this'll do for you. (mindepth=2, maxdepth=2)
If you needed deeper subdirectories (mindepth=3, maxdepth=3) you could add a level -
for d in $ROOT_DIR/*/*/
and/or both (mindepth=2, maxdepth=3)
for d in $ROOT_DIR/*/ $ROOT_DIR/*/*/
or if you didn't want a mindepth/maxdepth,
shopt -s globstar
for d in $ROOT_DIR/**/
This will work if your filenames contain no newlines.
find -name '.*' | awk -F/ -v OFS=/ '{ --NF } !a[$0]++'
Learn awk: https://www.gnu.org/software/gawk/manual/gawk.html

Get list (not tree) of dependencies with Gradle

I have a Gradle project with complex dependencies, which I can see using ./gradlew module-name:dependencies:
[...]
testRuntimeClasspath - Runtime classpath of source set 'test'.
+--- org.apache.logging.log4j:log4j-core -> 2.11.0
| \--- org.apache.logging.log4j:log4j-api:2.11.0
+--- com.google.guava:guava -> 20.0
+--- project :xxx
| +--- org.springframework:spring-tx -> 5.1.7.RELEASE
| | +--- org.springframework:spring-beans:5.1.7.RELEASE
| | | \--- org.springframework:spring-core:5.1.7.RELEASE
| | | \--- org.springframework:spring-jcl:5.1.7.RELEASE
| | \--- org.springframework:spring-core:5.1.7.RELEASE (*)
| +--- org.springframework:spring-context -> 5.1.7.RELEASE
| | +--- org.springframework:spring-aop:5.1.7.RELEASE
| | | +--- org.springframework:spring-beans:5.1.7.RELEASE (*)
| | | \--- org.springframework:spring-core:5.1.7.RELEASE (*)
| | +--- org.springframework:spring-beans:5.1.7.RELEASE (*)
| | +--- org.springframework:spring-core:5.1.7.RELEASE (*)
| | \--- org.springframework:spring-expression:5.1.7.RELEASE
| | \--- org.springframework:spring-core:5.1.7.RELEASE (*)
[...]
When I exclude nested dependencies and include them explicitly, the result might look like this:
[...]
testRuntimeClasspath - Runtime classpath of source set 'test'.
+--- org.apache.logging.log4j:log4j-core -> 2.11.0
| \--- org.apache.logging.log4j:log4j-api:2.11.0
+--- com.google.guava:guava -> 20.0
+--- project :xxx
| +--- org.springframework:spring-context -> 5.1.7.RELEASE
| | +--- org.springframework:spring-aop:5.1.7.RELEASE
| | | +--- org.springframework:spring-beans:5.1.7.RELEASE (*)
| | | \--- org.springframework:spring-core:5.1.7.RELEASE (*)
| | +--- org.springframework:spring-beans:5.1.7.RELEASE (*)
| | +--- org.springframework:spring-core:5.1.7.RELEASE (*)
| | \--- org.springframework:spring-expression:5.1.7.RELEASE
| | \--- org.springframework:spring-core:5.1.7.RELEASE (*)
+--- org.springframework:spring-tx -> 5.1.7.RELEASE
| +--- org.springframework:spring-beans:5.1.7.RELEASE
| | \--- org.springframework:spring-core:5.1.7.RELEASE
| | \--- org.springframework:spring-jcl:5.1.7.RELEASE
| \--- org.springframework:spring-core:5.1.7.RELEASE (*)
[...]
In order to see if the set of dependencies changed, I'd like to compare lists of dependencies. In other words, I'd like to flatten the tree view shown above, so that I can concentrate on differences that are not related to transitive inclusions.
With Maven I can do mvn dependency:tree and mvn dependency:list. How can I do this using Gradle?
I don't think you will find some Gradle core tasks to achieve this (maybe some community plugin exist), but you can write your own custom task to list dependencies in any format you want ( text, csv, ...)
task dependencyList() {
doLast() {
configurations.each { configuration ->
if (configuration.isCanBeResolved()){
println("Configuration $configuration.name ================================")
def files = configuration.resolvedConfiguration.getFiles().sort()
files.forEach{ f -> println(" dep: $f.name")}
}
}
}
}

How can I get the metadata of dependencies in gradle?

I want to get all information I can get from the Gradle about each dependency I added,
I can get the dependency tree by run
grade dependencies
we get something like this
+--- io.springfox:springfox-swagger2:2.9.2
| +--- io.swagger:swagger-annotations:1.5.20
| +--- io.swagger:swagger-models:1.5.20
| | +--- com.fasterxml.jackson.core:jackson-annotations:2.9.5 -> 2.9.0
| | +--- org.slf4j:slf4j-api:1.7.22 -> 1.7.26
| | \--- io.swagger:swagger-annotations:1.5.20
| +--- io.springfox:springfox-spi:2.9.2 (*)
| +--- io.springfox:springfox-schema:2.9.2
| | +--- io.springfox:springfox-core:2.9.2 (*)
| | \--- io.springfox:springfox-spi:2.9.2 (*)
| +--- io.springfox:springfox-swagger-common:2.9.2
| | +--- io.swagger:swagger-annotations:1.5.20
| | +--- io.swagger:swagger-models:1.5.20 (*)
| | +--- io.springfox:springfox-spi:2.9.2 (*)
| | +--- io.springfox:springfox-schema:2.9.2 (*)
| | +--- io.springfox:springfox-spring-web:2.9.2 (*)
| | +--- com.google.guava:guava:20.0
| | +--- com.fasterxml:classmate:1.4.0
| | +--- org.slf4j:slf4j-api:1.7.25 -> 1.7.26
| | +--- org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE (*)
| | \--- org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE (*)
| +--- io.springfox:springfox-spring-web:2.9.2 (*)
| +--- com.google.guava:guava:20.0
| +--- com.fasterxml:classmate:1.4.0
| +--- org.slf4j:slf4j-api:1.7.25 -> 1.7.26
| +--- org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE (*)
| +--- org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE (*)
| \--- org.mapstruct:mapstruct:1.2.0.Final
But can't get all other information about the dependencies
on how can I achieve this?
Update
I want to get information about the creator, date, homepage of the library, library language, license type or any information that can be provided.
Gradle does not offer APIs for doing this.
If your dependencies use Maven POM file or Ivy XML as their metadata, you can access these files through an ArtifactQuery. There is an example in the documentation to do that.
You will however have to decide which information to extract and how to present it.

<<Spring Boot 1.1.6>> Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException

I am new to spring boot and building an application with Spring boot 1.1.6.The basic application was working fine.
But when I added some dependencies, I am unable to start the application and seeing the below exception during staring.
My build.gradle file
` buildscript {
ext {
springBootVersion = '1.1.6.RELEASE'
}
repositories {
maven {
url "http://repo.spring.io/libs-snapshot"
}
mavenLocal()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.6.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'war'
sourceCompatibility = 1.7
compileJava {
targetCompatibility = 1.7
}
war {
baseName = 'gs-convert-jar-to-war'
version = '0.1.0'
}
repositories {
mavenCentral()
mavenLocal()
maven { url "http://repo.spring.io/libs-snapshot" }
maven { url "http://maven.springframework.org/milestone" }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") {
exclude module: "spring-boot-starter-tomcat"
exclude module:"spring-boot-starter-logging"
}
providedRuntime("org.springframework.boot:spring-boot-starter-jetty:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-aop:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-test:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-security:${springBootVersion}")
compile("com.google.guava:guava:17.0")
compile("com.squareup.retrofit:retrofit:1.6.0")
compile("commons-io:commons-io:2.4")
compile("com.local.abdd:abdd-jith912:1.0.4-SNAPSHOT"){
exclude module:"slf4j-api"
}
compile("com.local.abdd:abdd-jith912:1.0.4-SNAPSHOT:tests"){
exclude module:"slf4j-api"
}
testCompile("junit:junit")
compile("org.slf4j:slf4j-api:1.7.7"){
force = true
}
compile("org.slf4j:slf4j-log4j12:1.7.7"){
force=true
}
compile("org.slf4j:slf4j-jdk14:1.7.7"){
force=true
}
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
`
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load bean class: ; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/security/config/annotation/authentication/configurers/GlobalAuthenticationConfigurerAdapter.class] cannot be opened because it does not exist
at org.springframework.context.annotation.ConfigurationClassParser.processDeferredImportSelectors(ConfigurationClassParser.java:392)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:165)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:305)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:243)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:254)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:94)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:611)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
at org.magnum.mobilecloud.video.Application.main(Application.java:27)
Caused by: java.io.FileNotFoundException: class path resource [org/springframework/security/config/annotation/authentication/configurers/GlobalAuthenticationConfigurerAdapter.class] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172)
at org.springframework.core.type.classreading.SimpleMetadataReader.(SimpleMetadataReader.java:50)
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:82)
at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:102)
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:77)
at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:561)
at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getSuperClass(ConfigurationClassParser.java:736)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:284)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:218)
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:435)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:258)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:218)
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:435)
at org.springframework.context.annotation.ConfigurationClassParser.processDeferredImportSelectors(ConfigurationClassParser.java:389)
... 13 more
My gradle dependencies output is too huge that I cannot enter here.
However I find some spring components used as transitive dependencies like
| +--- com.local.infra.thirdparty:oracle-simplefan:11.2.0.2
| | | | | | +--- javax.jms:jms:1.1
| | | | | | +--- org.springframework:spring-jms:3.1.1.RELEASE
| | | | | | | +--- aopalliance:aopalliance:1.0
| | | | | | | +--- org.springframework:spring-aop:3.1.1.RELEASE -> 4.0.7.RELEASE (*)
| | | | | | | +--- org.springframework:spring-beans:3.1.1.RELEASE -> 4.0.7.RELEASE (*)
| | | | | | | +--- org.springframework:spring-context:3.1.1.RELEASE -> 4.0.7.RELEASE (*)
| | | | | | | +--- org.springframework:spring-core:3.1.1.RELEASE -> 4.0.7.RELEASE (*)
| | | | | | | \--- org.springframework:spring-tx:3.1.1.RELEASE -> 3.2.2.RELEASE
| | | | | | | +--- aopalliance:aopalliance:1.0
| | | | | | | +--- org.springframework:spring-beans:3.2.2.RELEASE -> 4.0.7.RELEASE (*)
| | | | | | | \--- org.springframework:spring-core:3.2.2.RELEASE -> 4.0.7.RELEASE (*)
and
+--- org.springframework.security:spring-security-core:3.0.4.RELEASE -> 3.2.5.RELEASE (*)
| | | | | | | +--- org.springframework.security:spring-security-taglibs:3.0.4.RELEASE
| | | | | | | | +--- org.springframework.security:spring-security-web:3.0.4.RELEASE -> 3.2.5.RELEASE (*)
| | | | | | | | +--- org.springframework.security:spring-security-acl:3.0.4.RELEASE
| | | | | | | | | +--- org.springframework.security:spring-security-core:3.0.4.RELEASE -> 3.2.5.RELEASE (*)
| | | | | | | | | \--- org.springframework:spring-context-support:3.0.3.RELEASE -> 3.2.2.RELEASE (*)
| | | | | | | | \--- org.springframework:spring-web:3.0.3.RELEASE -> 4.0.7.RELEASE (*)
| | | | | | | +--- org.springframework.security:spring-security-config:3.0.4.RELEASE -> 3.2.5.RELEASE (*)
I'm not 100% sure that this will solve your problem, but it will move things in the right direction.
You have a number of dependencies that are out of sync with other dependencies from the same Spring project. For example you have a mix of versions in your Spring Framework dependencies. Most are 4.0.7.RELEASE but a few are 3.x.x.
One way to fix this is to add an explicit, direct dependency on the problematic modules (Spring Boot will provide the right version for you. For example:
dependencies {
compile 'org.springframework:spring-context-support'
compile 'org.springframework:spring-jms'
compile 'org.springframework:spring-tx'
compile 'org.springframework:spring-security-acl'
compile 'org.springframework:spring-security-taglibs'
}
Try making this change and looking at the output of gradle dependencies again. Repeat the process if you spot any other modules with versions that are out of line with their other modules in the same Spring project. Once the versions all look right, try running your app again.

Resources