ClassLoader:将类视为资源安全或实现细节?

时间:2015-06-10 18:10:13

标签: java classloader

对于我的用例,我想通过Socket连接传输一个类(不是对象,实际的类文件),然后在接收端加载该类。

该类通常包含在项目中(在发送端),因此它在类路径上的某处

我已经完成了所有代码,但实际上从类路径中获取类文件,我不得不采取一些奇怪的方法将类作为资源(代码被剥离到必要部分):

public class ClassTransport {

    public byte[] data;
    public String qualifiedName;

    public static ClassTransport create(Class<?> theClass) throws Exception {
        ClassTransport result = new ClassTransport();
        result.qualifiedName = theClass.getName();
        // brute force derive the class file name
        String classResourceName = theClass.getName().replace('.', '/') + ".class";             

        ClassLoader cl = theClass.getClassLoader();
        try (InputStream in = cl.getResourceAsStream(classResourceName)) {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int b;
            while ((b = in.read()) >= 0) {
                out.write(b);
            }
            out.close();
            result.data = out.toByteArray();
        }
        return result;      
    }

}

这是有效的,但它实际上是安全这样做还是违反了任何规范 - 特别是在将来失败来检索课程的可能性是什么JRE发布还是在特定平台上发布?

1 个答案:

答案 0 :(得分:1)

简短的回答:这可能很好。

更长的答案:它不能保证没问题,因为JLS中的任何内容都不能保证包中的类被组织为目录中的文件。

JLS的相关部分是7.2. Host Support for Packages

  

在Java SE平台的简单实现中,包和编译单元可以存储在本地文件系统中。其他实现可以使用分布式文件系统或某种形式的数据库来存储它们。

     

如果主机系统在数据库中存储包和编译单元,则数据库不得对基于文件的实现中允许的编译单元施加可选限制(第7.6节)。

要点是,理论上,类路径可能类似于数据库而不是文件系统。因此,虽然您的方法不会违反任何规范,但任何规范都不会支持。我找不到任何这种情况的系统,所以你可能好吧假设在大多数情况下使用文件系统。

这也在this StackOverflow问题中进行了讨论。