AppBundleRunner 的作用
- 运行通过AppBundleGenerator 生成的jar
- 加载上边jar 相关依赖到类加载器中
- 初始化实例,并调用main 方法
- 同时还包含运行实例的停止
参考处理说明
- 类加载处理
实际上是load 方法,通过解析jar 元数据信息,同时也会进行jar 的解压处理 - 实例初始化
也在load 方法中处理,参考代码
// 会包含自己的类加载器
// Pick-up the classloader used as the parent to the System (application) classloader
// so that JVM extension classloader is also included, but application classloader used
// to bootstrap twill container is excluded.
final ClassLoader parentClassLoader = ClassLoader.getSystemClassLoader() != null
? ClassLoader.getSystemClassLoader().getParent()
: null;
bundleJarClassLoader = new BundledDaemonClassLoader(classPathUrlArray, parentClassLoader, nativeLibraryPaths);
Thread.currentThread().setContextClassLoader(bundleJarClassLoader);
// 通过配置参数进行类的实例化
final String mainClassName = arguments.getMainClassName();
logger.debug("Instantiating instance of {}", mainClassName);
final Class<?> cls = bundleJarClassLoader.loadClass(mainClassName);
checkArgument(Runnable.class.isAssignableFrom(cls), "{} does not implement `java.lang.Runnable` interface");
Constructor<? extends Runnable> constructor = cls.asSubclass(Runnable.class).getConstructor(String[].class);
runnable = constructor.newInstance(new Object[] { arguments.getMainArgs() });
return bundleJarClassLoader;
- 运行
因为对于运行的类实现了Runnable 接口直接运行就可以了(实际上就是以前介绍的YarnDaemon) - 运行实例的停止
因为实现了AutoCloseable,调用服务的close 就可以了,实际上是对于DACDaemon服务的shutdown
使用
就是在标准的apache twill 实现中AppBundleRunnable 调用的
参考代码
@Override
public final void initialize(TwillContext context) {
arguments = Arguments.fromArray(context.getArguments());
final File jarFile = new File(arguments.getJarFileName());
Objects.requireNonNull(jarFile, String.format("Jar file %s cannot be null", jarFile.getAbsolutePath()));
checkArgument(jarFile.exists(), "Jar file %s must exist", jarFile.getAbsolutePath());
checkArgument(jarFile.canRead(), "Jar file %s must be readable", jarFile.getAbsolutePath());
// 加载AppBundleRunner
jarRunner = loadJarRunner(jarFile, arguments);
}
AppBundleRunner 创建
private AppBundleRunner loadJarRunner(File jarFile, Arguments arguments) {
AppBundleRunner jarRunner = new AppBundleRunner(jarFile, arguments);
try {
// 会运行到上边说到的流程中
jarRunner.load();
return jarRunner;
} catch (Exception e) {
logger.error("Error loading classes into jarRunner", e);
}
return null;
}
说明
AppBundleRunner 核心还是对于YarnDaemon 服务实例的管理,之后方便在TwillRunnable的子类中使用,属于YarnService 服务中的一部分
参考资料
provision/yarn/yarntwill/src/main/java/com/dremio/provision/yarn/AppBundleRunner.java
provision/yarn/yarntwill/src/main/java/com/dremio/provision/yarn/BundledDaemonClassLoader.java
provision/yarn/yarntwill/src/main/java/com/dremio/provision/yarn/AppBundleRunnable.java