Несовместимые типы, ограничения ограничений и метод, не найденные во время миграции Java 9
При переносе одного из наших проектов на Java 9 (сборка 9 + 181) я столкнулся с особой проблемой, которая выглядит как некорректная реализация в какой-либо используемой библиотеке, связанной с вывод типа и java-module. Я использую конфигурации 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
Из примера проекта я смог исправить проблему компиляции. В методе com.SomeService#run
было 2 исключения. В модуле -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);
}