[
https://issues.apache.org/jira/browse/DRILL-6888?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16713579#comment-16713579
]
Paul Rogers commented on DRILL-6888:
------------------------------------
I suspect this is because BatchHolder is an inner (non-static) class. Here is
the code that calls the constructor:
{code:java}
protected HashAggTemplate.BatchHolder newBatchHolder(int arg1) {
return this.injectMembers(new HashAggregatorGen0 .BatchHolder(arg1));
}
{code}
Here is the class declaration:
{code:java}
final class BatchHolder
extends HashAggTemplate.BatchHolder
...
public BatchHolder(int arg1) {
{code}
Nested classes worked earlier. I suspect that the change is that
{{injectMembers()}} code. I suspect some confusion has crept in about how the
{{newBatchHolder()}} method is supposed to work. Here's the idea:
With byte-code fixup, the "template" class is merged with the generated class.
This means that if you include code that says {{new BatchHolder()}} it will be
rewritten to refer to the new, code-gen-and-merged version.
In plain Java, we can't do this trick: all references in the "template" (now
base) class must be to classes known at Drill build time. So, we can refer to
base classes only. So, we can do this:
{code:java}
BatchHolder foo = newBatchHolder();
{code}
The {{newBatchHolder()}} method is supposed to be overridden by the generated
code to create an instance of the generated nested class. That works very
nicely.
But, at some point that "inject" code got added. That is likely to screw up the
mechanism. Looks like it is trying to do something clever to inject members.
But, nothing clever is needed, just do the very simple pattern above and all
will work file. Or, do a two step:
{code:java}
protected BatchHolder outerNewBatchHolder(int batchRowCount) {
return this.injectMembers(newBatchHolder(batchRowCount));
}
// These methods are overridden in the generated class when created as plain
Java code.
protected BatchHolder newBatchHolder(int batchRowCount) {
return new BatchHolder(batchRowCount);
}
{code}
Can't recall the exact form that the "newFoo" methods should take. Go back
about a year in the history of this file to see how it was back then.
Then, for the 54 version, we've got additional problems:
{code:java}
protected HashAggTemplate.BatchHolder newBatchHolder(int arg1) {
return this.injectMembers(new HashAggregatorGen0 .BatchHolder(arg1));
}
protected HashAggTemplate.HashAggSpilledPartition
newHashAggSpilledPartition(int arg1, int arg2, int arg3, String arg4) {
return this.injectMembers(new HashAggregatorGen0
.HashAggSpilledPartition(arg1, arg2, arg3, arg4));
}
protected HashAggTemplate.HashAggUpdater newHashAggUpdater() {
return this.injectMembers(new HashAggregatorGen0 .HashAggUpdater());
}
{code}
Notice that the code gen has dutifully created three "newFoo" methods. But,
each calls the same method: {{injectMembers}}. This will only work if three
versions of the method exist: one for each of the three different classes.
Else, there is a type incompatibility issue, which is what I suspect Janino is
complaining about.
You can also try switching to use the JDK compiler; I suspect it will produce a
better error message.
I realize that this code gen stuff is a bit obscure. The thing to remember is:
when using plain Java, there is no mystery (other than how we generate the
code): the generated code itself has to follow Java semantics; it can't do any
behind-the-scenes byte code magic.
> Nested classes in HashAggTemplate break the plain Java for debugging codegen
> ----------------------------------------------------------------------------
>
> Key: DRILL-6888
> URL: https://issues.apache.org/jira/browse/DRILL-6888
> Project: Apache Drill
> Issue Type: Improvement
> Components: Execution - Relational Operators
> Affects Versions: 1.14.0
> Reporter: Boaz Ben-Zvi
> Assignee: Boaz Ben-Zvi
> Priority: Minor
> Attachments: janino5306141716524056052.java,
> janino6744306210553474372.java
>
>
> The *prefer_plain_java* compile option is useful for debugging of generated
> code.
> DRILL-6719 ("separate spilling logic for Hash Agg") introduced two nested
> classes into the HashAggTemplate class. However those nested classes cause
> the prefer_plain_java compile option to fail when compiling the generated
> code, like:
> {code:java}
> Error: SYSTEM ERROR: CompileException: File
> '/tmp/janino5709636998794673307.java', Line 36, Column 35: No applicable
> constructor/method found for actual parameters
> "org.apache.drill.exec.test.generated.HashAggregatorGen11$HashAggSpilledPartition";
> candidates are: "protected
> org.apache.drill.exec.physical.impl.aggregate.HashAggTemplate$BatchHolder
> org.apache.drill.exec.physical.impl.aggregate.HashAggTemplate.injectMembers(org.apache.drill.exec.physical.impl.aggregate.HashAggTemplate$BatchHolder)"
> {code}
> +The proposed fix+: Move those nested classes outside HashAgTemplate.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)