You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:54:03