Java扩展应用程序类加载器?
问题:我的公司有很多不同的罐子/现有项目,它们在客户中运行。 为了进行调试,我们希望生成一个日志,其中每个组件加载哪个类,更具体地说: 从哪里开始 。 例如:jar StackOverFlowJar.jar中的stack.overflow.ClassA。
我的想法:我已经尝试将每个jar /现有项目传递给一个自定义类加载器。 这个自定义类加载器可能会将上面的信息写入文件,并将正常的类加载流委派给其父代。
我的CustomClassLoader扩展了ClassLoader,我可以看到它加载类如:
java.lang.Class
java.lang.Thread
java.lang.ThreadGroup
等等,核心库中的所有标准Java类。 这些类可以到达我的CustomClassLoader。 但是,如下图所示:
来源:http://javarevisited.blogspot.nl/2012/12/how-classloader-works-in-java.html
有多个ClassLoaders。 引导类加载器(我用我的CustomClassLoader扩展的那个)只负责核心库。 如果找不到自定义创建的类,它将把它委托给扩展类加载器。 如果扩展类加载器找不到它,它会将它委派回应用程序类加载器,并且我可以在调试模式中看到,这确实是加载我的自定义类的一个。 但它不通过我的CustomClassLoader。
我的问题:是否可以扩展Application ClassLoader和扩展ClassLoader? 或者,对于我的问题,或许还有另一种解决方法?
非常感谢您提前!
您可以创建一个简单的Jar文件,在类路径中使用该Jar来运行该文件。 然后你可以有一个扩展了URLClassLoader
的类,将这个对象传递给你真实的类路径,通过你的ClassLoader加载你的真正的主类,并且使用反射调用main方法。
示例主要方法
public static void main (String... args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
URL[] classpath = new URL[0];
LoggingClassLoader loggingClassLoader = new LoggingClassLoader(classpath, Main.class.getClassLoader());
Class<?> aClass = loggingClassLoader.loadClass("com.company.project.RealMain");
Method main = aClass.getMethod("main", args.getClass());
main.invoke(null);
}
示例类加载器对象
编辑
我稍微扩展了这个例子,现在每个jar / URL有一个加载器,以防你需要跟踪从哪个jar加载哪个类:
public static class LoggingClassLoader extends URLClassLoader {
final List<ChildLogger> childLochildLoggersders = new ArrayList<>();
public LoggingClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
for(URL url : urls) {
childLochildLoggersders.add(new ChildLogger(url, this));
}
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
for(ChildLogger childLoader : childLochildLoggersders) {
try {
return childLoader.loadClass(name);
} catch(ClassNotFoundException ignore) {
}
}
throw new ClassNotFoundException(name);
}
private static class ChildLogger extends URLClassLoader {
private final URL url;
private ChildLogger(URL url, ClassLoader parent) {
super(new URL[]{url}, parent);
this.url = url;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> aClass = super.findClass(name);
System.out.println("Loaded from :" + url + " class: " + name);
return aClass;
}
}
}
你也可以使用
-verbose:类
JVM选项可打印加载类的位置。 https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
链接地址: http://www.djcxy.com/p/44397.html上一篇: Java extend Application Classloader?
下一篇: java.lang.NoClassDefFoundError, Ant task could not see classes in jar inside jar