1

I have two dependencies which point to a conflicting version of javax.validation:validation-api. To resolve this, I added a dependencyManagement section with the latest version of the validation-api.

While this causes the app to build correct, and the app works at runtime, during tests, the build breaks at a line in which the validation api is referenced (via a @Valid annotation).

The conflicting dependencies are:

<dependency>
  <groupId>io.dropwizard</groupId>
  <artifactId>dropwizard-core</artifactId>
  <version>0.9.2</version>
</dependency>

<dependency>
  <groupId>com.google.gwt</groupId>
  <artifactId>gwt-user</artifactId>
  <version>2.8.0-beta1</version>
  <scope>provided</scope>
</dependency>

I've added the following dependencyManagement:

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>

This works at runtime and compile time, but fails in tests where I refer @Valid.

Would greatly appreciate any help, as this is driving me nuts.

A_Di-Matteo
  • 26,902
  • 7
  • 94
  • 128
Ali
  • 261,656
  • 265
  • 575
  • 769

2 Answers2

2

A possible troubleshooting path is on the scope (provided) defined for gwt-user, which is the only library bringing in validation-api applying the dependencies management above.

Running the following first omitting dropwizard-core

mvn dependency:tree -Dincludes=javax.validation

The output would be:

[INFO] +- com.google.gwt:gwt-user:jar:2.8.0-beta1:provided  
[INFO] |  +- javax.validation:validation-api:jar:1.1.0.Final:compile  
[INFO] |  \- javax.validation:validation-api:jar:sources:1.0.0.GA:provided  

Taking hence the desired 1.1.0.Final version instead of the transitive 1.0.0.GA one.
(Note the scopes above, the last token per dependency entry, they should all be on provided because its root, gwt-user is on provided scope. However, validation-api is on compile because of the dependency management entry).

While omitting gwt-user the output would be:

[INFO] com.sample:sample2:jar:0.0.1-SNAPSHOT
[INFO] \- io.dropwizard:dropwizard-core:jar:0.9.2:compile
[INFO]    \- io.dropwizard:dropwizard-validation:jar:0.9.2:compile
[INFO]       \- org.hibernate:hibernate-validator:jar:5.2.2.Final:compile
[INFO]          \- javax.validation:validation-api:jar:1.1.0.Final:compile

Hence, indeed, both would bring it in, but the first was defined as provided scope while the second as default (compile) scope.

Moreover, the dependency management for validation-api has been defined for default (compile) scope, impacting how Maven is bringing it in via gwt-user (listed above, as compile, even though gwt-user is provided and all of its transitive dependencies would also be on provided, unless defined differently by dependencies management, like in this case).

Provided dependencies, per official Maven documentation are

available on the compilation and test classpath

Hence you are having during compilation and test two libraries in conjuction, validation-api and gwt-user, which would then have different coupling at runtime (gwt-user is expected to be provided by the runtime container).

If gwt-user must be in provided scope, I would suggest to adopt a finer governance and exclude validation-api directly from gwt-user. As such, validation-api will be brought in from dropwizard-core with the version required by the dependencies management.

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>io.dropwizard</groupId>
        <artifactId>dropwizard-core</artifactId>
        <version>0.9.2</version>
    </dependency>
    <dependency>
        <groupId>com.google.gwt</groupId>
        <artifactId>gwt-user</artifactId>
        <version>2.8.0-beta1</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

Update
From your comment below, you are also using the following as part of your dependencies management:

<dependency>
    <groupId>com.google.gwt</groupId>
    <artifactId>gwt</artifactId>
    <version>2.8.0-beta1</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

Which is then also specifying the following in its dependencies management:

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.0.0.GA</version>
</dependency>
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.0.0.GA</version>
    <!-- Note: use classifier=sources rather than type=java-sources so they're added to the classpath -->
    <classifier>sources</classifier>
</dependency>

While you managed to override the first, you didn't override the second and indeed it is still added to the classpath (check dependency tree output above, the 1.0.0.GA sources are still brought in, in provided scope. That's a further difference between compiler/test and runtime. At runtime, you don't have it as part of your classpath.

I would hence suggest to also add to your dependencies management its 1.1.0.Final version as overriden, so that it would be coherent with the first one.

A_Di-Matteo
  • 26,902
  • 7
  • 94
  • 128
  • Thanks. I think you're thinking along the right lines. However, I've already tried exclusions and just tried them again - the error doesn't go away. It continues to appear in tests, while runtime continues to work. So it doesn't go away in tests. – Ali Apr 12 '16 at 14:01
  • This is the output of running dependency tree: `[INFO] com.myproject:jar:1.0-SNAPSHOT [INFO] \- io.dropwizard:dropwizard-validation:jar:0.9.2:compile [INFO] \- org.hibernate:hibernate-validator:jar:5.2.2.Final:compile [INFO] \- javax.validation:validation-api:jar:1.1.0.Final:compile` – Ali Apr 12 '16 at 14:02
  • to have something more coherent, you could try to apply scope provided to the dependencyManagement entry, then remove the esplicit exclusion you just added. Then you may have the same error at runtime: while this is not nice at first, it could then help further towards the right solution. – A_Di-Matteo Apr 12 '16 at 14:24
  • Yep, adding that gives a runtime error as well. One more thing, in my dependencyManagement, I have the following entry: ` com.google.gwt gwt 2.8.0-beta1 pom import ` – Ali Apr 12 '16 at 14:38
  • @ClickUpvote check my update, I found a further important difference which may help you out – A_Di-Matteo Apr 12 '16 at 16:34
  • I've now added the following to my dependencyManagement: ` javax.validation validation-api 1.1.0.Final javax.validation validation-api 1.1.0.Final sources `. However, it still fails at test time. Am I overriding it correctly? – Ali Apr 12 '16 at 18:52
0

You have to excluded the dependency from one or another like this :

       <dependency>
          <groupId>io.dropwizard</groupId>
          <artifactId>dropwizard-core</artifactId>
          <version>0.9.2</version>
       </dependency>

     <dependency>
          <groupId>com.google.gwt</groupId>
          <artifactId>gwt-user</artifactId>
          <version>2.8.0-beta1</version>
          <scope>provided</scope>
          <exclusions>
             <exclusion> 
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
             </exclusion>
          </exclusions> 
    </dependenc
vincent
  • 1,214
  • 12
  • 22