You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Eric Milles (JIRA)" <ji...@apache.org> on 2017/09/09 14:17:00 UTC

[jira] [Created] (GROOVY-8313) NullPointerException in TypeResolver when using generic array return type

Eric Milles created GROOVY-8313:
-----------------------------------

             Summary: NullPointerException in TypeResolver when using generic array return type
                 Key: GROOVY-8313
                 URL: https://issues.apache.org/jira/browse/GROOVY-8313
             Project: Groovy
          Issue Type: Bug
            Reporter: Eric Milles


I think this is related to GROOVY-6899.  I've been trying to isolate this for some time now: https://github.com/groovy/groovy-eclipse/issues/174.  When using a generic array type as a return value, the bridge method is written improperly.

{code}
public interface MultiIndexed<PK, SK> {
  PK getPrimaryKey();
  SK[] getSecondaryKeys();
}

class MIData implements MultiIndexed<Integer, String> {
  final String value
  final Integer primaryKey
  final String[] secondaryKeys

  MIData(String val, Integer pk, String... sk) {
    this.value = val
    this.primaryKey = pk
    this.secondaryKeys = sk
  }
}
{code}

javap on MiData.class shows {{public final SK[] getSecondaryKeys();}}.  The equivalent Java class shows a different signature for the bridge method: {{public java.lang.Object[] getSecondaryKeys();}}.

This causes an NPE under Introspector when bean info is trying to be resolved.
{code}
java.lang.NullPointerException
    at com.sun.beans.TypeResolver.resolve(TypeResolver.java:203)
    at com.sun.beans.TypeResolver.resolve(TypeResolver.java:162)
    at com.sun.beans.TypeResolver.resolveInClass(TypeResolver.java:81)
    at java.beans.FeatureDescriptor.getReturnType(FeatureDescriptor.java:370)
    at java.beans.Introspector.getTargetEventInfo(Introspector.java:1052)
    at java.beans.Introspector.getBeanInfo(Introspector.java:427)
    at java.beans.Introspector.getBeanInfo(Introspector.java:173)
    at groovy.lang.MetaClassImpl$15.run(MetaClassImpl.java:3289)
    at java.security.AccessController.doPrivileged(Native Method)
    at groovy.lang.MetaClassImpl.addProperties(MetaClassImpl.java:3287)
    at groovy.lang.MetaClassImpl.initialize(MetaClassImpl.java:3263)
    at org.codehaus.groovy.reflection.ClassInfo.getMetaClassUnderLock(ClassInfo.java:254)
    at org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:285)
    at MiData.$getStaticMetaClass(MiData.groovy)
    at MiData.<init>(MiData.groovy)

class Main {
  static void main(String[] args) {
    def data = new MIData('V', 1, 'B')
    print 'no error'
  }
}
{code}


I think this can be fixed in {{Verifier.getCovariantImplementation}}, like this:
{code}
        // if we reach this point we have at least one parameter or return type, that
        // is different in its specified form. That means we have to create a bridge method!
        MethodNode newMethod = new MethodNode(
                oldMethod.getName(),
                overridingMethod.getModifiers() | ACC_SYNTHETIC | ACC_BRIDGE,
                // GRECLIPSE edit
                //oldMethod.getReturnType().getPlainNodeReference(),
                GenericsUtils.nonGeneric(oldMethod.getReturnType()),
                // GRECLIPSE end
                cleanParameters(oldMethod.getParameters()),
                oldMethod.getExceptions(),
                null
        );
{code}




--
This message was sent by Atlassian JIRA
(v6.4.14#64029)