ClassLoader:将 class 视为资源 - 安全还是实现细节?
ClassLoader: Treating a class as a resource - safe or implementation detail?
对于我的用例,我想通过 Socket 连接传输 class(不是对象,实际的 class 文件),然后在接收端加载 class结束。
class 通常包含在项目中(在发送端),因此它在 class 路径的 某处。
我的所有代码都可以正常工作,但实际上要从 class 路径 获取 class 文件,我不得不求助于一些奇怪的虐待class 作为资源(代码精简到基本部分):
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 版本或特定平台上检索 class?
简答:可能没问题。
更长的答案:它不能保证没问题,因为 JLS 中没有任何内容保证包中的 类 被组织为目录中的文件。
JLS 的相关部分是 7.2. Host Support for Packages:
In simple implementations of the Java SE platform, packages and compilation units may be stored in a local file system. Other implementations may store them using a distributed file system or some form of database.
If a host system stores packages and compilation units in a database, then the database must not impose the optional restrictions (§7.6) on compilation units permissible in file-based implementations.
要点是,理论上,类路径可能位于数据库之类的东西中,而不是文件系统中。因此,虽然您的方法没有违反任何规范,但它也不支持任何规范。不过,我找不到任何属于这种情况的系统,因此在大多数情况下,假设文件系统是 可能 没问题。
这也在 this Whosebug 问题中进行了讨论。
对于我的用例,我想通过 Socket 连接传输 class(不是对象,实际的 class 文件),然后在接收端加载 class结束。
class 通常包含在项目中(在发送端),因此它在 class 路径的 某处。
我的所有代码都可以正常工作,但实际上要从 class 路径 获取 class 文件,我不得不求助于一些奇怪的虐待class 作为资源(代码精简到基本部分):
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 版本或特定平台上检索 class?
简答:可能没问题。
更长的答案:它不能保证没问题,因为 JLS 中没有任何内容保证包中的 类 被组织为目录中的文件。
JLS 的相关部分是 7.2. Host Support for Packages:
In simple implementations of the Java SE platform, packages and compilation units may be stored in a local file system. Other implementations may store them using a distributed file system or some form of database.
If a host system stores packages and compilation units in a database, then the database must not impose the optional restrictions (§7.6) on compilation units permissible in file-based implementations.
要点是,理论上,类路径可能位于数据库之类的东西中,而不是文件系统中。因此,虽然您的方法没有违反任何规范,但它也不支持任何规范。不过,我找不到任何属于这种情况的系统,因此在大多数情况下,假设文件系统是 可能 没问题。
这也在 this Whosebug 问题中进行了讨论。