zoukankan      html  css  js  c++  java
  • Jar包冲突及java.lang.NoSuchMethodError异常解决方案(转载)

    问题

    在编码过程中,往往会遇到jar包冲突的问题。问题的表现特征一般都是抛出java.lang.NoSuchMethodError异常。那么,今天就聊聊怎么解决此类问题。

    分析

    此问题跟java的类加载机制有关。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从哪个类包加载指定类(其中className为className参数为类的全名,不需要.class后缀,端口号为web项目的端口号,此处为80):

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

    srcAdd.jsp源码如下:

    <%@page contentType="text/html; charset=GBK"%>
    <%@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>

    原文链接:http://blog.csdn.net/wo541075754/article/details/48243403

  • 相关阅读:
    leetcode 131. Palindrome Partitioning
    leetcode 526. Beautiful Arrangement
    poj 1852 Ants
    leetcode 1219. Path with Maximum Gold
    leetcode 66. Plus One
    leetcode 43. Multiply Strings
    pytorch中torch.narrow()函数
    pytorch中的torch.repeat()函数与numpy.tile()
    leetcode 1051. Height Checker
    leetcode 561. Array Partition I
  • 原文地址:https://www.cnblogs.com/CryOnMyShoulder/p/8464532.html
Copyright © 2011-2022 走看看