这两个工具的作用:
- 找某个jar包下某个class某个方法
- 查看java类在那个jar包下。
解决:服务器上java程序报错:ClassNotFoundException,NoClassDefFoundError下边有补充解析。
只需要依赖jdk,直接复制这个类去某个机器上跑一下就可以,方便快捷
查看java类在那个jar包
java添加classpath
linux示例:添加 -classpath xxx/xxx.jar:xxx/xxx.jar
如果是windows用;分割,如果是mac和linux用:分割
java编译
javac -d . xxx.java
点代表当前目录如果没报名可以不加-d .
示例
javac -d . Test.java
运行
java com.dxz.chama.javaagent.asm.Test
如果添加class资源运行
java -classpath xxx/xxx.jar:xxx/xxx.jar com.dxz.chama.javaagent.asm.Test
package com.dxz.chama.javaagent.asm;
import java.net.URL;
/**
* description: 查找某个类在那个jar包下
*
* @author: he QQ: 905845006
* @email: 905845006@qq.com
* @date: 2020/8/15 5:39 PM
*/
public class Test {
public static void main(String args[]) {
Class targetclass = String.class;
String className = targetclass.getName();
className= "sun.net.www.protocol.http.HttpURLConnection";
className = className.replace('.', '/');
String resource = "/" + className + ".class";
URL url = targetclass.getResource(resource);
System.out.println(url.getFile());
// 输出结果:
// file:/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/rt.jar!/sun/net/www/protocol/http/HttpURLConnection.class
}
}
查看jar包下java类
package com.dxz.chama.javaagent.asm;
/**
* description:
*
* @author: he QQ: 905845006
* @email: 905845006@qq.com
* @date: 2020/8/15 3:11 PM
*/
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class jarTest {
public static void getJarName(String jarFile) throws Exception {
getJarName(jarFile,null);
}
public static void getJarName(String jarFile, String clazz) throws Exception {
try {
//通过将给定路径名字符串转换为抽象路径名来创建一个新File实例
File f = new File(jarFile);
URL url1 = f.toURI().toURL();
URLClassLoader myClassLoader = new URLClassLoader(new URL[]{url1}, Thread.currentThread().getContextClassLoader());
//通过jarFile和JarEntry得到所有的类
JarFile jar = new JarFile(jarFile);
//返回zip文件条目的枚举
Enumeration<JarEntry> enumFiles = jar.entries();
JarEntry entry;
System.out.println(enumFiles);
//测试此枚举是否包含更多的元素
while (enumFiles.hasMoreElements()) {
entry = (JarEntry) enumFiles.nextElement();
if (entry.getName().indexOf("META-INF") < 0) {
String classFullName = entry.getName();
if (!classFullName.endsWith(".class")) {
classFullName = classFullName.substring(0, classFullName.length() - 1);
} else {
//去掉后缀.class
String className = classFullName.substring(0, classFullName.length() - 6).replace("/", ".");
if (className.equals("module-info")) {
System.out.println("is jdk9 continue");
continue;
}
//如果传入指定类 只查看指定类
if (clazz != null && !className.equals(clazz)) {
continue;
}
System.out.println("className:"+className);
Class<?> myclass = myClassLoader.loadClass(className);
//打印类名
System.out.println("*****************************");
System.out.println("全类名:" + className);
//得到类中包含的属性
Method[] methods = myclass.getMethods();
for (Method method : methods) {
String methodName = method.getName();
System.out.println("方法名称:" + methodName);
Class<?>[] parameterTypes = method.getParameterTypes();
for (Class<?> clas : parameterTypes) {
// String parameterName = clas.getName();
String parameterName = clas.getSimpleName();
System.out.println("参数类型:" + parameterName);
}
System.out.println("==========================");
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 这些默认方法不打印
*/
private static String DEFAULT_METHOD = "waitequalsnotifynotifyAlltoStringhashCodegetClass";
//必须传1个参数,指定的jar包,如果传2个参数,第一个为jar包,第二个为需要找的类
public static void main(String[] args) throws Exception {
//jar包所在路径
/*getJarName("F:\\user.jar");
getJarName("F:\\role1.jar");
getJarName("F:\\role2.jar"); */
//getJarName("F:\\UserInfo.jar");
String jarz = null;
String clazz = null;
if(args.length>1){
jarz = args[0];
clazz = args[1];
}else{
jarz = args[0];
}
if (jarz != null) {
getJarName(jarz);
}
//org.apache.tools.ant.util.ResourceUtils$ResourceSelectorProvider
if (jarz != null && clazz != null) {
System.out.println("示例类格式:org.apache.tools.ant.util.ResourceUtils$ResourceSelectorProvider");
getJarName(jarz, clazz);
}
//测试
// getJarName("/Users/heliming/IdeaProjects/bugokhttp/asm6/target/asm6-1.0-SNAPSHOT.jar");
}
}
补充:
ClassNotFoundException解释:
当应用程序运行的过程中尝试使用类加载器去加载Class文件的时候,如果没有在classpath中查找到指定的类,就会抛出ClassNotFoundException。一般情况下,当我们使用Class.forName()或者ClassLoader.loadClass以及使用ClassLoader.findSystemClass()在运行时加载类的时候,如果类没有被找到,那么就会导致JVM抛出ClassNotFoundException。
NoClassDefFoundError解释:
当JVM在加载一个类的时候,如果这个类在编译时是可用的,但是在运行时找不到这个类的定义的时候,JVM就会抛出一个NoClassDefFoundError错误。比如当我们在new一个类的实例的时候,如果在运行是类找不到,则会抛出一个NoClassDefFoundError的错误。
来源:oschina
链接:https://my.oschina.net/u/3730149/blog/4497189