【问题标题】:NoSuchFieldError INSTANCE at org.apache.http.impl.io.DefaultHttpRequestWriterFactoryorg.apache.http.impl.io.DefaultHttpRequestWriterFactory 的 NoSuchFieldError 实例
【发布时间】:2017-11-30 00:42:44
【问题描述】:
java version "1.7.0_71" 
Gradle 2.1

你好,

UPDATE:

依赖关系

gradle dependencies | grep httpcore
|    +--- org.apache.httpcomponents:httpcore:4.3.3
|    +--- org.apache.httpcomponents:httpcore:4.3.3
|    +--- org.apache.httpcomponents:httpcore:4.3.3
|    +--- org.apache.httpcomponents:httpcore:4.3.3
|    |         |    |         |    +--- org.apache.httpcomponents:httpcore:4.1 -> 4.3.3
|    +--- org.apache.httpcomponents:httpcore:4.3.3
|    |         |    |         |    +--- org.apache.httpcomponents:httpcore:4.1 -> 4.3.3

这是否意味着我有 4.1 是到 4.3.3 的软链接?似乎很奇怪,因为当我打印出类加载器正在加载的内容时,它似乎加载了 4.3.3:/home/steve/.gradle/caches/modules-2/files-2.1/org.apache.httpcomponents/httpcore/4.3.3/f91b7a4aadc5cf486df6e4634748d7dd7a73f06d/httpcore-4.3.3.jar 似乎很奇怪。

当我尝试运行我的 httpClient 时,我不断收到此错误。一切编译正常。

java.lang.NoSuchFieldError: INSTANCE
        at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:52

我的代码很简单,删除了不重要的代码以保持它的小:

public class GenieClient {
    private CloseableHttpClient mClient;

    public GenieClient() {
        ClassLoader classLoader = GenieClient.class.getClassLoader();
        URL resource = classLoader.getResource("org/apache/http/message/BasicLineFormatter.class");
        log.log(Level.INFO, "resource: " + resource);

        mClient = HttpClientBuilder.create().build();
    }

    public int sendRequest() {   
        int responseCode = -1;

        try {
            HttpResponse response = mClient.execute(new HttpPost("http://www.google.com"));
            responseCode = response.getStatusLine().getStatusCode();
        }
        catch(IOException ex) {
            log.log(Level.SEVERE, "IOException: " + ex.getMessage());
        }

        return responseCode;
    }
}

我从 classLoader 得到的输出是这样的:

INFO: resource: jar:file:/home/steve/.gradle/caches/modules-2/files-2.1/org.apache.httpcomponents/httpcore/4.3.3/f91b7a4aadc5cf486df6e4634748d7dd7a73f06d/httpcore-4.3.3.jar!/org/apache/http/message/BasicLineFormatter.class

我使用 gradle 作为我的构建工具,并在我的 build.gradle 文件中设置了这样的依赖项:

dependencies {
    compile 'org.apache.httpcomponents:httpclient:4.3.6'
}

我也尝试包含以下 httpcore,但仍然得到相同的错误:

compile 'org.apache.httpcomponents:httpcore:4.4'

一切正常,只有当我运行我的 httpClient 时,

非常感谢您的任何建议,

【问题讨论】:

  • 您的依赖关系树中的某处可能还有旧版本的 httpcore。 gradle dependencies 的输出是什么?
  • 您能否提供一个完整的、可运行的示例来说明问题?
  • 您在类路径中有不同的 httpcore 版本。尝试排除 httpcore 4.1,看起来您必须使用不同的 jar 执行 2 次。
  • 19x 500 赏金和 1800 代表在大约 10 个其他赏金中...... ant2009,你可能是我所知道的唯一一个拥有 60 金、185 银和 320 棕色徽章的人,花费大约 12k 代表在赏金 - 并且有 327 声望... 这个。是。疯狂!
  • @ToYonos 和 vaxquie,嗯,不知道我做错了什么,我在他们的规定的指导方针和政策中使用 SO。我已经成为会员很长时间了,在那段时间里,我发布了一些问题并回答了一些问题。 500点赏金是为了给其他成员的支持额外的功劳。

标签: java gradle apache-httpclient-4.x


【解决方案1】:

org.apache.httpcomponents:httpcore:4.1 -&gt; 4.3.3 表示4.1 是请求的版本,通过冲突解决将其解析为4.3.3。执行gradle -q dependencyInsight --configuration compile --dependency httpcore 之类的操作应该会让您对此有更多了解。

您应该检查构建输出,并查看您的应用实际打包了哪些 jar。此外,使用一些文件管理器通过构建输出(当然包括档案)运行搜索BasicLineFormatter.class,这应该会给您一个明确的答案,即哪些 jar 包含此类的哪个版本。

如果只有一个版本 (4.3.3),这一定意味着另一个版本来自运行您的应用的容器。解决此问题的方法取决于容器。

如果您确实找到多个版本,您可以尝试在项目中全局排除对httpcore 的传递依赖(user guide 的第 51.4.7 章)。

如果您为特定配置定义排除项,则在解析此配置或任何继承配置时,将为所有依赖项过滤排除的传递依赖项。

【讨论】:

    【解决方案2】:

    好像BasicLineFormatter 得到了它的静态INSTANCE in 4.3-beta1 linklink

    【讨论】:

      【解决方案3】:

      用 -verbose:class 启动你的 jvm,它会显示从哪里加载哪个类。

      我过去在两种情况下遇到过这样的问题:

      1. 您正在加载的其中一个 jar 包含一个带有 Classpath 子句的清单,该子句引用了不正确的 httpcore 版本。

      2. 您正在使用自己的类加载器在某个容器(tomcat 或某物)中运行,并且某些类已加载,例如由另一个罐子里的容器。

      我也不认为您显示该类资源的代码有效,因为它明确使用了 GenieClient 的类加载器。可能使用BasicLineFormatter.class.getClassloader() 会产生不同的结果。 但最好试试-verbose:class

      【讨论】:

        【解决方案4】:

        很明显,在您的类路径中有一些旧版本的BasicLineFormatter,它具有DEFAULT 字段而不是INSTANCE。见e.g

        但是您的类加载器报告您正在使用 httpcore-4.3.3,并且您的 Gradle 依赖关系树支持了这一点。

        因此,您似乎还有其他一些 JAR,其中包含旧版本的 BasicLineFormatter。您可能需要检查您的依赖项 JAR 并查看它是否在其中。试试jar tf *.jar | grep 'BasicLineFormatter' 看看可能涉及哪些 JAR。

        此外,这可能是相关的。我看了你的标签,看来你做了一些 Android 开发。所以下面的 Stack Overflow question 可能会很有趣:

        即使这不是确切的问题,它也显示了即使你有正确的 httpcore 依赖项,你也可能有一个旧的BasicLineFormatter

        【讨论】:

          【解决方案5】:
          1. 找到比 4.3 更旧的 httpcore 版本
          2. 从引用的库中删除旧版本的 httpcore jar。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-02-06
            • 2022-01-22
            • 2014-05-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多