Java NoSuchFieldError INSTANCE 在 org.apache.http.impl.io.DefaultHttpRequestWriterFactory
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27921077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NoSuchFieldError INSTANCE at org.apache.http.impl.io.DefaultHttpRequestWriterFactory
提问by ant2009
java version "1.7.0_71"
Gradle 2.1
Hello,
你好,
UPDATE:
The dependencies
依赖关系
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
Does this mean I have 4.1 that is a soft link to 4.3.3? Seems strange as when I print out what the class loader is loading it seems to load 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
seems very strange.
这是否意味着我的 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
看起来很奇怪。
I keep getting this error when I try and run my httpClient. Everything compiles ok.
当我尝试运行我的 httpClient 时,我不断收到此错误。一切编译正常。
java.lang.NoSuchFieldError: INSTANCE
at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:52
My code is very simple, removed not important code to keep it small:
我的代码很简单,删除了不重要的代码以保持小:
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;
}
}
The output I get from the classLoader is this:
我从 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
I am using gradle as my build tool and have set the dependencies like this in my build.gradle
file:
我使用 gradle 作为我的构建工具,并在我的build.gradle
文件中设置了这样的依赖项:
dependencies {
compile 'org.apache.httpcomponents:httpclient:4.3.6'
}
I have also tried to include the following httpcore, but still get the same error:
我还尝试包含以下 httpcore,但仍然出现相同的错误:
compile 'org.apache.httpcomponents:httpcore:4.4'
Everything builds ok, its only when I run my httpClient,
一切正常,只有当我运行我的 httpClient 时,
Many thanks for any suggestions,
非常感谢您的任何建议,
采纳答案by Predrag Maric
org.apache.httpcomponents:httpcore:4.1 -> 4.3.3
means 4.1
is the requested version, which is resolved to 4.3.3
by conflict resolution. Executing something like gradle -q dependencyInsight --configuration compile --dependency httpcore
should give you more insight on this.
org.apache.httpcomponents:httpcore:4.1 -> 4.3.3
mean4.1
是请求的版本,它4.3.3
通过冲突解决来解决。执行类似的操作gradle -q dependencyInsight --configuration compile --dependency httpcore
应该能让你更深入地了解这一点。
You should check the build output, and see what jars are actually packaged with your app. Also, using some file manager run a search for BasicLineFormatter.class
through the build output (including archives, of course), this should give you a definite answer what jars contain what version of this class.
您应该检查构建输出,并查看您的应用程序实际打包了哪些 jar。此外,使用一些文件管理器BasicLineFormatter.class
通过构建输出(当然包括档案)运行搜索,这应该会给你一个明确的答案,哪些 jars 包含这个类的哪个版本。
If there is only one version (4.3.3) this must mean that the other version comes from the container that's running your app. Ways of resolving this depend on the container.
如果只有一个版本 (4.3.3),这一定意味着另一个版本来自运行您的应用程序的容器。解决这个问题的方法取决于容器。
If you do find multiple versions, you can try excluding transitive dependency to httpcore
globally in the project (chapter 51.4.7 of user guide).
如果确实找到多个版本,可以尝试httpcore
在项目中排除对全局的传递依赖(用户指南第 51.4.7 章)。
If you define an exclude for a particular configuration, the excluded transitive dependency will be filtered for all dependencies when resolving this configuration or any inheriting configuration.
如果您为特定配置定义了排除项,则在解析此配置或任何继承配置时,将针对所有依赖项过滤排除的传递依赖项。
回答by mabn
Start your jvm with -verbose:class, it will show which class is being loaded from where.
使用 -verbose:class 启动您的 jvm,它将显示从何处加载哪个类。
I had such problems in the past in two scenarios:
我过去在两种情况下遇到过这样的问题:
one of the jars you're loading has a manifest with Classpath clause which references incorrect version of httpcore.
you're running within some container (tomcat or sth) with own classloaders and some classes are loaded e.g. by the container from a different jar.
您正在加载的其中一个 jar 有一个带有 Classpath 子句的清单,它引用了不正确的 httpcore 版本。
您正在使用自己的类加载器在某个容器(tomcat 或 sth)中运行,并且某些类是由来自不同 jar 的容器加载的。
I also don't think your code showing resource for the class works as it explicitly uses GenieClient's classloader. Probably using BasicLineFormatter.class.getClassloader()
would give different results.
But better try with -verbose:class
.
我也不认为您的代码显示该类的资源有效,因为它显式使用 GenieClient 的类加载器。可能使用BasicLineFormatter.class.getClassloader()
会产生不同的结果。但最好尝试使用-verbose:class
.
回答by mabn
Clearly there is some older version of BasicLineFormatter
on your classpath, one that has the DEFAULT
field instead of INSTANCE
. See e.g.
很明显BasicLineFormatter
,您的类路径上有一些旧版本,其中包含DEFAULT
字段而不是INSTANCE
. 见例如。
But your classloader is reporting that you're using httpcore-4.3.3, and your Gradle dependency tree backs that up.
但是您的类加载器报告您正在使用 httpcore-4.3.3,并且您的 Gradle 依赖关系树支持这一点。
So it seems that you have some other JAR that has an old version of BasicLineFormatter
in it. You might need to go through your dependency JARs and just look to see whether it is in there. Try a jar tf *.jar | grep 'BasicLineFormatter'
to see which JARs might be involved.
因此,您似乎还有其他一些带有旧版本的 JAR BasicLineFormatter
。您可能需要查看您的依赖 JAR 并查看它是否在那里。尝试jar tf *.jar | grep 'BasicLineFormatter'
查看可能涉及哪些 JAR。
Also, this maybe relevant. I looked at your tags and it seems you do some Android development. So the following Stack Overflow questionmay be of interest:
此外,这可能是相关的。我查看了您的标签,似乎您进行了一些 Android 开发。因此,以下 Stack Overflow问题可能会引起您的兴趣:
Even if that's not the exact issue, it shows how you might have an old BasicLineFormatter
hanging around even if you have the right httpcore dependency.
即使这不是确切的问题,它也显示了BasicLineFormatter
即使您有正确的 httpcore 依赖项,您也可能会遇到旧的问题。
回答by atish shimpi
回答by Saurabh Saha
- find httpcore which is of an older version than 4.3
- remove the older version of httpcore jar from Referenced Libraries.
- 找到比 4.3 旧版本的 httpcore
- 从参考库中删除旧版本的 httpcore jar。