Java 9迁移期间找不到不兼容的类型,等式约束和方法

在将我们的一个项目迁移到Java 9(build 9 + 181)时 ,我面临着一个特殊的问题,在一些与类型推断和java模块相关的库中看起来是不正确的实现。 我正在使用dropwizard-core(1.1.0)guice(4.1.0)配置如下:

 public class CustomService extends io.dropwizard.Application { 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) [ERROR] method io.dropwizard.jetty.setup.ServletEnvironment.addFilter(java.lang.String,javax.servlet.Filter) is not applicable [ERROR] (argument mismatch; java.lang.Class 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。 如果这不是迁移时的回归问题,为什么这不会因我们之前的设置而失败? 这是否也要求我们的服务中的代码更改,或者我们是否应该等待库移动到模块,如果这可能有帮助?

注意 :尝试研究依赖版本和类实现的用法。 它们在先前和当前设置中都相同。

请告诉我有关我可以提供帮助的任何进一步信息。


更新 :我能够在我创建的微服务示例中重现它,以将其与我项目的其余部分隔离开来。

从示例项目中我能够解决编译问题。 com.SomeService#run方法中有2个例外。 你的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

由于它们是不同的jar子,因此它们会输出不同的模块。 因此,需要明确添加要求。 没有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); }