1.调用Package.getPackages()找不到目标包
yidian-boot采用约定优于配置
的设计原则,所有对外接口约定存放在以.client
结尾的包中,所以我需要先找到所有以.client
结尾的包,再找到其中包含@FeignClient
的类,然后对其进行实例化。
但调用Package.getPackages()返回的包名并未包含目标包名。
- 原因
目标包的的类都未被引用,所以还未被ClassLoader加载。 - 解决方案
通过非常好用的反射框架:reflections 实现。
2.FeignContext已经实例化,但自动注入时却找不到
原因:实例化FeignContext的BeanFactory和应用所用的BeanFactory不是同一个。
通过跟踪调试,发现是spring-cloud-context
包中的BootstrapApplicationListener
监听到了第一次ApplicationContext初始化的消息后,在onApplicationEvent
方法中发起了第二次初始化,再次创建了一个新的BeanFactory。
解决方案:
2019-08-01 18:52:29.382 ERROR 3115 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field dockerClient in com.yidian.boot.demo.controller.TestController required a single bean, but 2 were found:
- client: a programmatically registered singleton - feignClient: defined by method 'feignClient' in class path resource [org/springframework/cloud/openfeign/ribbon/DefaultFeignLoadBalancedConfiguration.class]
3.Jackson把泛型序列化成Map
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.yidian.boot.interfaces.demo.model.RouteInfo
4.自定义ILoadBalencer
5.Failed to start bean 'documentationPluginsBootstrapper'
原因是client-starter启动时需要调用smp中的接口获取当前应用的配置信息,而smp尚未启动,导致接口调用失败,进一步造成springfox.documentation.spring.web.plugins.Docket
构建失败。
因此,优先启动smp即可。
6. SpringJUnit4ClassRunner requires JUnit 4.12 or higher.
从提示信息可以看出需要使用 JUnit 4.12 或更高版本。修改pom.xml吧JUnit版本改为4.12即可:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
7.no suitable HttpMessageConverter found for response type [com.yidian.boot.interfaces.model.Response<com.yidian.boot.interfaces.demo.model.smp.App>] and content type [text/plain;charset=UTF-8]
原因是响应消息头部中Content-Type=text/plain;charset=UTF-8
,并不是期望的Content-Type=application/json;charset=UTF-8
,Feign找不到合适的HttpMessageConverter
来讲响应数据反序列化成Bean,所以报错。
解决方案:自定义HttpMessageConverter
public class MyFeignDocoder extends FastJsonHttpMessageConverter {
public MyFeignDocoder() {
List<MediaType> mediaTypes = new ArrayList<>();
FastJsonConfig fastJsonConfig=new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(
SerializerFeature.QuoteFieldNames,
SerializerFeature.WriteMapNullValue,
SerializerFeature.DisableCircularReferenceDetect,
SerializerFeature.WriteDateUseDateFormat,
SerializerFeature.WriteNullStringAsEmpty);
List<MediaType> mediaTypeList=new ArrayList<>();
mediaTypeList.add(MediaType.APPLICATION_JSON_UTF8);
mediaTypeList.add(MediaType.APPLICATION_JSON);
mediaTypeList.add(MediaType.ALL);
mediaTypeList.add(MediaType.TEXT_HTML);
this.setSupportedMediaTypes(mediaTypeList);
this.setFastJsonConfig(fastJsonConfig);
}
}
注入自定义Decoder
@Bean
public Decoder feignDecoder() {
final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(new MyFeignDocoder());
return new ResponseEntityDecoder(new SpringDecoder(new ObjectFactory<HttpMessageConverters>() {
@Override
public HttpMessageConverters getObject() throws BeansException {
return httpMessageConverters;
}
}));
}
同理,可以解决Encoder的问题。
8.com.netflix.client.ClientException: Load balancer does not have available server for client: yidian-boot-smp
gateway访问smp获取服务路由信息时,一直提示找不到yidian-boot-smp
服务,但从Eureka Server监控页面可以看到,yidian-boot-smp
处于正常连接状态。
9.Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
原因:为Docker预留的内存过小,把内存增大即可。
10.sh: can't open 'run.sh'
其中run.sh代码如下:
#!/usr/bin/env bash
cd /home/app
env=$1
if [ "$env" = "" ]
then
env="prod"
fi
if [ ! -d logs ];then
mkdir logs
fi
java -jar server.jar --spring.profiles.active=$env >/dev/null 2>&1/home/app
原因:我使用的jre基础镜像是alpine
版本的,其中不包含bash命令,因而无法执行。
解决方案:将#!/usr/bin/env bash
改为#!/bin/sh
即可。
网友评论