我写一个静态的分析工具,用于分配,分析Java码使用的个体和小型图书馆。其中一个部分的ASM我们使用的要求(或至少,看来需要),该类应从装载这类装入器。

我们希望该工具将能够分析。类文件,而不需要他们在类路径。我们已经负荷。课程由一个指定的目录在运行时间和阅读它们在使用输入流.这是可以接受的个体和小型在大多数情况下。有一些类别,例如 SimpleVerifier, ,它试图载的课程。

它是可能的,在这种情况下,在注册。类文件应载入这样的呼吁 Class.forName() 会负他们?或是有一个简单的方法来扩大这类装入器让这个吗?


编辑:的信息 URLClassLoader 是有用的。不幸的是,使用 Thread.currentThread().setContextClassLoader() 一个实例是没有工作,在这种情况。图书馆码我打电话到使用的一个装载机检索上的实例,使用初始化 getClass().getClassLoader().

到时候我设的URLClassLoader类没有被初始化所以我猜contextClassLoader不负荷。

我明白的答复是否正确?将使用URLClassLoader载的第3类方是一个可能性吗?

有帮助吗?

解决方案

差不多。

如果你有类编制的某个地方,你可以载他们 URLClassLoader.然后你可以设定此类装入器的类装入器对当前线: 螺纹。setContextClassLoader(类装入器)

用户可以获得当前线上下文课程序和使用,以访问这类定义。

其他提示

首先,ASM可以用这种方式,它不会使用类装入器获得的信息有关的类。

有几个地方在小型矿场框架内负荷类默认,但所有这些地方可以替代在你自己的子类。出了我的头顶:

  • ClassWriter.getCommonSuperClass() 方法是称为,只有当ClassWriter.COMPUTE_FRAMES标志的使用和可overwriten不使用类装入器获得信息有关的类。你可以找到一个例子就在 ClassWriterComputeFramesTest 介绍一个抽象在其它任何情况下
  • 同样SimpleVerifier.getClass()方法使用 SimpleVerifier.isAssignableFrom() 你可以复盖后者和使用在其它任何情况下抽象,以找到共同的超级类型。如果我没有记错的话,AspectWerkz项目已经实施了类似的事情在其类型的模式匹配的代码。还注意到,没有 SimpleVerifier.setClassLoader() 方法,该方法可以使用如果你还想载入自己的课程。

在一个侧面说明,在一个太阳的Jvm,装类获得永久代区域的和不能被卸载,所以它不是一个好主意负荷类只有静态的代码分析的目的,如果你可以避免,特别是如果工具将纳入一个长期生活的过程中,如IDE。

你不能,因为我所知,延长该系统类装载在运行时,但可以动态加载类从任意位置(罐子目录或)使用 URLClassLoader.

你可以尝试建立一个"启动"在启动的应用程序,创建一个 URLClassLoader 通过它的位置上类路径和你自己的 .class 位置,并开始应用这类装入器。

SimpleVerifier 装载由 URLClassLoader 它还将能够负荷类额外的位置。

是的,你可以使用 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!!
}

取自这个 的问题.

我创造了自己的类加载其相当简单的。

 /**
 * 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);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top