Dropwizard: Runtime Error - java.lang.NoSuchMethodError: org.hibernate.validator.HibernateValidatorConfiguration.addValueExtractor

Created on 3 Jan 2020  路  5Comments  路  Source: dropwizard/dropwizard

Release: 2.0.0

Error- As soon you execute the jar file, you get following error:

Exception in thread "main" java.lang.NoSuchMethodError: org.hibernate.validator.HibernateValidatorConfiguration.addValueExtractor(Ljavax/validation/valueextraction/ValueExtractor;)Ljavax/validation/Configuration;
        at io.dropwizard.validation.BaseValidator.newConfiguration(BaseValidator.java:27)
        at io.dropwizard.jersey.validation.Validators.newConfiguration(Validators.java:33)
        at io.dropwizard.jersey.validation.Validators.newValidatorFactory(Validators.java:26)
        at io.dropwizard.setup.Bootstrap.<init>(Bootstrap.java:64)
        at io.dropwizard.Application.run(Application.java:86)
        at BusinessAPI.main(BusinessAPI.java:51)

Workaround: Exclusion of 6.1.0.Final version and inclusion of 6.0.17.Final

    <dependency>
      <groupId>io.dropwizard</groupId>
      <artifactId>dropwizard-core</artifactId>
        <exclusions>
          <exclusion>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
          </exclusion>
        </exclusions>
    </dependency>

    <dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.17.Final</version>
    </dependency>

Most helpful comment

Problem is that javax.validation:validation-api-1.1.0-Final.jar and jakarta.validation:jakarta.validation-api-2.0.2.jar are both on your classpath, they have classes in the same namespace(javax.validation) and older version of the class, one which doesn't have methods present in the latest version, is being loaded by the classloader.

You'll have to exclude javax.validation from your classpath, it's coming from swagger-models

All 5 comments

@sharmasourabh Thanks for reporting this!

Could you please post your complete POM and the BusinessAPI class so we can try to reproduce the issue?

Thanks for following up.

POM:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <packaging>pom</packaging>

  <groupId>com.x</groupId>
  <artifactId>x-service</artifactId>
  <version>0.1</version>
  <name>X Service</name>

  <modules>
    <module>authentication-api</module>
    <module>business-api</module>
    <module>common</module>
  </modules>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <dropwizard.version>2.0.0</dropwizard.version>
    <jjwt.version>0.10.7</jjwt.version>
    <swagger.version>2.1.0</swagger.version>
    <reflections.version>0.9.11</reflections.version>
    <maven.shade.plugin.version>3.2.1</maven.shade.plugin.version>
    <maven.jar.plugin.version>3.2.0</maven.jar.plugin.version>
    <maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version>
    <junit5.version>5.5.2</junit5.version>
  </properties>

  <repositories>
    <repository>
      <id>project.local</id>
      <name>project</name>
      <url>file:${project.basedir}/</url>
    </repository>
    <repository>
      <id>sonatype-nexus-snapshots</id>
      <name>Sonatype Nexus Snapshots</name>
      <url>http://oss.sonatype.org/content/repositories/snapshots</url>
    </repository>
  </repositories>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>io.dropwizard</groupId>
        <artifactId>dropwizard-dependencies</artifactId>
        <version>${dropwizard.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>io.dropwizard</groupId>
      <artifactId>dropwizard-core</artifactId>
        <exclusions>
          <exclusion>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
          </exclusion>
        </exclusions>
    </dependency>

    <dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.17.Final</version>
    </dependency>

    <dependency>
      <groupId>io.dropwizard</groupId>
      <artifactId>dropwizard-auth</artifactId>
    </dependency>
    <dependency>
      <groupId>io.dropwizard</groupId>
      <artifactId>dropwizard-assets</artifactId>
    </dependency>
    <dependency>
      <groupId>io.dropwizard</groupId>
      <artifactId>dropwizard-http2</artifactId>
    </dependency>
    <dependency>
      <groupId>io.dropwizard</groupId>
      <artifactId>dropwizard-hibernate</artifactId>
    </dependency>
    <dependency>
      <groupId>io.dropwizard</groupId>
      <artifactId>dropwizard-migrations</artifactId>
    </dependency>
    <dependency>
      <groupId>org.postgresql</groupId>
      <artifactId>postgresql</artifactId>
    </dependency>
    <dependency>
      <groupId>io.dropwizard</groupId>
      <artifactId>dropwizard-forms</artifactId>
    </dependency>
    <dependency>
      <groupId>io.jsonwebtoken</groupId>
      <artifactId>jjwt-api</artifactId>
      <version>${jjwt.version}</version>
    </dependency>
    <dependency>
      <groupId>io.jsonwebtoken</groupId>
      <artifactId>jjwt-impl</artifactId>
      <version>${jjwt.version}</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>io.jsonwebtoken</groupId>
      <artifactId>jjwt-jackson</artifactId>
      <version>${jjwt.version}</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
    </dependency>

    <dependency>
      <groupId>net.sourceforge.htmlunit</groupId>
      <artifactId>htmlunit</artifactId>
      <version>2.36.0</version>
    </dependency>

    <!-- swagger v3 / swagger-jaxrs2 -->
    <dependency>
      <groupId>io.swagger.core.v3</groupId>
      <artifactId>swagger-core</artifactId>
      <version>${swagger.version}</version>
    </dependency>
    <dependency>
      <groupId>io.swagger.core.v3</groupId>
      <artifactId>swagger-jaxrs2</artifactId>
      <version>${swagger.version}</version>
    </dependency>
    <dependency>
      <groupId>io.swagger.core.v3</groupId>
      <artifactId>swagger-integration</artifactId>
      <version>${swagger.version}</version>
    </dependency>

    <!-- Test dependencies -->
    <dependency>
      <groupId>org.reflections</groupId>
      <artifactId>reflections</artifactId>
      <version>${reflections.version}</version>
      <scope>compiler</scope>
    </dependency>
    <dependency>
      <groupId>io.dropwizard</groupId>
      <artifactId>dropwizard-testing</artifactId>
      <scope>test</scope>
      <exclusions>
        <exclusion>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>${junit5.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish.jersey.test-framework.providers</groupId>
      <artifactId>jersey-test-framework-provider-inmemory</artifactId>
      <scope>test</scope>
      <exclusions>
        <exclusion>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
        </exclusion>
        <exclusion>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.glassfish.jersey.test-framework.providers</groupId>
      <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
      <scope>test</scope>
      <exclusions>
        <exclusion>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
        </exclusion>
        <exclusion>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-shade-plugin</artifactId>
          <version>${maven.shade.plugin.version}</version>
          <configuration>
            <createDependencyReducedPom>true</createDependencyReducedPom>
            <filters>
              <filter>
                <artifact>*:*</artifact>
                <excludes>
                  <exclude>META-INF/*.SF</exclude>
                  <exclude>META-INF/*.DSA</exclude>
                  <exclude>META-INF/*.RSA</exclude>
                </excludes>
              </filter>
            </filters>
          </configuration>
          <executions>
            <execution>
              <phase>package</phase>
              <goals>
                <goal>shade</goal>
              </goals>
              <configuration>
                <transformers>
                  <transformer
                    implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                  <transformer
                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                    <mainClass>campspot.CampspotAPI</mainClass>
                  </transformer>
                </transformers>
              </configuration>
            </execution>
          </executions>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-jar-plugin</artifactId>
          <version>${maven.jar.plugin.version}</version>
          <configuration>
            <archive>
              <manifest>
                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
              </manifest>
            </archive>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>${maven.compiler.plugin.version}</version>
          <configuration>
            <source>${maven.compiler.source}</source>
            <target>${maven.compiler.target}</target>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

App Class: (Above I have shared the logs of BusinessAPI class, below class also produce the same error.

public class AuthenticationAPI extends Application<DBConfig> {

  public static void main(String[] args) throws Exception {
      new AuthenticationAPI().run(args);
  }

  private final ScanningHibernateBundle<DBConfig> hibernate =
    new ScanningHibernateBundle<DBConfig>("dao.entities") {
      @Override
      protected void configure(Configuration configuration) {
        configuration.addPackage("dao.entities");
        super.configure(configuration);
      }

      @Override
      public PooledDataSourceFactory getDataSourceFactory(DBConfig config) {
        return config.getDataSourceFactory();
      }
    };

  @Override
  public void initialize(Bootstrap<DBConfig> bootstrap) {
    bootstrap.addBundle(hibernate);
  }

  @Override
  public void run(DBConfig config, Environment environment) throws Exception {
    setupSwagger(environment);
    SessionFactory sessionFactory = hibernate.getSessionFactory();
    UserDAO userDAO = new UserDAO(sessionFactory);
    TokenDAO tokenDAO = new TokenDAO(sessionFactory, userDAO);
    setupAuth(environment, tokenDAO, userDAO);
    AuthResource authResource = new AuthResource(userDAO, tokenDAO);

    environment.jersey().register(authResource);
  }

  private void setupAuth(Environment environment, TokenDAO tokenDAO, UserDAO userDAO) {
    CustomAuthenticator authenticator =
      new UnitOfWorkAwareProxyFactory(hibernate).create(CustomAuthenticator.class,
        new Class<?>[]{TokenDAO.class, UserDAO.class}, new Object[]{tokenDAO, userDAO});
    CustomAuthFilter filter = new CustomAuthFilter(authenticator);

    environment.jersey().register(new AuthDynamicFeature(filter));
    environment.jersey().register(RolesAllowedDynamicFeature.class);
  }

  private void setupSwagger(Environment env) {
    OpenAPI oas = new OpenAPI();
    Info info =
      new Info().title("Sidhh PMS Auth API").description("Sidhh PMS Auth API. Greetings for you!")
        .version("v1").termsOfService("http://example.com/terms")
        .contact(new Contact().email("[email protected]"));
    oas.info(info);
    SwaggerConfiguration oasConfig = new SwaggerConfiguration().openAPI(oas).prettyPrint(true)
      .resourcePackages(Stream.of("resources").collect(Collectors.toSet()));
    env.jersey().register(new OpenApiResource().openApiConfiguration(oasConfig));
  }
}

Problem is that javax.validation:validation-api-1.1.0-Final.jar and jakarta.validation:jakarta.validation-api-2.0.2.jar are both on your classpath, they have classes in the same namespace(javax.validation) and older version of the class, one which doesn't have methods present in the latest version, is being loaded by the classloader.

You'll have to exclude javax.validation from your classpath, it's coming from swagger-models

Thanks @j4n1!
Exclusion of validation-api from swagger-core fixed the prob. No issue with dropwizard 2.0. My gotcha!

    <dependency>
      <groupId>io.swagger.core.v3</groupId>
      <artifactId>swagger-core</artifactId>
      <version>${swagger.version}</version>
      <exclusions>
        <exclusion>
          <groupId>javax.validation</groupId>
          <artifactId>validation-api</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

For bystanders ending up here, this has been fixed in swagger-core v2.1.2 from https://github.com/swagger-api/swagger-core/pull/3467 so the exclusion shouldn't be needed anymore.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rbjorklin picture rbjorklin  路  3Comments

jamisonhyatt picture jamisonhyatt  路  8Comments

Allsimon picture Allsimon  路  4Comments

ramsrib picture ramsrib  路  3Comments

ramsrib picture ramsrib  路  4Comments