Repository: kylin Updated Branches: refs/heads/yang22-hbase102 8efe45d87 -> 6f1a7b730 (forced update)
KYLIN-2306 tolerate class missing exception when loading job list Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/85313ee6 Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/85313ee6 Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/85313ee6 Branch: refs/heads/yang22-hbase102 Commit: 85313ee63f56c5ca183a9a634beccd7bc2784e1c Parents: 7eb3d7c Author: Billy Liu <billy...@apache.org> Authored: Wed Dec 21 09:48:12 2016 +0800 Committer: Billy Liu <billy...@apache.org> Committed: Wed Dec 21 17:25:24 2016 +0800 ---------------------------------------------------------------------- .../kylin/job/execution/ExecutableManager.java | 54 ++++++++++++++++++++ .../apache/kylin/rest/service/JobService.java | 2 +- 2 files changed, 55 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/85313ee6/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java ---------------------------------------------------------------------- diff --git a/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java b/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java index 4351e31..0c49a3e 100644 --- a/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java +++ b/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java @@ -200,6 +200,35 @@ public class ExecutableManager { } } + /** + * Since ExecutableManager will instantiate all AbstractExecutable class by Class.forName(), but for each version release, + * new classes are introduced, old classes are deprecated, renamed or removed. The Class.forName() will throw out + * ClassNotFoundException. This API is used to retrieve the Executable Object list, not for calling the object method, + * so we could just instance the parent common class instead of the concrete class. It will tolerate the class missing issue. + * + * @param timeStartInMillis + * @param timeEndInMillis + * @param expectedClass + * @return + */ + public List<AbstractExecutable> getAllAbstractExecutables(long timeStartInMillis, long timeEndInMillis, Class<? extends AbstractExecutable> expectedClass) { + try { + List<AbstractExecutable> ret = Lists.newArrayList(); + for (ExecutablePO po : executableDao.getJobs(timeStartInMillis, timeEndInMillis)) { + try { + AbstractExecutable ae = parseToAbstract(po, expectedClass); + ret.add(ae); + } catch (IllegalArgumentException e) { + logger.error("error parsing one executabePO: ", e); + } + } + return ret; + } catch (PersistentException e) { + logger.error("error get All Jobs", e); + throw new RuntimeException(e); + } + } + public List<String> getAllJobIds() { try { return executableDao.getJobIds(); @@ -423,4 +452,29 @@ public class ExecutableManager { } } + private AbstractExecutable parseToAbstract(ExecutablePO executablePO, Class<? extends AbstractExecutable> expectedClass) { + if (executablePO == null) { + logger.warn("executablePO is null"); + return null; + } + try { + Class<? extends AbstractExecutable> clazz = ClassUtil.forName(expectedClass.getName(), AbstractExecutable.class); + Constructor<? extends AbstractExecutable> constructor = clazz.getConstructor(); + AbstractExecutable result = constructor.newInstance(); + result.initConfig(config); + result.setId(executablePO.getUuid()); + result.setName(executablePO.getName()); + result.setParams(executablePO.getParams()); + List<ExecutablePO> tasks = executablePO.getTasks(); + if (tasks != null && !tasks.isEmpty()) { + Preconditions.checkArgument(result instanceof ChainedExecutable); + for (ExecutablePO subTask : tasks) { + ((ChainedExecutable) result).addTask(parseToAbstract(subTask, DefaultChainedExecutable.class)); + } + } + return result; + } catch (ReflectiveOperationException e) { + throw new IllegalStateException("cannot parse this job:" + executablePO.getId(), e); + } + } } http://git-wip-us.apache.org/repos/asf/kylin/blob/85313ee6/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java ---------------------------------------------------------------------- diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java b/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java index d6caddb..ca8659c 100644 --- a/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java +++ b/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java @@ -532,7 +532,7 @@ public class JobService extends BasicService implements InitializingBean { } public List<CubingJob> listAllCubingJobs(final String cubeName, final String projectName, final Set<ExecutableState> statusList, long timeStartInMillis, long timeEndInMillis, final Map<String, Output> allOutputs) { - List<CubingJob> results = Lists.newArrayList(FluentIterable.from(getExecutableManager().getAllExecutables(timeStartInMillis, timeEndInMillis)).filter(new Predicate<AbstractExecutable>() { + List<CubingJob> results = Lists.newArrayList(FluentIterable.from(getExecutableManager().getAllAbstractExecutables(timeStartInMillis, timeEndInMillis, CubingJob.class)).filter(new Predicate<AbstractExecutable>() { @Override public boolean apply(AbstractExecutable executable) { if (executable instanceof CubingJob) {