是否有可能系统类装入器的负载。类文件的规定,在运行时间?
-
18-09-2019 - |
题
我写一个静态的分析工具,用于分配,分析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);
}