Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reflection on parametrized types #660

Closed
eapache opened this issue Nov 12, 2015 · 4 comments
Closed

Reflection on parametrized types #660

eapache opened this issue Nov 12, 2015 · 4 comments
Labels

Comments

@eapache
Copy link

eapache commented Nov 12, 2015

cc @boourns @carsonb @brunobowden

I've been trying to use square's retrofit library with j2objc and have run into various roadblocks (see e.g. #659 and j2objc-contrib/j2objc-gradle#570) which I am slowly working around.

I now have it building, however I am running into a problem with it's use of reflection (specifically the check at https://github.com/square/retrofit/blob/62b2290fea162850942477638bd500b1db670e12/retrofit/src/main/java/retrofit/Utils.java#L184-L186). My code works fine in Java, since the type in question is a retrofit.Call<MyFoo>. However, j2objc translates retrofit.Call into an interface rather than a parametrized generic, so even though the code is right, it throws the given IllegalArgumentException when run on iOS.

I'm not sure what Objective-C's type system is like when you get into complex stuff like this, but I suspect j2objc should be translating retrofit.Call into something else, or perhaps shimming the reflection library to recognize interfaces as parametrized types?

I haven't been able to come up with a minimal test case, but it should be straight-forward for someone with more java reflection experience.

@tomball
Copy link
Collaborator

tomball commented Nov 12, 2015

Looks like a straightforward bug, which should be relatively easy to fix.

To answer your question about how reflecting parameterized types works, each translated class has a private __metadata class method, which returns a J2ObjcClassInfo struct that provides the Java type information that can't be inferred using the Objective C runtime.

Like in JVM class files, parameterized type information is stored as generic signature strings in the class, method and field structs, using the same format. An easy way to verify that a signature is correct is to run "javap -v" on the associated class file, and compare it with the string in the __metadata struct. If the signature doesn't match then the issue is with the translator, otherwise it's a potential bug in the reflection runtime.

@eapache
Copy link
Author

eapache commented Nov 13, 2015

Both the java and objc sides provide the same signature string: <T:Ljava/lang/Object;>Ljava/lang/Object;Ljava/lang/Cloneable; so that part is correct (generated from the file https://github.com/square/retrofit/blob/62b2290fea162850942477638bd500b1db670e12/retrofit/src/main/java/retrofit/Call.java). This suggests a bug in the reflection runtime then.

@eapache
Copy link
Author

eapache commented Nov 13, 2015

However, things may be slightly more complicated. The type which is failing to reflect is coming from a method which returns retrofit.Call<Foo>. Dumping javap -v on that file I see the string Lretrofit/Call<Lcom/shopify/Foo;> whereas in objc, the J2ObjcMethodInfo struct for that method lists the return type as only Lretrofit.Call; so perhaps this is a translation issue after all? Just with the method return specifically rather than the type as a whole.

@tomball
Copy link
Collaborator

tomball commented Nov 13, 2015

There was a bug in the translator, with a fix out for review. To keep the metadata small, we only emit signatures when there's a need, and that test for methods wasn't checking that a method's return value was parameterized (only that it was a type variable). Changing that test to:

if (method.isGenericMethod() || method.getReturnType().isTypeVariable()
    || method.getReturnType().isParameterizedType()) {

fixed the unit test I wrote. If you have the time and inclination, please patch the above and see if it fixes your issue.

tomball added a commit that referenced this issue Nov 18, 2015
…eturn types.

	Change on 2015/11/16 by tball <[email protected]>
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=107959033
@tomball tomball closed this as completed Nov 25, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants