本文介绍了Java 9迁移期间找不到不兼容的类型,等式约束和方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将我们的一个项目迁移到 Java 9(内部版本9 + 181) 时,我面临着一个特殊的问题,即在使用的某个库中看起来不正确的实现与和。我使用 dropwizard-core(1.1.0) guice(4.1.0) 配置如下:

While migrating one of our projects to Java 9(build 9+181), I am facing a peculiar problem what looks like an incorrect implementation in some library in use related to type inference and java-module. I am using a dropwizard-core(1.1.0) and guice(4.1.0) configurations as follows:

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);
        ..
    }
}






使用以下组合对我配置正常:


The configuration works fine for me with the following combination :


  • Java 8 + Maven 3 +编译器插件3.6.1 [我们的原始设置]

  • Java 9 + Maven 3 +编译器插件3.7.0(命令行和maven配置已更新)

但是当我切换到模块结构然后尝试编译由这些类组成的maven模块时,我在 mvn clean install

But as I switch to the module structure and then try and compile the maven module consisting of those classes, I get these errors during 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)


我不确定为什么会出现这些错误,以及它们是否与使用中的模块结构有关。

I am not sure why these errors occurred and if they could be related to the module structure in use.

Q1。是否有任何类型推断相关的更改可能会影响maven编译与模块结构更改(如果可能),请记住使用的依赖项?

同时在迁移时,我主要使用IntelliJ建议的自动模块名称来构建 module-info

Also while migrating, I have mostly used the automatic module names as suggested by IntelliJ to construct the module-info as :

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。如果这不是迁移时的回归问题,为什么这不会因我们之前的设置而失败?这是否也要求我们的服务中的代码更改,或者我们是否应该等待库移动到模块,如果这可能有帮助?

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

Note: Have tried to look into the usage of the dependency versions and class implementation. They are same in both the previous and current setup.

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

Do let me know for any further information I could help with.

更新
我能够在由我创建,用于将其与我项目的其余部分隔离开来。

Update:I was able to reproduce the same in a microservice sample created by me to isolate it from the rest of my project.

推荐答案

从示例项目中我能够解决编译问题。 com.SomeService#run 方法中有2个例外。你的module-info.java中有缺少的模块,一旦你添加了这些代码就应该编译。

From the sample project I was able to fix the compilation issue. There were 2 exceptions in com.SomeService#run method. There were missing modules in your module-info.java, once you add these the code should compile.

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的情况下工作正常,因为当时没有使用模块系统。

Since they are different jars, they export different modules. Hence, the requires needs to be explicitly added.Your code works fine without module-info.java because at that time module system is not used.

我通过以下方法找到了修复方法,提到的方法在评论中:

I found the fix by doing the below, method mentioned in comments:

@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);
}

这篇关于Java 9迁移期间找不到不兼容的类型,等式约束和方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 14:05