定义字段时出现 java.lang.NoSuchFieldError 异常
我正在为 Apache Tomcat 开发一个 Web 应用程序。 我使用一个名为 Location 的类,在其中定义了一个名为 ipAddresses 的字段。如下:
package com.maxmind.geoip;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
public class Location {
private final static double EARTH_DIAMETER = 2 * 6378.2;
private final static double PI = 3.14159265;
private final static double RAD_CONVERT = PI / 180;
public Set<String> ipAddresses;
public String countryCode;
public String countryName;
public String region;
public String city;
public String postalCode;
public float latitude;
public float longitude;
public int dma_code;
public int area_code;
public int metro_code;
public Location() {
ipAddresses = new HashSet<String>();
}
...
}
但是,在将 web 应用程序部署到服务器(war 文件)并尝试运行其中使用此类的 servlet 后,我收到异常 java.lang.NoSuchFieldError ip地址。
此外,当尝试调试它(Eclipse)时,当我到达调用 Location loc = new Location() 的地方时,会发生两件奇怪的事情:
- 我编码的构造函数没有被调用,调试器不会进入其中,而是程序计数器箭头显示在 Location.java 文件中的导入上。
- 从 Location loc = new Location() 调用“返回”后,当我查看对象的内容时,该字段实际上不存在。
- 使用 jar 文件部署的源文件确实包含此字段。
我尝试了很多事情:
- 清理和构建项目并重新部署它。
- 手动或使用 Eclipse 清理服务器的工作目录。
- 在 Eclipse 中更改服务器的工作目录。
- 在 Eclipse 中重新安装服务器。
- 完全重新安装 Tomcat,三次并安装到不同的位置!
我很困惑。可能是什么?
I'm working on a web application for Apache Tomcat.
I'm using a class called Location in which i defined a field called ipAddresses. Here it is:
package com.maxmind.geoip;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
public class Location {
private final static double EARTH_DIAMETER = 2 * 6378.2;
private final static double PI = 3.14159265;
private final static double RAD_CONVERT = PI / 180;
public Set<String> ipAddresses;
public String countryCode;
public String countryName;
public String region;
public String city;
public String postalCode;
public float latitude;
public float longitude;
public int dma_code;
public int area_code;
public int metro_code;
public Location() {
ipAddresses = new HashSet<String>();
}
...
}
However, after deploying the webapp to the server (war file) and trying to run the servlet that is using this class in it, i'm getting the exception java.lang.NoSuchFieldError for ipAddresses.
Moreover, when trying to debug it (Eclipse), when i reach a place where Location loc = new Location() is called, two weird things happen:
- The constructor i coded isn't called, the debugger won't step into it, instead the program counter arrow is shown on on of the imports of in the Location.java file.
- After "returning" from the Location loc = new Location() call, when i'm viewing the object's content the field actually does not exist.
- The source file that was deployed with the jar file does include this field.
I have tried many things:
- cleaning and building the project and redeploying it.
- cleaning the server's working directory, both manual and by using Eclipse.
- changing the working directory of the server, in Eclipse.
- re-installing the server in Eclipse.
- re-installing Tomcat entirely, three times and to different locations!
I'm pretty stuck. What could it be?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你到底在使用这个领域吗?有没有相关的参考资料? Eclipse 完全有可能正在优化它。
在
Windows->Preferences->Java->Compiler
中,有一个设置:保留未使用的(从不读取)局部变量
。这个检查了吗?如果没有,请检查并重试。Are you using the field at all? Are there any references to it?. It is entirely possible that Eclipse is optimising it away.
In
Windows->Preferences->Java->Compiler
, there is a setting:Preserve unused (never read) local variables
. Is this checked? If not, check it and try again.这些症状表明您在
JRE/lib
或JRE/lib/ext
的某些 JAR 中具有com.maxmind.geoip.Location
类或任何其他独立于 Eclipse/Tomcat 的类路径位置,这些位置在类加载中始终优先于 WAR 的类。构建后检查 loc.getClass().getProtectionDomain().getCodeSource().getLocation() 应该可以深入了解它的实际加载位置。
The symptoms indicate that you have the
com.maxmind.geoip.Location
class in some JAR in theJRE/lib
orJRE/lib/ext
or any other Eclipse/Tomcat-independent classpath location which will always have precedence in classloading over the WAR's classes.Examining the
loc.getClass().getProtectionDomain().getCodeSource().getLocation()
after you construct it should give insights about where it is actually been loaded from.