handlebars.java icon indicating copy to clipboard operation
handlebars.java copied to clipboard

Shouldn't be illegal to access field 'coder'

Open agilob opened this issue 2 years ago • 1 comments

Hi

I'm updating openapi-generator to jdk11+. I updated handlebars from 4.2.1 to 4.3.0 and started getting this exception in jdk11 and 17

Caused by: com.github.jknack.handlebars.HandlebarsException: testdata-localhost.hbs:1:46: java.lang.IllegalStateException: Shouldn't be illegal to access field 'coder'
    testdata-localhost.hbs:1:46
	at com.github.jknack.handlebars.context.FieldValueResolver.invokeMember(FieldValueResolver.java:217)
	at com.github.jknack.handlebars.context.FieldValueResolver.invokeMember(FieldValueResolver.java:39)
	at com.github.jknack.handlebars.context.MemberValueResolver.resolve(MemberValueResolver.java:59)
	at com.github.jknack.handlebars.context.MemberValueResolver.propertySet(MemberValueResolver.java:194)
	at com.github.jknack.handlebars.Context$CompositeValueResolver.propertySet(Context.java:226)
	at com.github.jknack.handlebars.Context.propertySet(Context.java:569)
	at com.github.jknack.handlebars.Options.propertySet(Options.java:787)
	at com.github.jknack.handlebars.helper.EachHelper.apply(EachHelper.java:84)
	at com.github.jknack.handlebars.internal.Block.merge(Block.java:211)
	at com.github.jknack.handlebars.internal.BaseTemplate.apply(BaseTemplate.java:126)
	at com.github.jknack.handlebars.internal.TemplateList.merge(TemplateList.java:95)
	at com.github.jknack.handlebars.internal.BaseTemplate.apply(BaseTemplate.java:126)
	at com.github.jknack.handlebars.internal.BaseTemplate.apply(BaseTemplate.java:114)
	at com.github.jknack.handlebars.Options.apply(Options.java:538)
	at com.github.jknack.handlebars.helper.EachHelper.apply(EachHelper.java:99)
	at com.github.jknack.handlebars.internal.Block.merge(Block.java:211)
	at com.github.jknack.handlebars.internal.BaseTemplate.apply(BaseTemplate.java:126)
	at com.github.jknack.handlebars.internal.TemplateList.merge(TemplateList.java:95)
	at com.github.jknack.handlebars.internal.BaseTemplate.apply(BaseTemplate.java:126)
	at com.github.jknack.handlebars.internal.BaseTemplate.apply(BaseTemplate.java:114)
	at com.github.jknack.handlebars.internal.ForwardingTemplate.apply(ForwardingTemplate.java:100)
	at org.openapitools.codegen.templating.HandlebarsEngineAdapter.compileTemplate(HandlebarsEngineAdapter.java:92)
	at org.openapitools.codegen.TemplateManager.write(TemplateManager.java:163)
	at org.openapitools.codegen.DefaultGenerator.processTemplateToFile(DefaultGenerator.java:1042)
	at org.openapitools.codegen.DefaultGenerator.generateApis(DefaultGenerator.java:638)
	... 29 more
Caused by: java.lang.IllegalStateException: Shouldn't be illegal to access field 'coder'
	... 54 more
Caused by: java.lang.IllegalAccessException: class com.github.jknack.handlebars.context.FieldValueResolver$FieldMember cannot access a member of class java.lang.String (in module java.base) with modifiers "private final"
	at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:361)
	at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:591)
	at java.base/java.lang.reflect.Field.checkAccess(Field.java:1075)
	at java.base/java.lang.reflect.Field.get(Field.java:416)
	at com.github.jknack.handlebars.context.FieldValueResolver$FieldMember.get(FieldValueResolver.java:135)
	at com.github.jknack.handlebars.context.FieldValueResolver.invokeMember(FieldValueResolver.java:214)
	... 53 more

This is when running DefaultGeneratorTest.supportCustomTemplateEngine

agilob avatar Oct 28 '21 07:10 agilob

See #940

In this class: https://github.com/OpenAPITools/openapi-generator/blob/4d947a1c4579a73c7350ea55153d33ef76ba5d89/modules/openapi-generator/src/main/java/org/openapitools/codegen/templating/HandlebarsEngineAdapter.java

Change the FieldValueResolver to something like:

        var MY_FIELD_VALUE_RESOLVER = new FieldValueResolver() {

            @Override
            protected Set<FieldWrapper> members(
                    Class<?> clazz) {
                var members = super.members(clazz);
                return members.stream()
                    .filter(fw -> isValidField(fw))
                    .collect(Collectors.toSet());
            }

            boolean isValidField(
                    FieldWrapper fw) {
                if (fw instanceof AccessibleObject) {
                    if (isUseSetAccessible(fw)) {
                        return true;
                    }
                    return false;
                }
                return true;
            }
        };

However the above has serious backward compatibility issues if you rely on public fields in the JDK which there should not be many other than array lengths.

agentgt avatar Mar 31 '22 13:03 agentgt

Integrated in https://github.com/OpenAPITools/openapi-generator/pull/15553

agilob avatar May 17 '23 06:05 agilob