3

I am porting an existing application Java 7 to Java 11 (Drools 7.42.0). The application works as expected if I compile as Java 1.8 and deploy on Java 11 container (Weblogic 14). But if I compile the same code in Java 11, I get the following error. The only change between 1.8 and 11 is the java compiler level in Maven pom. I have ASM7 as a dependency in Maven.

Caused by: java.lang.UnsupportedOperationException: This feature requires ASM7
        at org.mvel2.asm.ClassVisitor.visitNestMember(ClassVisitor.java:236)
        at org.mvel2.asm.ClassReader.accept(ClassReader.java:651)
        at org.mvel2.asm.ClassReader.accept(ClassReader.java:391)
        at org.drools.core.util.asm.ClassFieldInspector.processClassWithByteCode(ClassFieldInspector.java:107)
        at org.drools.core.util.asm.ClassFieldInspector.processClassWithByteCode(ClassFieldInspector.java:114)
        at org.drools.core.util.asm.ClassFieldInspector.<init>(ClassFieldInspector.java:86)
        at org.drools.core.util.asm.ClassFieldInspector.<init>(ClassFieldInspector.java:74)
        at org.drools.core.base.ClassFieldAccessorFactory.getClassFieldInspector(ClassFieldAccessorFactory.java:157)
        at org.drools.core.base.ClassFieldAccessorFactory.getFieldType(ClassFieldAccessorFactory.java:141)
        at org.drools.core.base.ClassFieldAccessorStore.getFieldType(ClassFieldAccessorStore.java:295)
        at org.drools.compiler.rule.builder.PatternBuilder.getValueType(PatternBuilder.java:1079)
        at org.drools.compiler.rule.builder.PatternBuilder.normalizeExpression(PatternBuilder.java:1047)
        at org.drools.compiler.rule.builder.PatternBuilder.buildExpression(PatternBuilder.java:965)
        at org.drools.compiler.rule.builder.PatternBuilder.buildCcdDescr(PatternBuilder.java:942)
        at org.drools.compiler.rule.builder.PatternBuilder.build(PatternBuilder.java:767)
        at org.drools.compiler.rule.builder.PatternBuilder.processConstraintsAndBinds(PatternBuilder.java:620)
        at org.drools.compiler.rule.builder.PatternBuilder.build(PatternBuilder.java:187)
        at org.drools.compiler.rule.builder.PatternBuilder.build(PatternBuilder.java:154)
        at org.drools.compiler.rule.builder.PatternBuilder.build(PatternBuilder.java:136)
        at org.drools.compiler.rule.builder.GroupElementBuilder.build(GroupElementBuilder.java:66)
        at org.drools.compiler.rule.builder.RuleBuilder.build(RuleBuilder.java:107)
        at org.drools.compiler.builder.impl.KnowledgeBuilderImpl.internalAddRule(KnowledgeBuilderImpl.java:1183)
        at org.drools.compiler.builder.impl.KnowledgeBuilderImpl.addRule(KnowledgeBuilderImpl.java:1178)
        at org.drools.compiler.builder.impl.KnowledgeBuilderImpl.lambda$null$3(KnowledgeBuilderImpl.java:1134)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
        at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:290)
        at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)

I noticed while debugging that this was caused by an "enum" in our code. Drools works fine if we remove the enum and use constants. The error seems to suggest that this could happen to any nested classes. Is there a better way to handle this other than changing our code to remove nested classes and enums?

I see that in the class org.drools.core.util.asm.ClassFieldInspector, the API is set to ASM5, but MVEL is expecting ASM7. But not sure why it would work in Java 8 and not in Java 11. Any suggestions?

ClassFieldVisitor(final Class< ? > cls,
                  final boolean includeFinalMethods,
                  final ClassFieldInspector inspector) {
    super(Opcodes.ASM5);
    this.clazz = cls;
    this.includeFinalMethods = includeFinalMethods;
    this.inspector = inspector;
}
  • 1
    The newer versions of ASM are aware of byte-code changes in newer versions of Java. And it would appear something changed in enums between Java 8 and Java 11. Why not just update to ASM7? – Slaw Sep 15 '20 at 20:14
  • 1
    Given that it's about nested classes, it probably has to do with: https://openjdk.java.net/jeps/181 So when compiling for Java 11, you get nest members in the class file, which ASM can only read starting from ASM7. But, this ClassFieldInspector is explicitly requiring the ASM5 API. In other words, it seems like it is not up to date for handling Java 11 code. – Jorn Vernee Sep 15 '20 at 20:20
  • 3
    As said in [this answer](https://stackoverflow.com/a/63408495/2711488), the specified ASM version is necessary for subclasses, to declare that the decision not to override a method, i.e. `visitNestMember`, was a deliberate decision and not based on not knowing this newer method. Most probably, a class named `ClassFieldVisitor` is truly not interested in nest groups and would work when changing `ASM5` to `ASM7`, but someone must revise the class and make that decision. – Holger Sep 16 '20 at 08:21

1 Answers1

1

Disclaimer: I'm one of the Drools developers

That's interesting as we might not emit valid ASM code. Please file a bug on https://issues.redhat.com so that we can fix it

Thank you very much

Luca Molteni
  • 5,230
  • 5
  • 34
  • 42