使用 运行代码时java -jar app.jar
,java 仅使用 JAR 文件清单中定义的类路径(即Class-Path
属性)。如果该类位于 中app.jar
,或者该类位于 JAR 清单的属性中设置的类路径中Class-Path
,则可以使用以下代码片段加载该类,其中className
是完全限定的类名。
final String classAsPath = className.replace('.', '/') + ".class";
final InputStream input = ClassLoader.getSystemResourceAsStream( path/to/class );
现在,如果该类不是 JAR 的一部分,并且不在清单中Class-Path
,那么类加载器将找不到它。相反,您可以使用URLClassLoader
, 小心处理 windows 和 Unix/Linux/MacOSX 之间的差异。
// the class to load
final String classAsPath = className.replace('.', '/') + ".class";
// the URL to the `app.jar` file (Windows and Unix/Linux/MacOSX below)
final URL url = new URL( "file", null, "///C:/Users/diffusive/app.jar" );
//final URL url = new URL( "file", null, "/Users/diffusive/app.jar" );
// create the class loader with the JAR file
final URLClassLoader urlClassLoader = new URLClassLoader( new URL[] { url } );
// grab the resource, through, this time from the `URLClassLoader` object
// rather than from the `ClassLoader` class
final InputStream input = urlClassLoader.getResourceAsStream( classAsPath );
在这两个示例中,您都需要处理异常,以及输入流null
是否找不到资源这一事实。另外,如果你需要InputStream
进入一个byte[]
,你可以使用 Apache 的 commons IOUtils.toByteArray(...)
。而且,如果你想要一个Class
,你可以使用类加载器的defineClass(...)
方法,它接受byte[]
.
您可以在 Diffusive 源代码中的一个类中找到此代码ClassLoaderUtils
,您可以在 SourceForge 的 github.com/robphilipp/diffusive 上找到该代码
以及一种从相对路径和绝对路径为 Windows 和 Unix/Linux/MacOSX 创建 URL 的方法RestfulDiffuserManagerResource.createJarClassPath(...)