ResteasyClientBuilder是一个支持Client pool,SSL context,异步执行的HttpClient Builder。在使用时遇到了奇怪的事情。我在test
包下使用
1 | new ResteasyClientBuilder().executorService(Executors.newCachedThreadPool()); |
就没问题,但是在main
包下使用上述代码,就出现:
Caused by: org.jboss.resteasy.spi.UnhandledException: java.lang.NoSuchMethodError: org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder.executorService(Ljava/util/concurrent/ExecutorService;)Ljavax/ws/rs/client/ClientBuilder;
at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:78)
at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:222)
at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:179)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:422)
NoSuchMethodError
。我怀疑是项目包依赖的问题,去pom.xml
发现依赖是
1 | <dependency> |
之所以用<scope>provided</scope>
是因为resteasy-client
是Wildfly自带的组件,所以打包项目时不包含resteasy-client
,带了反而会出错。
之所以报NoSuchMethodError
是因为Wildfly自带的resteasy-client
在/home/bejond/codewildfly-10.1.0.Final/modules/system/layers/base/org/jboss/resteasy/resteasy-jaxrs/main/resteasy-client-3.0.19.Final.jar
,版本比较旧,是3.0.19.Final
。
这个版本里并没有executorService(ExecutorService executorService)
。实际上是ResteasyClientBuilder
的父类ClientBuilder
并没有定义executorService(ExecutorService executorService)
。
而test
下能正常测试是因为使用的新版本的resteasy-client
,我使用的是resteasy-client-3.5.0.Final
。而自动化测试是不依赖Web服务器的,所以能正常运行。
pom.xml
依赖没写<version>
是依赖了父pom。子pom如果要使用别的版本的依赖,加上<version>
即可:
1 | <dependency> |
Stackoverflow RESTEasy Client + NoSuchMethodError建议下载最新resteasy-jaxrx
包,替换wildfly-10.1.0.Final/modules/system/layers/base/org/jboss/resteasy/resteasy-jaxrs
所有的组件。我并没有这么做,一来不确定是否有兼容性问题(Java向下兼容做得很好,一般不会有这个问题。但就怕遇到,排查起来很麻烦),二来加大实施成本。所以我使用降级的方式来做,其实也不算降级,就是使用Wildfly10.1.0.Final自带的包。
这样调整后进入ResteasyClientBuilder
就找不到executorService(ExecutorService executorService)
了。但是打开ResteasyClientBuilder
的源码,发现提示编译错误。
点击ClientBuilder
跳到源码发现版本是2.1
2.1版本里的ClientBuilder定义新的抽象方法executorService(ExecutorService executorService)
,所以提示未实现抽象方法或者将ResteasyClientBuilder改为抽象类
错误。
是因为Intellij项目library依赖配置问题,到项目.idea/library
下,把Maven__org_jboss_spec_javax_ws_rs_jboss_jaxrs_api_2_1_spec_1_0_0_Final.xml
删掉即可。
然后Intellij会自动根据maven依赖增加Maven__org_jboss_spec_javax_ws_rs_jboss_jaxrs_api_2_0_spec_1_0_1_Final.xml
文件。
调整好依赖后,test
里的测试代码就会对executorService(ExecutorService executorService)
标红了。需要将项目代码和test
的代码修改为
1 | new ResteasyClientBuilder().asyncExecutor(Executors.newCachedThreadPool()); |
需要注意,asyncExecutor(ExecutorService asyncExecutor)
在新版本的resteasy-client
包里已经过期,用executorService(ExecutorService executorService)
代替。从这个例子也能看出程序设计的问题,低版本方法名定义得随意,到了后期调整为新的名字。实际上executorService
直接调用的asyncExecutor
,又将asyncExecutor
标记为Deprecated
。
补充: 在这个例子里如果不使用executorService(ExecutorService executorService)
,ResteasyClient.build()
就会创建10线程固定大小的线程池。那么设定connectionPoolSize(int size)
就不会起作用。