Storm拓扑频繁出现DEF_CONTENT_CHARSET字段缺失错误求助
解决Storm拓扑中
java.lang.NoSuchFieldError: DEF_CONTENT_CHARSET错误 先给你贴一下报错的完整堆栈信息,方便定位问题:
java.lang.NoSuchFieldError: DEF_CONTENT_CHARSET at org.apache.http.impl.client.DefaultHttpClient.setDefaultHttpParams(DefaultHttpClient.java:175) ~[stormjar.jar:?] at org.apache.http.impl.client.DefaultHttpClient.createHttpParams(DefaultHttpClient.java:158) ~[stormjar.jar:?] at org.apache.http.impl.client.AbstractHttpClient.getParams(AbstractHttpClient.java:448) ~[stormjar.jar:?] at org.apache.http.impl.client.AbstractHttpClient.createClientConnectionManager(AbstractHttpClient.java:309) ~[stormjar.jar:?] at org.apache.http.impl.client.AbstractHttpClient.getConnectionManager(AbstractHttpClient.java:466) ~[stormjar.jar:?] at org.apache.http.impl.client.AbstractHttpClient.createHttpContext(AbstractHttpClient.java:286) ~[stormjar.jar:?] at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:851) ~[stormjar.jar:?] at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805) ~[stormjar.jar:?] at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784) ~[stormjar.jar:?] at com.trinity.sensors.LocationName.getPlaceName(LocationName.java:77) ~[stormjar.jar:?] at com.trinity.sensors.ItmsVehicleDataBolt.execute(ItmsVehicleDataBolt.java:126) ~[stormjar.jar:?] at backtype.storm.topology.BasicBoltExecutor.execute(BasicBoltExecutor.java:50) ~[storm-core-0.10.0.2.4.3.0-227.jar:0.10.0.2.4.3.0-227] at backtype.storm.daemon.executor$fn__6713$tuple_action_fn__6715.invoke(executor.clj:684) ~[storm-core-0.10.0.2.4.3.0-227.jar:0.10.0.2.4.3.0-227] at backtype.storm.daemon.executor$mk_task_receiver$fn__6636.invoke(executor.clj:431) ~[storm-core-0.10.0.2.4.3.0-227.jar:0.10.0.2.4.3.0-227] at backtype.storm.disruptor$clojure_handler$reify__1319.onEvent(disruptor.clj:58) ~[storm-core-0.10.0.2.4.3.0-227.jar:0.10.0.2.4.3.0-227] at backtype.storm.utils.DisruptorQueue.consumeBatchToCursor(DisruptorQueue.java:120) ~[storm-core-0.10.0.2.4.3.0-227.jar:0.10.0.2.4.3.0-227] at backtype.storm.utils.DisruptorQueue.consumeBatchWhenAvailable(DisruptorQueue.java:99) ~[storm-core-0.10.0.2.4.3.0-227.jar:0.10.0.2.4.3.0-227] at backtype.storm.disruptor$consume_batch_when_available.invoke(disruptor.clj:80) ~[storm-core-0.10.0.2.4.3.0-227.jar:0.10.0.2.4.3.0-227] at backtype.storm.daemon.executor$fn__6713$fn__6726$fn__6777.invoke(executor.clj:813) ~[storm-core-0.10.0.2.4.3.0-227.jar:0.10.0.2.4.3.0-227] at backtype.storm.util$async_loop$fn__544.invoke(util.clj:479) [storm-core-0.10.0.2.4.3.0-227.jar:0.10.0.2.4.3.0-227] at clojure.lang.AFn.run(AFn.java:22) [clojure-1.6.0.jar:?] at java.lang.Thread.run(Thread.java:745) [?:1.8.0_77] 2018-05-29 09:21:27.164 b.s.d.executor [ERROR]
问题根源
这个错误本质是Apache HttpClient版本冲突。Storm集群本身自带了一个HttpClient版本,而你打包到stormjar.jar里的代码又引入了另一个版本的HttpClient。两个版本不兼容,导致运行时JVM找不到DEF_CONTENT_CHARSET字段——这个字段在HttpClient 4.2及更早版本中存在,但在4.3+的版本中被移除重构了,反过来如果Storm用的是新版本、你带的是旧版本也会出问题。
具体解决方案
1. 排除冲突依赖,复用Storm的版本
在你的项目构建文件(Maven的pom.xml或Gradle的build.gradle)里,把自己依赖的HttpClient中与Storm冲突的部分排除,或者直接标记为provided,让Storm集群的版本生效:
Maven示例:
<!-- 方式1:排除冲突的子依赖 --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>你的版本号</version> <exclusions> <exclusion> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> </exclusion> </exclusions> </dependency> <!-- 方式2:直接使用Storm提供的版本,不打包到jar里(更推荐) --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>与Storm匹配的版本</version> <scope>provided</scope> </dependency>
Gradle示例:
dependencies { // 排除冲突子依赖 implementation('org.apache.httpcomponents:httpclient:你的版本号') { exclude group: 'org.apache.httpcomponents', module: 'httpcore' } // 或者使用provided scope复用集群版本 provided 'org.apache.httpcomponents:httpclient:匹配Storm的版本' }
2. 替换过时的HttpClient API
如果你的代码还在使用DefaultHttpClient(这个类从HttpClient 4.3开始就被标记为过时),建议换成新的CloseableHttpClient和HttpClientBuilder,既能避免依赖旧字段,还能获得更好的性能和兼容性:
// 替换旧的DefaultHttpClient创建方式 CloseableHttpClient httpClient = HttpClientBuilder.create() .setDefaultRequestConfig(RequestConfig.custom() .setConnectTimeout(5000) // 设置连接超时 .setSocketTimeout(5000) // 设置读取超时 .build()) .build(); // 执行HTTP请求的示例 HttpGet httpGet = new HttpGet("你的请求URL"); try (CloseableHttpResponse response = httpClient.execute(httpGet)) { // 处理响应逻辑 HttpEntity entity = response.getEntity(); if (entity != null) { String content = EntityUtils.toString(entity, StandardCharsets.UTF_8); // 后续业务处理 } } catch (IOException e) { // 异常处理逻辑 } finally { // 关闭客户端,释放资源 httpClient.close(); }
3. 确认Storm集群的HttpClient版本
登录Storm集群节点,找到storm-core-0.10.0.2.4.3.0-227.jar,解压后查看内部依赖,或者查看Storm官方的依赖清单,确保你项目中使用的HttpClient版本和集群完全一致,从根源避免冲突。
内容的提问来源于stack exchange,提问作者Mahabaleshwar
相关产品推荐
相关产品推荐

