Open MeAdhere opened 2 years ago
你的分析是正确的。
从原理来说,当omni.constructor.enhance.enable
配置开启以后,Testable就会为所有待构造的类自动加上一个参数为java.lang.Void
的构造方法,用于避开原类型里可能导致抛异常的默认构造方法。由于这个修改必须在类型首次加载的时候进行,因而Testable无法等到执行OmniConstructor.newInstance()
再来按需添加,默认会给所有类都加上,但遇到某些框架不允许类型有多个构造方法的时候就会出问题。
解决办法是在testable.properties
配置文件里添加以下内容,显式指定不要处理ElasticSearch插件相关的类型:
omni.constructor.enhance.pkgPrefix.excludes = org.elasticsearch.transport,org.elasticsearch.plugin
具体可参考全局运行参数文档。
这个问题我会近期补充到文档的常见使用问题里,在下个版本里也会增加对ElasticPlugin这种特例情况的适配。
感谢反馈。
项目框架:springboot 1.5.9 测试用例
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:spring-config.xml") public class XxMapperTest { @Resource private XxMapper xxMapper; @Test public void test_get_xx() { Entity entity=new Entity(); entity.setA(System.currentTimeMillis()); entity.setB(1); xxMapper.insert(entity); Entity queryEntity= xxMapper.getXx(entity.getA(), entity.getB()); logger.error("queryEntity---"+ JSON.toJSONString(queryEntity)); Assert.assertTrue(entity.getA().equals(queryEntity.getA())); Assert.assertTrue(entity.getB().equals(queryEntity.getB())); }
}
说明:项目中有引入es框架
报错: Caused by: java.lang.IllegalStateException: no unique public constructor for [org.elasticsearch.transport.Netty4Plugin] at org.elasticsearch.plugins.PluginsService.loadPlugin(PluginsService.java:543) at org.elasticsearch.plugins.PluginsService.(PluginsService.java:104)
at org.elasticsearch.client.transport.TransportClient.newPluginService(TransportClient.java:105)
at org.elasticsearch.client.transport.TransportClient.buildTemplate(TransportClient.java:130)
at org.elasticsearch.client.transport.TransportClient.(TransportClient.java:273)
at org.elasticsearch.transport.client.PreBuiltTransportClient.(PreBuiltTransportClient.java:128)
at org.elasticsearch.transport.client.PreBuiltTransportClient.(PreBuiltTransportClient.java:114)
at org.elasticsearch.transport.client.PreBuiltTransportClient.(PreBuiltTransportClient.java:104)
at com.jd.paimai.user.rights.search.service.es.esclient.SpringDataEsTransportClient.getObject(SpringDataEsTransportClient.java:86)
at com.jd.paimai.user.rights.search.service.es.esclient.SpringDataEsTransportClient.getObject(SpringDataEsTransportClient.java:27)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
... 62 more
后经断点运行发现,走到了testable下的com.alibaba.testable.agent.transformer.TestableClassTransformer#transform
然后这个方法mock了一个org.elasticsearch.transport.Netty4Plugin,同时构造方法也多了一个
public org.elasticsearch.transport.Netty4Plugin(java.lang.Void),加上本身自己的构造器,构造器变成了2个
org.elasticsearch.plugins.PluginsService#loadPlugin方法会对构造器内容做校验,导致异常:
private Plugin loadPlugin(Class<? extends Plugin> pluginClass, Settings settings, Path configPath) { Constructor<?>[] constructors = pluginClass.getConstructors(); if (constructors.length == 0) { throw new IllegalStateException("no public constructor for [" + pluginClass.getName() + "]"); } else if (constructors.length > 1) { throw new IllegalStateException("no unique public constructor for [" + pluginClass.getName() + "]"); } else { Constructor<?> constructor = constructors[0]; if (constructor.getParameterCount() > 2) { throw new IllegalStateException(this.signatureMessage(pluginClass)); } else { Class[] parameterTypes = constructor.getParameterTypes();