use of org.apache.drill.exec.exception.ClassTransformationException in project drill by apache.
the class PhysicalOpUnitTestBase method mockFragmentContext.
protected void mockFragmentContext() throws Exception {
final CodeCompiler compiler = new CodeCompiler(drillConf, optionManager);
// final BufferAllocator allocator = this.allocator.newChildAllocator("allocator_for_operator_test", initReservation, maxAllocation);
new NonStrictExpectations() {
{
// optManager.getOption(withAny(new TypeValidators.BooleanValidator("", false))); result = false;
// // TODO(DRILL-4450) - Probably want to just create a default option manager, this is a hack to prevent
// // the code compilation from failing when trying to decide of scalar replacement is turned on
// // this will cause other code paths to fail because this return value won't be valid for most
// // string options
// optManager.getOption(withAny(new TypeValidators.StringValidator("", "try"))); result = "try";
// optManager.getOption(withAny(new TypeValidators.PositiveLongValidator("", 1l, 1l))); result = 10;
fragContext.getOptions();
result = optionManager;
fragContext.getManagedBuffer();
result = bufManager.getManagedBuffer();
fragContext.shouldContinue();
result = true;
fragContext.getExecutionControls();
result = executionControls;
fragContext.getFunctionRegistry();
result = funcReg;
fragContext.getConfig();
result = drillConf;
fragContext.getHandle();
result = ExecProtos.FragmentHandle.getDefaultInstance();
try {
CodeGenerator<?> cg = CodeGenerator.get(templateClassDefinition, funcReg);
cg.plainJavaCapable(true);
// cg.saveCodeForDebugging(true);
fragContext.getImplementationClass(withAny(cg));
result = new Delegate<Object>() {
@SuppressWarnings("unused")
Object getImplementationClass(CodeGenerator<Object> gen) throws IOException, ClassTransformationException {
return compiler.createInstance(gen);
}
};
fragContext.getImplementationClass(withAny(CodeGenerator.get(templateClassDefinition, funcReg).getRoot()));
result = new Delegate<Object>() {
@SuppressWarnings("unused")
Object getImplementationClass(ClassGenerator<Object> gen) throws IOException, ClassTransformationException {
return compiler.createInstance(gen.getCodeGenerator());
}
};
} catch (ClassTransformationException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
}
use of org.apache.drill.exec.exception.ClassTransformationException in project drill by apache.
the class ExternalSortBatch method createCopier.
private void createCopier(VectorAccessible batch, List<BatchGroup> batchGroupList, VectorContainer outputContainer, boolean spilling) throws SchemaChangeException {
try {
if (copier == null) {
CodeGenerator<PriorityQueueCopier> cg = CodeGenerator.get(PriorityQueueCopier.TEMPLATE_DEFINITION, context.getFunctionRegistry(), context.getOptions());
cg.plainJavaCapable(true);
// Uncomment out this line to debug the generated code.
// cg.saveCodeForDebugging(true);
ClassGenerator<PriorityQueueCopier> g = cg.getRoot();
generateComparisons(g, batch);
g.setMappingSet(COPIER_MAPPING_SET);
CopyUtil.generateCopies(g, batch, true);
g.setMappingSet(MAIN_MAPPING);
copier = context.getImplementationClass(cg);
} else {
copier.close();
}
@SuppressWarnings("resource") BufferAllocator allocator = spilling ? copierAllocator : oAllocator;
for (VectorWrapper<?> i : batch) {
@SuppressWarnings("resource") ValueVector v = TypeHelper.getNewVector(i.getField(), allocator);
outputContainer.add(v);
}
copier.setup(context, allocator, batch, batchGroupList, outputContainer);
} catch (ClassTransformationException | IOException e) {
throw new RuntimeException(e);
}
}
use of org.apache.drill.exec.exception.ClassTransformationException in project drill by apache.
the class RemovingRecordBatch method getGenerated2Copier.
private Copier getGenerated2Copier() throws SchemaChangeException {
Preconditions.checkArgument(incoming.getSchema().getSelectionVectorMode() == SelectionVectorMode.TWO_BYTE);
for (VectorWrapper<?> vv : incoming) {
vv.getValueVector().makeTransferPair(container.addOrGet(vv.getField(), callBack));
}
try {
final CodeGenerator<Copier> cg = CodeGenerator.get(Copier.TEMPLATE_DEFINITION2, context.getFunctionRegistry(), context.getOptions());
CopyUtil.generateCopies(cg.getRoot(), incoming, false);
Copier copier = context.getImplementationClass(cg);
copier.setupRemover(context, incoming, this);
cg.plainJavaCapable(true);
return copier;
} catch (ClassTransformationException | IOException e) {
throw new SchemaChangeException("Failure while attempting to load generated class", e);
}
}
use of org.apache.drill.exec.exception.ClassTransformationException in project drill by apache.
the class WindowFrameRecordBatch method buildSchema.
@Override
protected void buildSchema() throws SchemaChangeException {
logger.trace("buildSchema()");
final IterOutcome outcome = next(incoming);
switch(outcome) {
case NONE:
state = BatchState.DONE;
container.buildSchema(BatchSchema.SelectionVectorMode.NONE);
return;
case STOP:
state = BatchState.STOP;
return;
case OUT_OF_MEMORY:
state = BatchState.OUT_OF_MEMORY;
return;
}
try {
createFramers(incoming);
} catch (IOException | ClassTransformationException e) {
throw new SchemaChangeException("Exception when creating the schema", e);
}
if (incoming.getRecordCount() > 0) {
batches.add(new WindowDataBatch(incoming, oContext));
}
}
use of org.apache.drill.exec.exception.ClassTransformationException in project drill by axbaretto.
the class ClassTransformer method getImplementationClass.
public Class<?> getImplementationClass(final QueryClassLoader classLoader, final TemplateClassDefinition<?> templateDefinition, final String entireClass, final String materializedClassName) throws ClassTransformationException {
// unfortunately, this hasn't been set up at construction time, so we have to do it here
final ScalarReplacementOption scalarReplacementOption = ScalarReplacementOption.fromString(optionManager.getOption(SCALAR_REPLACEMENT_VALIDATOR));
try {
final long t1 = System.nanoTime();
final ClassSet set = new ClassSet(null, templateDefinition.getTemplateClassName(), materializedClassName);
final byte[][] implementationClasses = classLoader.getClassByteCode(set.generated, entireClass);
long totalBytecodeSize = 0;
Map<String, Pair<byte[], ClassNode>> classesToMerge = Maps.newHashMap();
for (byte[] clazz : implementationClasses) {
totalBytecodeSize += clazz.length;
final ClassNode node = AsmUtil.classFromBytes(clazz, ClassReader.EXPAND_FRAMES);
if (!AsmUtil.isClassOk(logger, "implementationClasses", node)) {
throw new IllegalStateException("Problem found with implementationClasses");
}
classesToMerge.put(node.name, Pair.of(clazz, node));
}
final LinkedList<ClassSet> names = Lists.newLinkedList();
final Set<ClassSet> namesCompleted = Sets.newHashSet();
names.add(set);
while (!names.isEmpty()) {
final ClassSet nextSet = names.removeFirst();
if (namesCompleted.contains(nextSet)) {
continue;
}
final ClassNames nextPrecompiled = nextSet.precompiled;
final byte[] precompiledBytes = byteCodeLoader.getClassByteCodeFromPath(nextPrecompiled.clazz);
final ClassNames nextGenerated = nextSet.generated;
// keeps only classes that have not be merged
Pair<byte[], ClassNode> classNodePair = classesToMerge.remove(nextGenerated.slash);
final ClassNode generatedNode;
if (classNodePair != null) {
generatedNode = classNodePair.getValue();
} else {
generatedNode = null;
}
/*
* TODO
* We're having a problem with some cases of scalar replacement, but we want to get
* the code in so it doesn't rot anymore.
*
* Here, we use the specified replacement option. The loop will allow us to retry if
* we're using TRY.
*/
MergedClassResult result = null;
boolean scalarReplace = scalarReplacementOption != ScalarReplacementOption.OFF && entireClass.length() < MAX_SCALAR_REPLACE_CODE_SIZE;
while (true) {
try {
result = MergeAdapter.getMergedClass(nextSet, precompiledBytes, generatedNode, scalarReplace);
break;
} catch (RuntimeException e) {
// if we had a problem without using scalar replacement, then rethrow
if (!scalarReplace) {
throw e;
}
// if we did try to use scalar replacement, decide if we need to retry or not
if (scalarReplacementOption == ScalarReplacementOption.ON) {
// option is forced on, so this is a hard error
throw e;
}
/*
* We tried to use scalar replacement, with the option to fall back to not using it.
* Log this failure before trying again without scalar replacement.
*/
logger.info("scalar replacement failure (retrying)\n", e);
scalarReplace = false;
}
}
for (String s : result.innerClasses) {
s = s.replace(DrillFileUtils.SEPARATOR_CHAR, '.');
names.add(nextSet.getChild(s));
}
classLoader.injectByteCode(nextGenerated.dot, result.bytes);
namesCompleted.add(nextSet);
}
// adds byte code of the classes that have not been merged to make them accessible for outer class
for (Map.Entry<String, Pair<byte[], ClassNode>> clazz : classesToMerge.entrySet()) {
classLoader.injectByteCode(clazz.getKey().replace(DrillFileUtils.SEPARATOR_CHAR, '.'), clazz.getValue().getKey());
}
Class<?> c = classLoader.findClass(set.generated.dot);
if (templateDefinition.getExternalInterface().isAssignableFrom(c)) {
logger.debug("Compiled and merged {}: bytecode size = {}, time = {} ms.", c.getSimpleName(), DrillStringUtils.readable(totalBytecodeSize), (System.nanoTime() - t1 + 500_000) / 1_000_000);
return c;
}
throw new ClassTransformationException("The requested class did not implement the expected interface.");
} catch (CompileException | IOException | ClassNotFoundException e) {
throw new ClassTransformationException(String.format("Failure generating transformation classes for value: \n %s", entireClass), e);
}
}
Aggregations