代码之家  ›  专栏  ›  技术社区  ›  Grundlefleck anujkk

是否可以在运行时指定系统类加载器加载.class文件?

  •  5
  • Grundlefleck anujkk  · 技术社区  · 15 年前

    我正在为作业编写一个静态分析工具,它使用ASM库分析Java字节码。我们使用的ASM的一个部分要求(或者至少看起来要求)从类加载器加载类。

    我们希望该工具能够分析.class文件,而不需要它们在类路径上。我们已经在运行时从指定目录加载了.class,并使用InputStream将它们读入。在大多数情况下,这对于ASM是可以接受的。有一些类,例如 SimpleVerifier ,它尝试加载类。

    Class.forName() 你会加载它们吗?或者有没有一种简单的方法来扩展类加载器来实现这一点?


    编辑:有关 URLClassLoader 这是有用的。不幸的是,使用 Thread.currentThread().setContextClassLoader() getClass().getClassLoader() .

    我是否正确理解了回答?是否可以使用URLClassLoader加载第三方类?

    6 回复  |  直到 8 年前
        2
  •  5
  •   Eugene Kuleshov    8 年前

    首先,ASM的使用方式可以避免使用ClassLoader获取类的信息。

    ASM框架中有几个地方默认加载类,但所有这些地方都可以在您自己的子类中重写。在我的脑海里:

        3
  •  2
  •   Dave Ray    15 年前

    据我所知,您不能在运行时扩展系统类加载器,但可以使用 URLClassLoader

        4
  •  2
  •   rsp    15 年前

    您可以尝试在应用程序启动时设置一个“启动器”,以创建 URLClassLoader .class 定位并从该类加载器启动应用程序。

    SimpleVerifier URLClassLoader

        5
  •  2
  •   Community CDub    7 年前

    是的,你可以用 URLClassLoader

    我有一个在运行时加载类的测试。该类不在类路径中(甚至在运行测试时也不存在),稍后将加载并运行良好。

    这是密码。

    void testHello() throws MalformedURLException, ClassNotFoundException {
        URL[] url = {
                new URL("file:/home/oreyes/testwork/")
        };
    
        try {
            new URLClassLoader(url).loadClass("Hello");
            throw new AssertionError("Should've thrown ClassNotFoundException");
        } catch ( ClassNotFoundException cnfe ){}
    
    
        c.process();// create the .class file 
    
        new URLClassLoader(url).loadClass("Hello");
    
        // it works!!
    }
    

    摘自 question

        6
  •  1
  •   mP.    15 年前

    我创建了自己的类加载器,非常简单。

     /**
     * Used to hold the bytecode for the class to be loaded.
     */
    private final static ThreadLocal<byte[]> BYTE_CODE = new ThreadLocal<byte[]>();
    
    @Override
    protected Class<?> findClass(final String name) throws ClassNotFoundException {
        final byte[] bytes = BYTE_CODE.get();
        if (null == bytes) {
            throw new ClassNotFoundException(name);
        }
        return this.defineClass(null, bytes, 0, bytes.length);
    }