java.lang.NoSuchMethodError解决办法

但凡Java的开发者,想必遇到过java.lang.NoSuchMethodError的错误信息吧。究其源,这个错误基本上都是由JVM的"全盘负责委托机制"引发的问题:因为在类路径下放置了多个不同版本的类包,如commons-lang 2.x.jar和commons-lang3.x.jar都位于类路径中,代码中用到了commons-lang3.x类的某个方法,而这个方法在commons-lang2.x中并不存在,JVM加载类时碰巧又从commons-lang 2.x.jar中加载类,运行时就会抛出NoSuchMethodError的错误。

这种问题的排查是比较棘手的,特别是在Web应用的情况下,可作为类路径的系统目录比较多,特别在类包众多时,情况尤其复杂:你不知道JVM到底从哪个类包中加载类文件。不过笔者有一个一般人不告诉的易用小工具,现奉献出来:

在光盘根路径下有一个srcAdd.jsp的程序,你把它放到Web应用的根路径下,通过如下方式即可查看JVM从哪个类包加载指定类:


 
 
  1. http://localhost/srcAdd.jsp?className=java.net.URL

<span style="font-size:18px;">      </span><span style="font-family:Microsoft YaHei;font-size:14px;">srcAdd.jsp</span>
<pre name="code" class="html"><span style="font-family:Microsoft YaHei;font-size:14px;"><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
<%@ page import="java.security.*,java.net.*,java.io.*"%>  
<%!  
    public static URL getClassLocation(final Class cls)   
    {  
        if(cls==null)  
        {  
            throw new IllegalArgumentException("null input: cls");  
        }  
        URL result=null;  
        final String clsAsResource=cls.getName().replace('.', '/').concat(".class");  
        final ProtectionDomain pd=cls.getProtectionDomain();  
        // java.lang.Class contract does not specify if 'pd' can ever be null;  
        // it is not the case for Sun's implementations, but guard against null  
        // just in case:  
        if(pd != null)   
        {  
            final CodeSource cs=pd.getCodeSource();  
            // 'cs' can be null depending on the classloader behavior:  
            if(cs != null)   
            {  
                result=cs.getLocation();  
            }  
            if(result != null)   
            {  
                // Convert a code source location into a full class file location  
                // for some common cases:  
                if("file".equals(result.getProtocol()))   
                {  
                    try   
                    {  
                        if(result.toExternalForm().endsWith(".jar") || result.toExternalForm().endsWith(".zip"))  
                        {  
                            result=new URL("jar:".concat(result.toExternalForm()).concat("!/").concat(clsAsResource));  
                        }  
                        else if(new File(result.getFile()).isDirectory())  
                        {  
                            result=new URL(result, clsAsResource);  
                        }  
                    }  
                    catch(MalformedURLException ignore)   
                    {  
                      
                    }  
                }  
            }  
        }  
        if(result == null)   
        {  
            // Try to find 'cls' definition as a resource; this is not  
            // document.d to be legal, but Sun's implementations seem to         //allow this:  
            final ClassLoader clsLoader=cls.getClassLoader();  
            result=clsLoader != null ? clsLoader.getResource(clsAsResource) : ClassLoader.getSystemResource(clsAsResource);  
        }  
        return result;  
    }  
%>  
<html>  
<head>  
<title>srcAdd.jar</title>  
</head>  
<body bgcolor="#ffffff">  
    使用方法,className参数为类的全名,不需要.class后缀,如  
    srcAdd.jsp?className=java.net.URL  
<%  
    try  
    {  
        String classLocation=null;  
        String error=null;  
        String className=request.getParameter("className");  
        classLocation=""+getClassLocation(Class.forName(className));  
        if(error == null)   
        {  
            out.print("类" + className + "实例的物理文件位于:");  
            out.print("<hr>");  
            out.print(classLocation);  
        }  
        else   
        {  
            out.print("类" + className + "没有对应的物理文件。<br>");  
            out.print("错误:" + error);  
        }  
    }  
    catch(Exception e)  
    {  
        out.print("异常。"+e.getMessage());  
    }  
%>  
</body>  
</html></span>


                
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值