Java-查看JVM从哪个JAR包中加载指定类
生活随笔
收集整理的這篇文章主要介紹了
Java-查看JVM从哪个JAR包中加载指定类
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
- 背景
- 方式一
- 方式二
背景
有的時候,我們經常會碰到java.lang.NoSuchMethodError的錯誤信息。
究其根源,是由于JVM的 全盤負責委托機制導致的。
關于 全盤負責委托機制 ,請查看另一篇博文 全盤負責委托機制
特別是對于一些web項目,jar包很多,如何精確的查找呢?
方式一
將下面的JSP文件,放到web容器的根路徑下,啟動web容器,通過 http://ip:port/projectname/srcAdd.jsp?className=XXXXXX
比如:
運行web項目,訪問
http://localhost:8080/hello-spring4/srcAdd.jsp?className=org.springframework.beans.factory.annotation.AutowiredsrcAdd.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>方式二
工具類 ClassLocationUtils.java
package com.xgj.master.ioc.classloaderUtil;import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.security.CodeSource; import java.security.ProtectionDomain;/*** * @ClassName: ClassLocationUtils* @Description: tools to find which jar does the class come from * */ public class ClassLocationUtils {/*** find the location of the class come from* @param cls* @return*/public static String where(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();if (pd != null) {final CodeSource cs = pd.getCodeSource();if (cs != null) result = cs.getLocation();if (result != null) {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) {final ClassLoader clsLoader = cls.getClassLoader();result = clsLoader != null ?clsLoader.getResource(clsAsResource) :ClassLoader.getSystemResource(clsAsResource);}System.out.println(result.toString());return result.toString();}}運行查找
package com.xgj.master.ioc.classloader;import com.xgj.master.ioc.classloaderUtil.ClassLocationUtils;public class ClassLoaderTest {public static void main(String[] args) {// TODO Auto-generated method stubClassLocationUtils.where(java.lang.Thread.class);}}運行結果:
總結
以上是生活随笔為你收集整理的Java-查看JVM从哪个JAR包中加载指定类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux-编写Shell的几个技巧
- 下一篇: Java-利用Spring提供的Reso