有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

类加载器在Java中,使用引导加载器时是否可以知道是否已经加载了类?

这是In Java, is it possible to know whether a class has already been loaded?的一个变体。我们的应用程序执行字节码插装,并使用-Xbootclasspath/a:选项来插装Java运行时。我想知道是否已经通过引导加载程序加载了一个类,而没有尝试加载它

如果类是由引导加载程序加载的,则引用查询中列出的代码将不起作用,因为我不相信有任何方法可以获取引导加载程序的实例以在调用中使用

有什么想法吗?我怀疑这是做不到的。这对我们的应用并不重要,但我很好奇


共 (2) 个答案

  1. # 1 楼答案

    当您想要执行运行时字节码指令插入时,应该使用the Instrumentation API实现Java代理

    当Java代理的参数类型被声明为(String agentArgs, Instrumentation inst)时,它将在其premainagentmain方法中获得一个^{}实例

    此API允许在运行时使用appending jar files to the bootstrap class path,因此不需要依赖命令行上指定的-Xbootclasspath/a选项

    此外,它还有方法^{}^{}来查询已经加载的类。因此,您可以使用getInitiatedClasses(null)获取引导加载程序当前加载的所有类。您必须迭代它们并自己比较名称,以确定数组中是否包含特定的类

  2. # 2 楼答案

    好吧,疯狂的想法

    您可以在描述的线程中使用相同的技术,尝试不同的方法。类类加载器具有以下方法:

    private Class<?> findBootstrapClassOrNull(String name)
    

    此方法调用本机方法:

    private native Class<?> findBootstrapClass(String name)
    

    你也可以试着让它变得容易接近

    编辑:不过,我已经尝试了从应用程序类加载器运行的以下代码:

    public class MyClassLoader extends ClassLoader {
        public static void main(String[] args)
                throws NoSuchMethodException,
                InvocationTargetException,
                IllegalAccessException {
            Method method = ClassLoader.class.getDeclaredMethod(
                    "findBootstrapClass", String.class);
            method.setAccessible(true);
            MyClassLoader cl = new MyClassLoader();
            System.out.println(method.invoke(cl, "java.lang.String"));
            System.out.println(method.invoke(cl, "sun.java2d.loops.GraphicsPrimitiveMgr$2"));
        }
    }
    

    (顺便说一句,这段代码不必扩展ClassLoader,我只是在上一个测试中留下了这个,在这个测试中,我从ClassLoader调用了一个受保护的方法。)

    无论我提供什么类,在我的主要方法运行时,似乎几乎所有的东西都已加载,但不确定。从“findBootstrapClass”方法的源代码中,我可以看到:

        /**
         * Returns a class loaded by the bootstrap class loader;
         * or return null if not found.
         */
        private Class<?> findBootstrapClassOrNull(String name)
    

    所以,除非在代码被检测时得到不同的结果,否则我认为这可能是不可行的

    注意:同样,我看到的源代码是针对OpenJDK 1.8的

    祝你好运