j2objcgradle / gson

A Java serialization/deserialization library to convert Java Objects into JSON and back
Apache License 2.0
1 stars 0 forks source link

java.lang.TypeNotPresentException #4

Open KellydeHaan opened 6 years ago

KellydeHaan commented 6 years ago

When the iOS application indirectly calls a Gson-method the application crashes with the following exception:

'JavaLangTypeNotPresentException', reason: 'java.lang.TypeNotPresentException: Type com.kgalligan.basicandroid.shared.Brewery not present'

As you can see from the namespace, I added the Brewery.class to the Basic Android Sample from the tutorial on the doppl website.

On Android this code works.

The dependencies on my build.gradle look like this: implementation 'com.google.code.gson:gson:2.6.2' j2objc 'org.j2objcgradle.com.google.code.gson:gson:2.6.2.7'

The code in the original Android file looks like this:

package com.kgalligan.basicandroid.shared;
import java.util.List;
public class BreweryResponse {

    private List<Brewery> breweries;

    public List<Brewery> getBreweries() {
        return breweries;
    }

    public void setBreweries(List<Brewery> breweries) {
        this.breweries = breweries;
    }
}

package com.kgalligan.basicandroid.shared;
import java.util.List;

public class Brewery {

    private String name;

    private String address;
    private String city;
    private List<String> open;
    private String zipcode;

    private List<Beer> beers;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public List<String> getOpen() {
        return open;
    }

    public void setOpen(List<String> open) {
        this.open = open;
    }

    public String getZipcode() {
        return zipcode;
    }

    public void setZipcode(String zipcode) {
        this.zipcode = zipcode;
    }

    public List<Beer> getBeers() {
        return beers;
    }

    public void setBeers(List<Beer> beers) {
        this.beers = beers;
    }

    @Override
    public String toString() {
        return "Brewery{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", city='" + city + '\'' +
                ", open=" + open +
                ", zipcode='" + zipcode + '\'' +
                ", beers=" + beers +
                '}';
    }
}

Called like this: new Gson().fromJson(breweries, BreweryResponse.class).getBreweries()

Any suggestions? Thanks in advance!

kpgalligan commented 6 years ago

It would be easier to review if I could see the whole project. In general, you get that exception when the type isn't available (hence the name). In iOS, if you don't add a flag telling the build to include everything, it'll only include classes with hard references. In Java (on the JVM, not J2objc), generics are useful at compile time, but at runtime a List is just a List (basically). It's possible that if the only place you reference Brewery directly by type is the generic param to the List that the Xcode build is stripping that class out.

Having said that, assuming you have a default config in your build gradle, the podspec should include

'OTHER_LDFLAGS' => '-ObjC'

-ObjC tells the linker to include all the classes.

So, basically, I need to see the build.gradle with the j2objcConfig section. I'd also suggest running a full clean and rebuild the pods. It would be easier to debug if you sent the code and I'll take a look.

KellydeHaan commented 6 years ago

Thank you for the quick response!

Complete code can be found here: https://github.com/KellydeHaan/BasicAndroidBrewerySample

The reason for two separate Api clients, AlamoFire and Retrofit, is that I ran into a similar issue with Retrofit as I did with Gson: de Retrofit interface could not be found by the Class Loader. But the Gson library is mentioned on the doppl website, and the Retrofit one isn't, so I decided to ask for help here 😄

kpgalligan commented 6 years ago

OK. I got it. The issue is the sample has a path prefix but doesn't include prefix.properties in the Xcode project.

https://developers.google.com/j2objc/guides/package-prefixes

Should be same issue for both problems. The docs need an update. We had docs about that but did a full refresh and not everything made it over (and the sample app should also have Xcode set up properly).

KellydeHaan commented 6 years ago

Thank you!