[ERROR] Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 0.583 s <<< FAILURE! - in au.gov.nla.ums.keycloak.integration.ITKeyCloakIntegrationTest [ERROR] getUserInfoFromUsernameAndPassword(au.gov.nla.ums.keycloak.integration.ITKeyCloakIntegrationTest) Time elapsed: 0.488 s <<< ERROR! java.lang.NoSuchMethodError: org.apache.commons.io.output.DeferredFileOutputStream.<init>(ILjava/lang/String;Ljava/lang/String;Ljava/io/File;)V at au.gov.nla.ums.keycloak.integration.ITKeyCloakIntegrationTest.getUserInfoFromUsernameAndPassword(ITKeyCloakIntegrationTest.java:65) [ERROR] getRolesAndGroupsFromClientCredentials(au.gov.nla.ums.keycloak.integration.ITKeyCloakIntegrationTest) Time elapsed: 0.088 s <<< ERROR! javax.ws.rs.ProcessingException: java.lang.NoSuchMethodError: org.apache.commons.io.output.DeferredFileOutputStream.<init>(ILjava/lang/String;Ljava/lang/String;Ljava/io/File;)V at au.gov.nla.ums.keycloak.integration.ITKeyCloakIntegrationTest.getRolesAndGroupsFromClientCredentials(ITKeyCloakIntegrationTest.java:46) Caused by: java.lang.NoSuchMethodError: org.apache.commons.io.output.DeferredFileOutputStream.<init>(ILjava/lang/String;Ljava/lang/String;Ljava/io/File;)V at au.gov.nla.ums.keycloak.integration.ITKeyCloakIntegrationTest.getRolesAndGroupsFromClientCredentials(ITKeyCloakIntegrationTest.java:46)
DeferredFileOutputStream comes from commons-io.jar. Version 1.3 doesn't have such constructor while version 2.5 does. OK, It should be an easy fix, I think, I just have to explicitly set the version of this jar by:
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> <scope>test</scope> </dependency>
But it doesn't work.
Then I use reflection to print out all the constructor signature in the hope to ascertain the version of the jar.
Class<?> cl = Class.forName("org.apache.commons.io.output.DeferredFileOutputStream"); Constructor<?>[] cons = cl.getConstructors(); System.out.println("Constructors:---"); for (Constructor<?> con : cons) { System.out.println(con); }
Here is the output:
Constructors:--- public org.apache.commons.io.output.DeferredFileOutputStream(int,java.io.File)
OK, now I am pretty certain that version 1.3 is at play. But the question is which jar is dependent upon commons-io and brings it on our classpath. More importantly, why can't the version of it be overwriten?
Eclipse's Dependency Hierarchy shows it comes indirectly from keycloak-modal-jpa. It says 'omitted for conflict with 2.5', and that's why local is working. How to get Jenkins show something like this?
A maven command comes to rescue:
mvn dependency:tree
The result shows commons-io is not being omitted
Compared to the result of my local run, everthing is the same except the local result doesn't have commons-io included in the tree.
Then I try excluding common-io from the keycloak-model-jar:
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-model-jpa</artifactId> <scope>provided</scope> <version>${keycloak.version}</version> <exclusions> <exclusion> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> </exclusion> </exclusions> </dependency>
Unfortunately, Jenkins shows exactly the same dependency tree.
Oh, wait a second. The group id in the dependency tree is org.apache.common, but the group id of what I exclude is commons-io.
Changing the group id to org.apache.commons:
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-model-jpa</artifactId> <scope>provided</scope> <version>${keycloak.version}</version> <exclusions> <exclusion> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> </exclusion> </exclusions> </dependency>
And finally it's working!
Upon closely inspecting the pom.xml of openshift-restclient-jar, which is directly dependent on commons-io, I make some surprising discovery. Both org.apache.commons.commons-io and commons-io.commons-io are on its dependency list.
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.1</version> </dependency>
It looks like a bug to me. Having said that, it remains a mystery to me as to why Jenkins sovles dependency differently from my local maven build. Could it be due to the different version of Maven?
Now I think it's more likely due to the different version of JDK
ReplyDelete