Несовместимые типы, ограничения равенства и метод, не найденный во время миграции Java 9

При переносе одного из наших проектов на Java 9(сборка 9+181) я сталкиваюсь со специфической проблемой, которая выглядит как неправильная реализация в некоторых библиотеках, связанная с выводом типов и java-модулем. Я использую dropwizard-core(1.1.0) а также guice(4.1.0) Конфигурации следующие:

public class CustomService extends io.dropwizard.Application<CustomServiceConfig> {

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

    // other initializations

    @Override
    public void run(CustomServiceConfig config, io.dropwizard.setup.Environment environment) throws Exception {
        com.google.inject.Injector injector = createInjector(config, environment);
        environment.jersey().register(injector.getInstance(SomeResource.class)); //line 45
        environment.healthChecks().register("DBHealth", injector.getInstance(HealthCheck.class)); 
        environment.servlets().addFilter("Filter-Name", SomeFilter.class)
                .addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
    }


    private com.google.inject.Injector createInjector(CustomServiceConfig config, Environment environment) {
        return com.google.inject.Guice.createInjector(new CustomServiceModule(config, environment));
    }

}

public class CustomServiceModule extends com.google.inject.AbstractModule {
    private final CustomServiceConfig serviceConfig;
    private final Environment environment;

    public CustomServiceModule(CustomServiceConfig serviceConfig, Environment environment) {
        this.serviceConfig = serviceConfig;
        this.environment = environment;
    }

    @Override
    protected void configure() {
        bind(SomeInterface.class).to(SomeInterfaceImpl.class);
        ..
    }
}

Конфигурация прекрасно работает для меня со следующей комбинацией:

  • Плагин компиляции Java 8 + Maven 3 + 3.6.1 [Наша первоначальная настройка]
  • Плагин компилятора Java 9 + Maven 3 + 3.7.0 (обновлена ​​конфигурация командной строки и maven)

Но когда я переключаюсь на структуру модуля, а затем пытаюсь скомпилировать модуль maven, состоящий из этих классов, я получаю эти ошибки во время mvn clean install:

[ERROR] ../service/service/CustomService.java:[45,29] incompatible types: inference variable T has incompatible bounds
    equality constraints: base.SomeResource
    upper bounds: java.lang.Class<?>,java.lang.Object

[ERROR] ../service/service/CustomService.java:[56,31]
no suitable method found for
addFilter(java.lang.String,java.lang.Class< SomeFilter >)
[ERROR]     method io.dropwizard.jetty.setup.ServletEnvironment.addFilter(java.lang.String,javax.servlet.Filter)
is not applicable
[ERROR]       (argument mismatch; java.lang.Class< SomeFilter > cannot be
converted to javax.servlet.Filter)

Я не уверен, почему эти ошибки произошли и могут ли они быть связаны с используемой структурой модуля.

Q1. Существуют ли какие-либо изменения, связанные с выводом типов, которые могут повлиять на компиляцию maven с изменениями структуры модуля (если это возможно) с учетом используемых зависимостей?

Также во время миграции я в основном использовал автоматические имена модулей, предложенные IntelliJ, для создания module-info как:

module service {
//    Internal modules  which compile successfully
    requires model;
    requires util;

//    Dependent library modules
    requires httpcore;
    requires guice;
    requires guava;
    requires dropwizard.core;
    requires mongo.java.driver;
    requires org.apache.commons.lang3;
    requires javax.servlet.api;
}

Q2. Если это не проблема регрессии во время миграции, почему это не сработало с нашей предыдущей настройкой? Требует ли это также изменения кода в нашем сервисе, или мы будем ждать, пока библиотеки перейдут в модули, если это может помочь?

Примечание: попытался изучить использование версий зависимостей и реализацию классов. Они одинаковы как в предыдущей, так и в текущей настройке.

Дайте мне знать для любой дополнительной информации, с которой я мог бы помочь.


Обновление: мне удалось воспроизвести то же самое в микросервисном образце, созданном мной, чтобы изолировать его от остальной части моего проекта.

1 ответ

Решение

Из примера проекта я смог решить проблему с компиляцией. Было 2 исключения в com.SomeService#run метод. В вашем module-info.java отсутствовали модули, после того как вы добавите их, код должен скомпилироваться.

requires dropwizard.jersey;
requires dropwizard.jetty;

JerseyEnvironment происходит от io.dropwizard:dropwizard-jersey:1.1.0

ServletEnvironment происходит от io.dropwizard:dropwizard-jetty:1.1.0

Так как это разные банки, они экспортируют разные модули. Следовательно, требования должны быть явно добавлены. Ваш код прекрасно работает без module-info.java, потому что в это время система модулей не используется.

Я нашел исправление, выполнив метод, упомянутый в комментариях ниже:

@Override
public void run(SomeServiceConfig config, Environment environment) throws Exception {
    Injector injector = Guice.createInjector(new SomeServiceModule());
    // Fix: Extract to variable to find Type of jersey and then find the module to add under requires
    JerseyEnvironment jersey = environment.jersey(); 
    jersey.register(injector.getInstance(SomeResource.class));
    // Fix 2: Same method as Fix 1
    ServletEnvironment servlets = environment.servlets();
    servlets.addFilter("Some-Filter", SomeFilter.class);
}
Другие вопросы по тегам