我正在使用 Apache Twill 将一个使用 Janino 动态编译类的开源项目移植到 YARN。这很好用,除了最后一个错误。当 Janino 与斜纹一起使用时,我得到一个找不到类的异常,尽管该类在 Classpath 中甚至使用过。
我得到的例外是:
2014-06-09T18:30:40,093Z 错误 oadepipProjectRecordBatch [zk1] [37daf04b-7d82-4d2f-987c-59851f2aeafe:frag:0:0] AbstractSingleRecordBatch:next(AbstractSingleRecordBatch.java:60) - 查询 org.apache 期间失败。 Drill.exec.exception.SchemaChangeException:尝试在 org.apache.drill.exec.record 的 org.apache.drill.exec.physical.impl.project.ProjectRecordBatch.setupNewSchema(ProjectRecordBatch.java:243) 加载生成的类时失败.AbstractSingleRecordBatch.next(AbstractSingleRecordBatch.java:57) at org.apache.drill.exec.physical.impl.project.ProjectRecordBatch.next(ProjectRecordBatch.java:83) at org.apache.drill.exec.record.AbstractSingleRecordBatch.next (AbstractSingleRecordBatch.java:45) 在 org.apache.drill.exec.physical.impl.limit.LimitRecordBatch.next(LimitRecordBatch.java:99) 在 org.apache.drill.exec.record.AbstractSingleRecordBatch.next(AbstractSingleRecordBatch.java:45) 在 org.apache.drill.exec.physical.impl.svremover.RemovingRecordBatch.next(RemovingRecordBatch.java:94) 在 org .apache.drill.exec.physical.impl.ScreenCreator$ScreenRoot.next(ScreenCreator.java:80) at org.apache.drill.exec.work.fragment.FragmentExecutor.run(FragmentExecutor.java:104) at java.util .concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:744) 原因: org.apache.drill.exec.exception.ClassTransformationException:失败svremover.RemovingRecordBatch.next(RemovingRecordBatch.java:94) 在 org.apache.drill.exec.physical.impl.ScreenCreator$ScreenRoot.next(ScreenCreator.java:80) 在 org.apache.drill.exec.work.fragment。 FragmentExecutor.run(FragmentExecutor.java:104) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 在 java.lang .Thread.run(Thread.java:744) 引起:org.apache.drill.exec.exception.ClassTransformationException:失败svremover.RemovingRecordBatch.next(RemovingRecordBatch.java:94) 在 org.apache.drill.exec.physical.impl.ScreenCreator$ScreenRoot.next(ScreenCreator.java:80) 在 org.apache.drill.exec.work.fragment。 FragmentExecutor.run(FragmentExecutor.java:104) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 在 java.lang .Thread.run(Thread.java:744) 引起:org.apache.drill.exec.exception.ClassTransformationException:失败runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:744) 原因:org.apache.drill .exec.exception.ClassTransformationException:失败runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:744) 原因:org.apache.drill .exec.exception.ClassTransformationException:失败
为值生成转换类:
package org.apache.drill.exec.test.generated;
import org.apache.drill.exec.exception.SchemaChangeException;
import org.apache.drill.exec.expr.holders.BitHolder;
import org.apache.drill.exec.expr.holders.VarCharHolder;
import org.apache.drill.exec.ops.FragmentContext;
import org.apache.drill.exec.record.RecordBatch;
import org.apache.drill.exec.vector.RepeatedVarCharVector;
import org.apache.drill.exec.vector.VarCharVector;
import org.apache.drill.exec.vector.complex.impl.RepeatedVarCharReaderImpl;
public class ProjectorGen0 {
RepeatedVarCharVector vv0;
RepeatedVarCharReaderImpl reader4;
VarCharVector vv5;
public boolean doEval(int inIndex, int outIndex)
throws SchemaChangeException
{
{
VarCharHolder out3 = new VarCharHolder();
complex:
vv0 .getAccessor().getReader().setPosition((inIndex));
reader4 .read(0, out3);
BitHolder out8 = new BitHolder();
out8 .value = 1;
if (!vv5 .getMutator().setSafe((outIndex), out3)) {
out8 .value = 0;
}
if (out8 .value == 0) {
return false;
}
}
{
return true;
}
}
public void doSetup(FragmentContext context, RecordBatch incoming, RecordBatch outgoing)
throws SchemaChangeException
{
{
int[] fieldIds1 = new int[ 1 ] ;
fieldIds1 [ 0 ] = 0;
Object tmp2 = (incoming).getValueAccessorById(RepeatedVarCharVector.class, fieldIds1).getValueVector();
if (tmp2 == null) {
throw new SchemaChangeException("Failure while loading vector vv0 with id: org.apache.drill.exec.record.TypedFieldId@1cf4a5a0.");
}
vv0 = ((RepeatedVarCharVector) tmp2);
reader4 = ((RepeatedVarCharReaderImpl) vv0 .getAccessor().getReader());
int[] fieldIds6 = new int[ 1 ] ;
fieldIds6 [ 0 ] = 0;
Object tmp7 = (outgoing).getValueAccessorById(VarCharVector.class, fieldIds6).getValueVector();
if (tmp7 == null) {
throw new SchemaChangeException("Failure while loading vector vv5 with id: org.apache.drill.exec.record.TypedFieldId@1ce776c0.");
}
vv5 = ((VarCharVector) tmp7);
}
}
}
在 org.apache.drill.exec.compile.ClassTransformer.getImplementationClass(ClassTransformer.java:302) 在 org.apache.drill.exec.ops.FragmentContext.getImplementationClass(FragmentContext.java:185) 在 org.apache.drill.exec .physical.impl.project.ProjectRecordBatch.setupNewSchema(ProjectRecordBatch.java:240) 在 org.apache.drill.exec.record.AbstractSingleRecordBatch.next(AbstractSingleRecordBatch.java:57) 在 org.apache.drill.exec.physical.impl .project.ProjectRecordBatch.next(ProjectRecordBatch.java:83) 在 org.apache.drill.exec.record.AbstractSingleRecordBatch.next(AbstractSingleRecordBatch.java:45) 在 org.apache.drill.exec.physical.impl.limit.LimitRecordBatch .next(LimitRecordBatch.java:99) 在 org.apache.drill.exec.record.AbstractSingleRecordBatch.next(AbstractSingleRecordBatch.java:45) 在 org.apache.drill.exec.physical。在 org.apache.drill.exec.physical.impl.ScreenCreator$ScreenRoot.next(ScreenCreator.java:80) 在 org.apache.drill.exec.work 的 impl.svremover.RemovingRecordBatch.next(RemovingRecordBatch.java:94)。 fragment.FragmentExecutor.run(FragmentExecutor.java:104) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java .lang.Thread.run(Thread.java:744) 原因:org.codehaus.commons.compiler.CompileException:第 4 行第 8 列:无法导入的类“org.apache.drill.exec.exception.SchemaChangeException”在 org.codehaus.janino.UnitCompiler.import2(UnitCompiler.java:192) 的 org.codehaus.janino.UnitCompiler 的 org.codehaus.janino.UnitCompiler.compileError(UnitCompiler.java:9014) 加载。访问 $000(UnitCompiler.java:104) at org.codehaus.janino.UnitCompiler$1.visitSingleTypeImportDeclaration(UnitCompiler.java:166) at org.codehaus.janino.Java$CompilationUnit$SingleTypeImportDeclaration.accept(Java.java:171) at org .codehaus.janino.UnitCompiler.(UnitCompiler.java:164) 在 org.apache.drill.exec.compile.JaninoClassCompiler.getClassByteCode(JaninoClassCompiler.java:53) 在 org.apache.drill.exec.compile.QueryClassLoader.getClassByteCode( QueryClassLoader.java:69) at org.apache.drill.exec.compile.ClassTransformer.getImplementationClass(ClassTransformer.java:256) at org.apache.drill.exec.ops.FragmentContext.getImplementationClass(FragmentContext.java:185) at org .apache.drill.exec.physical.impl.project.ProjectRecordBatch.setupNewSchema(ProjectRecordBatch.java:240) 在 org.apache.drill.exec.record。AbstractSingleRecordBatch.next(AbstractSingleRecordBatch.java:57) at org.apache.drill.exec.physical.impl.project.ProjectRecordBatch.next(ProjectRecordBatch.java:83) at org.apache.drill.exec.record.AbstractSingleRecordBatch.next( AbstractSingleRecordBatch.java:45) at org.apache.drill.exec.physical.impl.limit.LimitRecordBatch.next(LimitRecordBatch.java:99) at org.apache.drill.exec.record.AbstractSingleRecordBatch.next(AbstractSingleRecordBatch.java: 45) 在 org.apache.drill.exec.physical.impl.svremover.RemovingRecordBatch.next(RemovingRecordBatch.java:94) 在 org.apache.drill.exec.physical.impl.ScreenCreator$ScreenRoot.next(ScreenCreator.java: 80) 在 org.apache.drill.exec.work.fragment.FragmentExecutor.run(FragmentExecutor.java:104) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 在 java.lang.Thread.run(Thread.java:744)
如您所见,异常的类型是,SchemaChangeException
但内部异常是ClassNotFoundException
for SchemaChangeException
:
第 4 行第 8 列:无法加载导入的类“org.apache.drill.exec.exception.SchemaChangeException”
所以类加载器有问题,当应用程序使用 Apache Twill 运行时,它会发生变化。它独立工作,但在这两种情况下,底层 jar 都是相同的。
Apache Twill 还有一个添加额外资源的功能,但是在那里添加我的 jar 也不起作用,相反我得到了一个异常,即 jar 已经包含在内:
线程“ServiceDelegate STARTING”中的异常 java.lang.RuntimeException:java.util.zip.ZipException:重复条目:lib/drill-java-exec-1.0.0-m2-incubating-SNAPSHOT-rebuffed.jar
在 com.google.common.base.Throwables.propagate(Throwables.java:160) 在 org.apache.twill.yarn.YarnTwillController.doStartUp(YarnTwillController.java:133) 在 org.apache.twill.internal.AbstractZKServiceController.startUp (AbstractZKServiceController.java:82) 在 org.apache.twill.internal.AbstractExecutionServiceController$ServiceDelegate.startUp(AbstractExecutionServiceController.java:109) 在 com.google.common.util.concurrent.AbstractIdleService$1$1.run(AbstractIdleService.java:43 ) 在 java.lang.Thread.run(Thread.java:744) 引起:java.util.zip.ZipException:重复条目:lib/drill-java-exec-1.0.0-m2-incubating-SNAPSHOT-rebuffed。 jar 在 java.util.zip.ZipOutputStream.putNextEntry(ZipOutputStream.java:215) 在 java.util.jar.JarOutputStream.putNextEntry(JarOutputStream.java:109) 在 org.apache.twill.internal。ApplicationBundler.copyResource(ApplicationBundler.java:347) 在 org.apache.twill.internal.ApplicationBundler.createBundle(ApplicationBundler.java:140) 在 org.apache.twill.yarn.YarnTwillPreparer.createContainerJar(YarnTwillPreparer.java:388) 在 org .apache.twill.yarn.YarnTwillPreparer.access$300(YarnTwillPreparer.java:106) 在 org.apache.twill.yarn.YarnTwillPreparer$1.call(YarnTwillPreparer.java:264) 在 org.apache.twill.yarn.YarnTwillPreparer$1。在 org.apache.twill.yarn.YarnTwillController.doStartUp(YarnTwillController.java:98) 处调用(YarnTwillPreparer.java:253) ... 还有 4 个yarn.YarnTwillPreparer.access$300(YarnTwillPreparer.java:106) at org.apache.twill.yarn.YarnTwillPreparer$1.call(YarnTwillPreparer.java:264) at org.apache.twill.yarn.YarnTwillPreparer$1.call(YarnTwillPreparer.java :253) 在 org.apache.twill.yarn.YarnTwillController.doStartUp(YarnTwillController.java:98) ... 4 更多yarn.YarnTwillPreparer.access$300(YarnTwillPreparer.java:106) at org.apache.twill.yarn.YarnTwillPreparer$1.call(YarnTwillPreparer.java:264) at org.apache.twill.yarn.YarnTwillPreparer$1.call(YarnTwillPreparer.java :253) 在 org.apache.twill.yarn.YarnTwillController.doStartUp(YarnTwillController.java:98) ... 4 更多
使用的底层类加载器是URLClassLoader
. 它是用一个空数组初始化的,但它适用于独立应用程序,问题只是当它与 Apache Twill 一起运行时,它从哪里获取它应该查找的 URL?我怎么能检查它?
类加载器定义:
public class QueryClassLoader extends URLClassLoader {
static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(QueryClassLoader.class);
private final ClassCompiler classCompiler;
private AtomicLong index = new AtomicLong(0);
private ConcurrentMap<String, byte[]> customClasses = new MapMaker().concurrencyLevel(4).makeMap();
public QueryClassLoader(boolean useJanino) {
super(new URL[0]);
if (useJanino) {
this.classCompiler = new JaninoClassCompiler(this);
} else {
throw new UnsupportedOperationException("Drill no longer supports using the JDK class compiler.");
}
}
...
我可以研究的任何想法,为什么会发生错误或如何解决它?